redsnow 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +34 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +20 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +21 -0
  8. data/README.md +62 -0
  9. data/Rakefile +36 -0
  10. data/Vagrantfile +20 -0
  11. data/ext/snowcrash/Makefile +64 -0
  12. data/ext/snowcrash/Vagrantfile +20 -0
  13. data/ext/snowcrash/bin/snowcrash +0 -0
  14. data/ext/snowcrash/common.gypi +163 -0
  15. data/ext/snowcrash/config.gypi +10 -0
  16. data/ext/snowcrash/config.mk +5 -0
  17. data/ext/snowcrash/configure +213 -0
  18. data/ext/snowcrash/provisioning.sh +15 -0
  19. data/ext/snowcrash/snowcrash.gyp +141 -0
  20. data/ext/snowcrash/src/ActionParser.h +503 -0
  21. data/ext/snowcrash/src/AssetParser.h +215 -0
  22. data/ext/snowcrash/src/BlockUtility.h +186 -0
  23. data/ext/snowcrash/src/Blueprint.h +283 -0
  24. data/ext/snowcrash/src/BlueprintParser.h +347 -0
  25. data/ext/snowcrash/src/BlueprintParserCore.h +190 -0
  26. data/ext/snowcrash/src/BlueprintSection.h +140 -0
  27. data/ext/snowcrash/src/BlueprintUtility.h +126 -0
  28. data/ext/snowcrash/src/CBlueprint.cc +600 -0
  29. data/ext/snowcrash/src/CBlueprint.h +354 -0
  30. data/ext/snowcrash/src/CSourceAnnotation.cc +140 -0
  31. data/ext/snowcrash/src/CSourceAnnotation.h +106 -0
  32. data/ext/snowcrash/src/CodeBlockUtility.h +189 -0
  33. data/ext/snowcrash/src/DescriptionSectionUtility.h +156 -0
  34. data/ext/snowcrash/src/HTTP.cc +46 -0
  35. data/ext/snowcrash/src/HTTP.h +105 -0
  36. data/ext/snowcrash/src/HeaderParser.h +289 -0
  37. data/ext/snowcrash/src/ListBlockUtility.h +273 -0
  38. data/ext/snowcrash/src/ListUtility.h +95 -0
  39. data/ext/snowcrash/src/MarkdownBlock.cc +176 -0
  40. data/ext/snowcrash/src/MarkdownBlock.h +93 -0
  41. data/ext/snowcrash/src/MarkdownParser.cc +266 -0
  42. data/ext/snowcrash/src/MarkdownParser.h +88 -0
  43. data/ext/snowcrash/src/ParameterDefinitonParser.h +570 -0
  44. data/ext/snowcrash/src/ParametersParser.h +252 -0
  45. data/ext/snowcrash/src/Parser.cc +71 -0
  46. data/ext/snowcrash/src/Parser.h +29 -0
  47. data/ext/snowcrash/src/ParserCore.cc +120 -0
  48. data/ext/snowcrash/src/ParserCore.h +82 -0
  49. data/ext/snowcrash/src/PayloadParser.h +672 -0
  50. data/ext/snowcrash/src/Platform.h +54 -0
  51. data/ext/snowcrash/src/RegexMatch.h +32 -0
  52. data/ext/snowcrash/src/ResourceGroupParser.h +195 -0
  53. data/ext/snowcrash/src/ResourceParser.h +584 -0
  54. data/ext/snowcrash/src/SectionUtility.h +142 -0
  55. data/ext/snowcrash/src/Serialize.cc +52 -0
  56. data/ext/snowcrash/src/Serialize.h +69 -0
  57. data/ext/snowcrash/src/SerializeJSON.cc +601 -0
  58. data/ext/snowcrash/src/SerializeJSON.h +21 -0
  59. data/ext/snowcrash/src/SerializeYAML.cc +336 -0
  60. data/ext/snowcrash/src/SerializeYAML.h +21 -0
  61. data/ext/snowcrash/src/SourceAnnotation.h +177 -0
  62. data/ext/snowcrash/src/StringUtility.h +109 -0
  63. data/ext/snowcrash/src/SymbolTable.h +83 -0
  64. data/ext/snowcrash/src/UriTemplateParser.cc +195 -0
  65. data/ext/snowcrash/src/UriTemplateParser.h +243 -0
  66. data/ext/snowcrash/src/Version.h +39 -0
  67. data/ext/snowcrash/src/csnowcrash.cc +23 -0
  68. data/ext/snowcrash/src/csnowcrash.h +38 -0
  69. data/ext/snowcrash/src/posix/RegexMatch.cc +99 -0
  70. data/ext/snowcrash/src/snowcrash.cc +18 -0
  71. data/ext/snowcrash/src/snowcrash.h +41 -0
  72. data/ext/snowcrash/src/snowcrash/snowcrash.cc +170 -0
  73. data/ext/snowcrash/src/win/RegexMatch.cc +78 -0
  74. data/ext/snowcrash/sundown/CONTRIBUTING.md +10 -0
  75. data/ext/snowcrash/sundown/Makefile +83 -0
  76. data/ext/snowcrash/sundown/Makefile.win +33 -0
  77. data/ext/snowcrash/sundown/examples/smartypants.c +72 -0
  78. data/ext/snowcrash/sundown/examples/sundown.c +80 -0
  79. data/ext/snowcrash/sundown/html/houdini.h +37 -0
  80. data/ext/snowcrash/sundown/html/houdini_href_e.c +108 -0
  81. data/ext/snowcrash/sundown/html/houdini_html_e.c +84 -0
  82. data/ext/snowcrash/sundown/html/html.c +647 -0
  83. data/ext/snowcrash/sundown/html/html.h +77 -0
  84. data/ext/snowcrash/sundown/html/html_smartypants.c +389 -0
  85. data/ext/snowcrash/sundown/html_block_names.txt +25 -0
  86. data/ext/snowcrash/sundown/src/autolink.c +297 -0
  87. data/ext/snowcrash/sundown/src/autolink.h +51 -0
  88. data/ext/snowcrash/sundown/src/buffer.c +225 -0
  89. data/ext/snowcrash/sundown/src/buffer.h +96 -0
  90. data/ext/snowcrash/sundown/src/html_blocks.h +206 -0
  91. data/ext/snowcrash/sundown/src/markdown.c +2701 -0
  92. data/ext/snowcrash/sundown/src/markdown.h +147 -0
  93. data/ext/snowcrash/sundown/src/src_map.c +200 -0
  94. data/ext/snowcrash/sundown/src/src_map.h +58 -0
  95. data/ext/snowcrash/sundown/src/stack.c +81 -0
  96. data/ext/snowcrash/sundown/src/stack.h +29 -0
  97. data/ext/snowcrash/sundown/sundown.def +20 -0
  98. data/ext/snowcrash/tools/gyp/AUTHORS +11 -0
  99. data/ext/snowcrash/tools/gyp/DEPS +24 -0
  100. data/ext/snowcrash/tools/gyp/OWNERS +1 -0
  101. data/ext/snowcrash/tools/gyp/PRESUBMIT.py +120 -0
  102. data/ext/snowcrash/tools/gyp/buildbot/buildbot_run.py +190 -0
  103. data/ext/snowcrash/tools/gyp/codereview.settings +10 -0
  104. data/ext/snowcrash/tools/gyp/data/win/large-pdb-shim.cc +12 -0
  105. data/ext/snowcrash/tools/gyp/gyp +8 -0
  106. data/ext/snowcrash/tools/gyp/gyp.bat +5 -0
  107. data/ext/snowcrash/tools/gyp/gyp_main.py +18 -0
  108. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSNew.py +340 -0
  109. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSProject.py +208 -0
  110. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSSettings.py +1063 -0
  111. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSToolFile.py +58 -0
  112. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUserFile.py +147 -0
  113. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUtil.py +267 -0
  114. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSVersion.py +409 -0
  115. data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.py +537 -0
  116. data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.pyc +0 -0
  117. data/ext/snowcrash/tools/gyp/pylib/gyp/common.py +521 -0
  118. data/ext/snowcrash/tools/gyp/pylib/gyp/common.pyc +0 -0
  119. data/ext/snowcrash/tools/gyp/pylib/gyp/easy_xml.py +157 -0
  120. data/ext/snowcrash/tools/gyp/pylib/gyp/flock_tool.py +49 -0
  121. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.py +0 -0
  122. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.pyc +0 -0
  123. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/android.py +1069 -0
  124. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/cmake.py +1143 -0
  125. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/dump_dependency_json.py +81 -0
  126. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/eclipse.py +335 -0
  127. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypd.py +87 -0
  128. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypsh.py +56 -0
  129. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.py +2181 -0
  130. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.pyc +0 -0
  131. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/msvs.py +3335 -0
  132. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/ninja.py +2156 -0
  133. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.py +1224 -0
  134. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.pyc +0 -0
  135. data/ext/snowcrash/tools/gyp/pylib/gyp/input.py +2809 -0
  136. data/ext/snowcrash/tools/gyp/pylib/gyp/input.pyc +0 -0
  137. data/ext/snowcrash/tools/gyp/pylib/gyp/mac_tool.py +510 -0
  138. data/ext/snowcrash/tools/gyp/pylib/gyp/msvs_emulation.py +972 -0
  139. data/ext/snowcrash/tools/gyp/pylib/gyp/ninja_syntax.py +160 -0
  140. data/ext/snowcrash/tools/gyp/pylib/gyp/ordered_dict.py +289 -0
  141. data/ext/snowcrash/tools/gyp/pylib/gyp/win_tool.py +292 -0
  142. data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.py +1440 -0
  143. data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.pyc +0 -0
  144. data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.py +2889 -0
  145. data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyc +0 -0
  146. data/ext/snowcrash/tools/gyp/pylib/gyp/xml_fix.py +69 -0
  147. data/ext/snowcrash/tools/gyp/pylintrc +307 -0
  148. data/ext/snowcrash/tools/gyp/samples/samples +81 -0
  149. data/ext/snowcrash/tools/gyp/samples/samples.bat +5 -0
  150. data/ext/snowcrash/tools/gyp/setup.py +19 -0
  151. data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.pbfilespec +27 -0
  152. data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.xclangspec +226 -0
  153. data/ext/snowcrash/tools/gyp/tools/emacs/gyp.el +252 -0
  154. data/ext/snowcrash/tools/gyp/tools/graphviz.py +100 -0
  155. data/ext/snowcrash/tools/gyp/tools/pretty_gyp.py +155 -0
  156. data/ext/snowcrash/tools/gyp/tools/pretty_sln.py +168 -0
  157. data/ext/snowcrash/tools/gyp/tools/pretty_vcproj.py +329 -0
  158. data/ext/snowcrash/tools/homebrew/snowcrash.rb +11 -0
  159. data/ext/snowcrash/vcbuild.bat +184 -0
  160. data/lib/redsnow.rb +31 -0
  161. data/lib/redsnow/binding.rb +132 -0
  162. data/lib/redsnow/blueprint.rb +365 -0
  163. data/lib/redsnow/object.rb +18 -0
  164. data/lib/redsnow/parseresult.rb +107 -0
  165. data/lib/redsnow/version.rb +4 -0
  166. data/provisioning.sh +20 -0
  167. data/redsnow.gemspec +35 -0
  168. data/test/_helper.rb +15 -0
  169. data/test/fixtures/sample-api-ast.json +97 -0
  170. data/test/fixtures/sample-api.apib +20 -0
  171. data/test/redsnow_binding_test.rb +35 -0
  172. data/test/redsnow_parseresult_test.rb +50 -0
  173. data/test/redsnow_test.rb +285 -0
  174. metadata +358 -0
@@ -0,0 +1,88 @@
1
+ //
2
+ // MarkdownParser.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 4/15/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_MARKDOWNPARSER_H
10
+ #define SNOWCRASH_MARKDOWNPARSER_H
11
+
12
+ #include "ParserCore.h"
13
+ #include "SourceAnnotation.h"
14
+ #include "MarkdownBlock.h"
15
+ #include "markdown.h"
16
+
17
+ namespace snowcrash {
18
+
19
+ //
20
+ // Markdown Parser
21
+ //
22
+ class MarkdownParser {
23
+ public:
24
+ // Default sundown parser configuration
25
+ static const size_t OutputUnitSize; // = 64;
26
+ static const size_t MaxNesting;// = 16;
27
+ static const int ParserExtensions;// = MKDEXT_FENCED_CODE | MKDEXT_NO_INTRA_EMPHASIS /*| MKDEXT_TABLES */;
28
+
29
+ // Parse source Markdown into Markdown AST
30
+ void parse(const SourceData& source, Result& result, MarkdownBlock::Stack& markdown);
31
+
32
+ private:
33
+ typedef sd_callbacks RenderCallbacks;
34
+ typedef void * RenderCallbackData;
35
+
36
+ RenderCallbacks renderCallbacks();
37
+ RenderCallbackData renderCallbackData();
38
+
39
+ MarkdownBlock::Stack m_renderStack;
40
+
41
+ // Header
42
+ static void renderHeader(struct buf *ob, const struct buf *text, int level, void *opaque);
43
+ void renderHeader(const std::string& text, int level);
44
+
45
+ // List
46
+ static void beginList(int flags, void *opaque);
47
+ void beginList(int flags);
48
+
49
+ static void renderList(struct buf *ob, const struct buf *text, int flags, void *opaque);
50
+ void renderList(const std::string& text, int flags);
51
+
52
+ // List item
53
+ static void beginListItem(int flags, void *opaque);
54
+ void beginListItem(int flags);
55
+
56
+ static void renderListItem(struct buf *ob, const struct buf *text, int flags, void *opaque);
57
+ void renderListItem(const std::string& text, int flags);
58
+
59
+ // Code block
60
+ static void renderBlockCode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque);
61
+ void renderBlockCode(const std::string& text, const std::string& language);
62
+
63
+ // Paragraph
64
+ static void renderParagraph(struct buf *ob, const struct buf *text, void *opaque);
65
+ void renderParagraph(const std::string& text);
66
+
67
+ // Horizontal Rule
68
+ static void renderHorizontalRule(struct buf *ob, void *opaque);
69
+ void renderHorizontalRule();
70
+
71
+ // HTML
72
+ static void renderHTML(struct buf *ob, const struct buf *text, void *opaque);
73
+ void renderHTML(const std::string& text);
74
+
75
+ // Quote
76
+ static void beginQuote(void *opaque);
77
+ void beginQuote();
78
+
79
+ static void renderQuote(struct buf *ob, const struct buf *text, void *opaque);
80
+ void renderQuote(const std::string& text);
81
+
82
+ // Source maps
83
+ static void blockDidParse(const src_map* map, const uint8_t *txt_data, size_t size, void *opaque);
84
+ void blockDidParse(const SourceDataBlock& sourceMap);
85
+ };
86
+ }
87
+
88
+ #endif
@@ -0,0 +1,570 @@
1
+ //
2
+ // ParameterDefinitonParser.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 9/1/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_PARAMETERDEFINITIONPARSER_H
10
+ #define SNOWCRASH_PARAMETERDEFINITIONPARSER_H
11
+
12
+ #include <sstream>
13
+ #include "BlueprintParserCore.h"
14
+ #include "Blueprint.h"
15
+ #include "RegexMatch.h"
16
+ #include "StringUtility.h"
17
+ #include "ListBlockUtility.h"
18
+ #include "SectionUtility.h"
19
+ #include "DescriptionSectionUtility.h"
20
+
21
+ /** Parameter Value regex */
22
+ #define PARAMETER_VALUE "`([^`]+)`"
23
+
24
+ /** Parameter Identifier */
25
+ #define PARAMETER_IDENTIFIER "([[:alnum:]_.-]+)"
26
+
27
+ /** Lead in and out for comma separated values regex */
28
+ #define CSV_LEADINOUT "[[:blank:]]*,?[[:blank:]]*"
29
+
30
+ namespace snowcrashconst {
31
+
32
+ /** Parameter Abbreviated definition matching regex */
33
+ const char* const ParameterAbbrevDefinitionRegex = "^" PARAMETER_IDENTIFIER \
34
+ "([[:blank:]]*=[[:blank:]]*`([^`]*)`[[:blank:]]*)?([[:blank:]]*\\(([^)]*)\\)[[:blank:]]*)?([[:blank:]]*\\.\\.\\.[[:blank:]]*(.*))?$";
35
+
36
+ /** Parameter Required matching regex */
37
+ const char* const ParameterRequiredRegex = "^[[:blank:]]*[Rr]equired[[:blank:]]*$";
38
+
39
+ /** Parameter Optional matching regex */
40
+ const char* const ParameterOptionalRegex = "^[[:blank:]]*[Oo]ptional[[:blank:]]*$";
41
+
42
+ /** Additonal Parameter Traits Example matching regex */
43
+ const char* const AdditionalTraitsExampleRegex = CSV_LEADINOUT "`([^`]*)`" CSV_LEADINOUT;
44
+
45
+ /** Additonal Parameter Traits Use matching regex */
46
+ const char* const AdditionalTraitsUseRegex = CSV_LEADINOUT "([Oo]ptional|[Rr]equired)" CSV_LEADINOUT;
47
+
48
+ /** Additonal Parameter Traits Type matching regex */
49
+ const char* const AdditionalTraitsTypeRegex = CSV_LEADINOUT "([^,]*)" CSV_LEADINOUT;
50
+
51
+ /** Parameter Values matching regex */
52
+ const char* const ParameterValuesRegex = "^[[:blank:]]*[Vv]alues[[:blank:]]*$";
53
+
54
+ /** Values expected content */
55
+ const char* const ExpectedValuesContent = "nested list of possible parameter values, one element per list item e.g. '`value`'";
56
+ }
57
+
58
+ namespace snowcrash {
59
+
60
+ /**
61
+ * Classifier of internal list items, ParameterCollection context.
62
+ */
63
+ template <>
64
+ FORCEINLINE SectionType ClassifyInternaListBlock<Parameter>(const BlockIterator& begin,
65
+ const BlockIterator& end) {
66
+
67
+
68
+ if (begin->type != ListBlockBeginType &&
69
+ begin->type != ListItemBlockBeginType)
70
+ return UndefinedSectionType;
71
+
72
+ SourceData remainingContent;
73
+ SourceData content = GetListItemSignature(begin, end, remainingContent);
74
+
75
+ content = TrimString(content);
76
+
77
+ if (RegexMatch(content, snowcrashconst::ParameterValuesRegex))
78
+ return ParameterValuesSectionType;
79
+
80
+ return UndefinedSectionType;
81
+ }
82
+
83
+ /** Children blocks classifier */
84
+ template <>
85
+ FORCEINLINE SectionType ClassifyChildrenListBlock<Parameter>(const BlockIterator& begin,
86
+ const BlockIterator& end) {
87
+
88
+ SectionType type = ClassifyInternaListBlock<Parameter>(begin, end);
89
+ if (type != UndefinedSectionType)
90
+ return type;
91
+
92
+ return UndefinedSectionType;
93
+ }
94
+
95
+ /**
96
+ * Returns true if given block has a parameter definition signature, false otherwise.
97
+ */
98
+ FORCEINLINE bool HasParameterDefinitionSignature(const BlockIterator& begin,
99
+ const BlockIterator& end) {
100
+
101
+ if (begin->type != ListBlockBeginType &&
102
+ begin->type != ListItemBlockBeginType)
103
+ return false;
104
+
105
+ // Since we are too generic make sure the signature is not inner list
106
+ SectionType listSection = ClassifyInternaListBlock<Parameter>(begin, end);
107
+ if (listSection != UndefinedSectionType)
108
+ return false;
109
+
110
+ // Or any other reserved keyword
111
+ if (HasParametersSignature(begin, end))
112
+ return false;
113
+
114
+ SourceData remainingContent;
115
+ SourceData content = GetListItemSignature(begin, end, remainingContent);
116
+ content = TrimString(content);
117
+ return RegexMatch(content, snowcrashconst::ParameterAbbrevDefinitionRegex);
118
+ }
119
+
120
+ /**
121
+ * Block Classifier, Parameter context.
122
+ */
123
+ template <>
124
+ FORCEINLINE SectionType ClassifyBlock<Parameter>(const BlockIterator& begin,
125
+ const BlockIterator& end,
126
+ const SectionType& context) {
127
+
128
+ if (context == UndefinedSectionType) {
129
+ if (HasParameterDefinitionSignature(begin, end))
130
+ return ParameterDefinitionSectionType;
131
+ }
132
+ else if (context == ParameterDefinitionSectionType) {
133
+
134
+ if (begin->type == ListItemBlockEndType ||
135
+ begin->type == ListBlockEndType)
136
+ return UndefinedSectionType;
137
+
138
+ SectionType listSection = ClassifyInternaListBlock<Parameter>(begin, end);
139
+ if (listSection != UndefinedSectionType)
140
+ return listSection;
141
+
142
+ if (begin->type == ListBlockBeginType)
143
+ return ForeignSectionType; // Foreign nested list-item
144
+
145
+ if (begin->type == ListItemBlockBeginType)
146
+ return UndefinedSectionType;
147
+ }
148
+ else if (context == ParameterValuesSectionType ||
149
+ context == ForeignSectionType) {
150
+
151
+ if (begin->type == ListItemBlockEndType ||
152
+ begin->type == ListBlockEndType)
153
+ return UndefinedSectionType;
154
+
155
+ SectionType listSection = ClassifyInternaListBlock<Parameter>(begin, end);
156
+ if (listSection != UndefinedSectionType)
157
+ return listSection;
158
+
159
+ return ForeignSectionType;
160
+ }
161
+
162
+ return (context == ParameterDefinitionSectionType) ? context : UndefinedSectionType;
163
+ }
164
+
165
+ /**
166
+ * Parameter section parser.
167
+ */
168
+ template<>
169
+ struct SectionParser<Parameter> {
170
+
171
+ static ParseSectionResult ParseSection(const BlueprintSection& section,
172
+ const BlockIterator& cur,
173
+ BlueprintParserCore& parser,
174
+ Parameter& parameter) {
175
+
176
+ ParseSectionResult result = std::make_pair(Result(), cur);
177
+ switch (section.type) {
178
+
179
+ case ParameterDefinitionSectionType:
180
+ result = HandleParmeterDefinitionSection(section, cur, parser, parameter);
181
+ break;
182
+
183
+ case ParameterValuesSectionType:
184
+ result = HandleValuesSection(section, cur, parser, parameter);
185
+ break;
186
+
187
+ case ForeignSectionType:
188
+ result = HandleForeignSection<Parameter>(section, cur, parser.sourceData);
189
+ break;
190
+
191
+ case UndefinedSectionType:
192
+ result.second = CloseList(cur, section.bounds.second);
193
+ break;
194
+
195
+ default:
196
+ result.first.error = UnexpectedBlockError(section, cur, parser.sourceData);
197
+ break;
198
+ }
199
+
200
+ return result;
201
+ }
202
+
203
+
204
+ static void Finalize(const SectionBounds& bounds,
205
+ BlueprintParserCore& parser,
206
+ Parameter& parameter,
207
+ Result& result) {}
208
+
209
+ /** Parse a parameter definition top-level section blocks. */
210
+ static ParseSectionResult HandleParmeterDefinitionSection(const BlueprintSection& section,
211
+ const BlockIterator& cur,
212
+ BlueprintParserCore& parser,
213
+ Parameter& parameter) {
214
+
215
+ ParseSectionResult result = std::make_pair(Result(), cur);
216
+ BlockIterator sectionCur = cur;
217
+
218
+ // Signature
219
+ if (sectionCur == section.bounds.first) {
220
+ ProcessSignature(section, sectionCur, parser.sourceData, result.first, parameter);
221
+ result.second = SkipSignatureBlock(sectionCur, section.bounds.second);
222
+ return result;
223
+ }
224
+
225
+ // Description
226
+ result = ParseDescriptionBlock<Parameter>(section,
227
+ sectionCur,
228
+ parser.sourceData,
229
+ parameter);
230
+ return result;
231
+
232
+ }
233
+
234
+ /**
235
+ * Retrieve and process parameter definition signature.
236
+ */
237
+ static void ProcessSignature(const BlueprintSection& section,
238
+ const BlockIterator& cur,
239
+ const SourceData& sourceData,
240
+ Result& result,
241
+ Parameter& parameter) {
242
+
243
+
244
+ // Set default values
245
+ parameter.use = UndefinedParameterUse;
246
+
247
+ // Process signature
248
+ SourceData remainingContent;
249
+ SourceData signature = GetListItemSignature(cur, section.bounds.second, remainingContent);
250
+
251
+ TrimString(signature);
252
+ CaptureGroups captureGroups;
253
+ if (RegexCapture(signature, snowcrashconst::ParameterAbbrevDefinitionRegex, captureGroups) &&
254
+ captureGroups.size() == 8) {
255
+
256
+ // Name
257
+ parameter.name = captureGroups[1];
258
+ TrimString(parameter.name);
259
+
260
+ // Default value
261
+ if (!captureGroups[3].empty())
262
+ parameter.defaultValue = captureGroups[3];
263
+
264
+ // Additional Attributes
265
+ if (!captureGroups[5].empty())
266
+ ProcessSignatureAdditionalTraits(section, cur, captureGroups[5], sourceData, result, parameter);
267
+
268
+ // Description
269
+ if (!captureGroups[7].empty())
270
+ parameter.description = captureGroups[7];
271
+
272
+ if (!remainingContent.empty()) {
273
+ parameter.description += "\n";
274
+ parameter.description += remainingContent;
275
+ parameter.description += "\n";
276
+ }
277
+
278
+ // Check possible required vs default clash
279
+ if (parameter.use != OptionalParameterUse &&
280
+ !parameter.defaultValue.empty()) {
281
+
282
+ // WARN: Required vs default clash
283
+ std::stringstream ss;
284
+ ss << "specifying parameter '" << parameter.name << "' as required supersedes its default value"\
285
+ ", declare the parameter as 'optional' to specify its default value";
286
+
287
+ BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
288
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
289
+ result.warnings.push_back(Warning(ss.str(),
290
+ LogicalErrorWarning,
291
+ sourceBlock));
292
+ }
293
+
294
+ }
295
+ else {
296
+ // ERR: unable to parse
297
+ BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
298
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
299
+ result.error = (Error("unable to parse parameter specification",
300
+ BusinessError,
301
+ sourceBlock));
302
+ }
303
+ }
304
+
305
+ /** Parse additional parameter attributes from abbrev definition bracket */
306
+ static void ProcessSignatureAdditionalTraits(const BlueprintSection& section,
307
+ const BlockIterator& cur,
308
+ const SourceData& additionalTraits,
309
+ const SourceData& sourceData,
310
+ Result& result,
311
+ Parameter& parameter)
312
+ {
313
+
314
+ // Cherry pick example value, if any
315
+ std::string source = additionalTraits;
316
+ TrimString(source);
317
+ CaptureGroups captureGroups;
318
+ if (RegexCapture(source, snowcrashconst::AdditionalTraitsExampleRegex, captureGroups) &&
319
+ captureGroups.size() > 1) {
320
+
321
+ parameter.exampleValue = captureGroups[1];
322
+ std::string::size_type pos = source.find(captureGroups[0]);
323
+ if (pos != std::string::npos)
324
+ source.replace(pos, captureGroups[0].length(), std::string());
325
+ }
326
+
327
+ // Cherry pick use attribute, if any
328
+ captureGroups.clear();
329
+ if (RegexCapture(source, snowcrashconst::AdditionalTraitsUseRegex, captureGroups) &&
330
+ captureGroups.size() > 1) {
331
+
332
+ parameter.use = (RegexMatch(captureGroups[1], snowcrashconst::ParameterOptionalRegex)) ? OptionalParameterUse : RequiredParameterUse;
333
+
334
+ std::string::size_type pos = source.find(captureGroups[0]);
335
+ if (pos != std::string::npos)
336
+ source.replace(pos, captureGroups[0].length(), std::string());
337
+ }
338
+
339
+ // Finish with type
340
+ captureGroups.clear();
341
+ if (RegexCapture(source, snowcrashconst::AdditionalTraitsTypeRegex, captureGroups) &&
342
+ captureGroups.size() > 1) {
343
+
344
+ parameter.type = captureGroups[1];
345
+
346
+ std::string::size_type pos = source.find(captureGroups[0]);
347
+ if (pos != std::string::npos)
348
+ source.replace(pos, captureGroups[0].length(), std::string());
349
+ }
350
+
351
+ // Check whats left
352
+ TrimString(source);
353
+ if (!source.empty()) {
354
+ // WARN: Additional parameters traits warning
355
+ std::stringstream ss;
356
+ ss << "unable to parse additional parameter traits";
357
+ ss << ", expected '([required | optional], [<type>], [`<example value>`])'";
358
+ ss << ", e.g. '(optional, string, `Hello World`)'";
359
+
360
+ BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
361
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
362
+ result.warnings.push_back(Warning(ss.str(),
363
+ FormattingWarning,
364
+ sourceBlock));
365
+
366
+ parameter.type.clear();
367
+ parameter.exampleValue.clear();
368
+ parameter.use = UndefinedParameterUse;
369
+ }
370
+ }
371
+
372
+ /** Parse possible values enumeration section blocks. */
373
+ static ParseSectionResult HandleValuesSection(const BlueprintSection& section,
374
+ const BlockIterator& cur,
375
+ BlueprintParserCore& parser,
376
+ Parameter& parameter) {
377
+
378
+ ParseSectionResult result = std::make_pair(Result(), cur);
379
+
380
+ // Check redefinition
381
+ if (!parameter.values.empty()) {
382
+ // WARN: parameter values are already defined
383
+ std::stringstream ss;
384
+ ss << "overshadowing previous 'values' definition";
385
+ ss << " for parameter '" << parameter.name << "'";
386
+
387
+ BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
388
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
389
+ result.first.warnings.push_back(Warning(ss.str(),
390
+ RedefinitionWarning,
391
+ sourceBlock));
392
+ }
393
+
394
+ // Clear any previous content
395
+ parameter.values.clear();
396
+
397
+ // Check additional content in signature
398
+ CheckSignatureAdditionalContent(section,
399
+ cur,
400
+ parser.sourceData,
401
+ "'values:' keyword",
402
+ snowcrashconst::ExpectedValuesContent,
403
+ result.first);
404
+
405
+ // Parse inner list of entities
406
+ BlockIterator sectionCur = SkipSignatureBlock(cur, section.bounds.second);
407
+ BlockIterator endCur = cur;
408
+ if (endCur->type == ListBlockBeginType)
409
+ ++endCur;
410
+ endCur = SkipToClosingBlock(endCur, section.bounds.second, ListItemBlockBeginType, ListItemBlockEndType);
411
+
412
+ if (sectionCur != endCur) {
413
+
414
+ // Iterate over list blocks, try to parse any nested lists of possible elements
415
+ for (; sectionCur != endCur; ++sectionCur) {
416
+
417
+ if (sectionCur->type == QuoteBlockBeginType)
418
+ sectionCur = SkipToClosingBlock(sectionCur, endCur, QuoteBlockBeginType, QuoteBlockEndType);
419
+
420
+ bool entitiesParsed = false;
421
+ if (sectionCur->type == ListBlockBeginType) {
422
+ if (parameter.values.empty()) {
423
+
424
+ // Try to parse some values
425
+ ParseSectionResult valuesResult = ParseValuesEntities(sectionCur,
426
+ section.bounds,
427
+ parser,
428
+ parameter.values);
429
+ result.first += valuesResult.first;
430
+ sectionCur = valuesResult.second;
431
+ if (result.first.error.code != Error::OK)
432
+ return result;
433
+
434
+ entitiesParsed = true;
435
+ }
436
+ else {
437
+ sectionCur = SkipToClosingBlock(sectionCur, endCur, ListBlockBeginType, ListBlockEndType);
438
+ }
439
+ }
440
+
441
+ if (!entitiesParsed) {
442
+ // WARN: ignoring extraneous content
443
+ std::stringstream ss;
444
+ ss << "ignoring additional content in the 'values' attribute of the '";
445
+ ss << parameter.name << "' parameter";
446
+ ss << ", " << snowcrashconst::ExpectedValuesContent;
447
+
448
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(sectionCur, cur, section.bounds, parser.sourceData);
449
+ result.first.warnings.push_back(Warning(ss.str(),
450
+ IgnoringWarning,
451
+ sourceBlock));
452
+ }
453
+ }
454
+ }
455
+
456
+ if (parameter.values.empty()) {
457
+ // WARN: empty definition
458
+ std::stringstream ss;
459
+ ss << "no possible values specified for parameter '" << parameter.name << "'";
460
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(sectionCur, cur, section.bounds, parser.sourceData);
461
+ result.first.warnings.push_back(Warning(ss.str(),
462
+ EmptyDefinitionWarning,
463
+ sourceBlock));
464
+ }
465
+
466
+ if((!parameter.exampleValue.empty() || !parameter.defaultValue.empty()) && !parameter.values.empty()) {
467
+ CheckExampleAndDefaultValue(section, sectionCur, parser, parameter, result);
468
+ }
469
+
470
+ endCur = CloseList(sectionCur, section.bounds.second);
471
+ result.second = endCur;
472
+ return result;
473
+ }
474
+
475
+ /** Parse entities in values attribute */
476
+ static ParseSectionResult ParseValuesEntities(const BlockIterator& cur,
477
+ const SectionBounds& bounds,
478
+ BlueprintParserCore& parser,
479
+ Collection<Value>::type& values) {
480
+
481
+ ParseSectionResult result = std::make_pair(Result(), cur);
482
+
483
+ if (cur->type != ListBlockBeginType)
484
+ return result;
485
+
486
+ BlockIterator sectionCur = ContentBlock(cur, bounds.second);
487
+
488
+ while (sectionCur != bounds.second &&
489
+ sectionCur->type == ListItemBlockBeginType) {
490
+
491
+ sectionCur = SkipToClosingBlock(sectionCur, bounds.second, ListItemBlockBeginType, ListItemBlockEndType);
492
+
493
+ CaptureGroups captureGroups;
494
+ std::string content = sectionCur->content;
495
+ if (content.empty()) {
496
+ // Not inline list, map from source
497
+ content = MapSourceData(parser.sourceData, sectionCur->sourceMap);
498
+ }
499
+
500
+ RegexCapture(content, PARAMETER_VALUE, captureGroups);
501
+ if (captureGroups.size() > 1) {
502
+ values.push_back(captureGroups[1]);
503
+ }
504
+ else {
505
+ // WARN: Ignoring unexpected content
506
+ TrimString(content);
507
+ std::stringstream ss;
508
+ ss << "ignoring the '" << content << "' element";
509
+ ss << ", expected '`" << content << "`'";
510
+
511
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(sectionCur, cur, bounds, parser.sourceData);
512
+ result.first.warnings.push_back(Warning(ss.str(),
513
+ IgnoringWarning,
514
+ sourceBlock));
515
+ }
516
+
517
+ ++sectionCur;
518
+ }
519
+
520
+ result.second = sectionCur;
521
+ return result;
522
+ }
523
+
524
+ static void CheckExampleAndDefaultValue(const BlueprintSection& section,
525
+ const BlockIterator& cur,
526
+ const BlueprintParserCore& parser,
527
+ const Parameter& parameter,
528
+ ParseSectionResult& result) {
529
+
530
+ bool isExampleFound = false;
531
+ bool isDefaultFound = false;
532
+
533
+ for (Collection<Value>::const_iterator it = parameter.values.begin(); it != parameter.values.end(); ++it){
534
+ if(parameter.exampleValue == *it) {
535
+ isExampleFound = true;
536
+ }
537
+ if(parameter.defaultValue == *it) {
538
+ isDefaultFound = true;
539
+ }
540
+ }
541
+
542
+ if(!parameter.exampleValue.empty() && !isExampleFound) {
543
+ // WARN: missing example in values.
544
+ std::stringstream ss;
545
+ ss << "the example value '" << parameter.exampleValue << "' of parameter '"<< parameter.name <<"' is not in its list of expected values";
546
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(cur, section.bounds.second, section.bounds, parser.sourceData);
547
+ result.first.warnings.push_back(Warning(ss.str(),
548
+ LogicalErrorWarning,
549
+ sourceBlock));
550
+ }
551
+
552
+ if(!parameter.defaultValue.empty() && !isDefaultFound) {
553
+ // WARN: missing default in values.
554
+ std::stringstream ss;
555
+ ss << "the default value '" << parameter.defaultValue << "' of parameter '"<< parameter.name <<"' is not in its list of expected values";
556
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(cur, section.bounds.second, section.bounds, parser.sourceData);
557
+ result.first.warnings.push_back(Warning(ss.str(),
558
+ LogicalErrorWarning,
559
+ sourceBlock));
560
+ }
561
+
562
+ return;
563
+ }
564
+
565
+ };
566
+
567
+ typedef BlockParser<Parameter, SectionParser<Parameter> > ParameterDefinitionParser;
568
+ }
569
+
570
+ #endif