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,46 @@
1
+ //
2
+ // HTTP.cc
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 7/11/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #include "HTTP.h"
10
+
11
+ using namespace snowcrash;
12
+
13
+ const std::string HTTPHeaderName::Accept = "Accept";
14
+ const std::string HTTPHeaderName::ContentLength = "Content-Length";
15
+ const std::string HTTPHeaderName::ContentType = "Content-Type";
16
+ const std::string HTTPHeaderName::TransferEncoding = "Transfer-Encoding";
17
+
18
+ const std::string HTTPMethodName::Head = "HEAD";
19
+ const std::string HTTPMethodName::Connect = "CONNECT";
20
+
21
+ StatusCodeTraits snowcrash::GetStatusCodeTrait(HTTPStatusCode code)
22
+ {
23
+ StatusCodeTraits traits;
24
+ traits.code = code;
25
+
26
+ // Following status codes MUST NOT contain response body
27
+ if (code == 204 || code == 304 || code/100 == 1) {
28
+ traits.allowBody = false;
29
+ }
30
+
31
+ return traits;
32
+ }
33
+
34
+ HTTPMethodTraits snowcrash::GetMethodTrait(HTTPMethod method)
35
+ {
36
+ HTTPMethodTraits traits;
37
+ traits.method = method;
38
+
39
+ // Following HTTP methods MUST NOT contain response body
40
+ // FIXME: When refactoring traits don't forget that 'CONNECT' has no body only when 1xx-2xx
41
+ if (method == HTTPMethodName::Head || method == HTTPMethodName::Connect) {
42
+ traits.allowBody = false;
43
+ }
44
+
45
+ return traits;
46
+ }
@@ -0,0 +1,105 @@
1
+ //
2
+ // HTTP.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 7/11/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_HTTP_H
10
+ #define SNOWCRASH_HTTP_H
11
+
12
+ #include <string>
13
+ #include "Blueprint.h"
14
+
15
+ /**
16
+ * \brief HTTP Methods
17
+ *
18
+ * Technical note: Using preprocessor macro instead of strict
19
+ * defined type due to C++98 string concatenation limitations.
20
+ * FIXME: To be improved with migration to C++11.
21
+ */
22
+ #define HTTP_REQUEST_METHOD "(GET|POST|PUT|DELETE|OPTIONS|PATCH|PROPPATCH|LOCK|UNLOCK|COPY|MOVE|MKCOL|HEAD|LINK|UNLINK|CONNECT)"
23
+
24
+ /**
25
+ * \brief URI Template.
26
+ *
27
+ * See previous technical note (using macro).
28
+ */
29
+ #define URI_TEMPLATE "(/.*)"
30
+
31
+ namespace snowcrash {
32
+
33
+ /**
34
+ * Selected HTTP Header names.
35
+ */
36
+ struct HTTPHeaderName {
37
+ static const std::string Accept;
38
+ static const std::string ContentLength;
39
+ static const std::string ContentType;
40
+ static const std::string TransferEncoding;
41
+ };
42
+
43
+ /**
44
+ * Selected HTTP Method names.
45
+ */
46
+ struct HTTPMethodName {
47
+ static const std::string Head;
48
+ static const std::string Connect;
49
+ };
50
+
51
+ /**
52
+ * A HTTP Status code.
53
+ */
54
+ typedef unsigned int HTTPStatusCode;
55
+
56
+ /**
57
+ * Traits of a HTTP response.
58
+ */
59
+ struct HTTPResponseTraits {
60
+
61
+ bool allowBody; /// < Response body is allowed.
62
+
63
+ HTTPResponseTraits() : allowBody(true) {}
64
+ };
65
+
66
+ /**
67
+ * Response traits for a HTTP method.
68
+ *
69
+ * HTTP request method related response prescription
70
+ * Ref: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
71
+ */
72
+ struct HTTPMethodTraits : HTTPResponseTraits
73
+ {
74
+ HTTPMethod method;
75
+ HTTPMethodTraits() : method("") {}
76
+ };
77
+
78
+ /**
79
+ * Response traits for a HTTP status code.
80
+ *
81
+ * Status-related response prescription.
82
+ * Ref: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
83
+ */
84
+ struct StatusCodeTraits : HTTPResponseTraits
85
+ {
86
+ HTTPStatusCode code;
87
+ StatusCodeTraits() : code(0) {}
88
+ };
89
+
90
+ /**
91
+ * \brief Retrieve response traits for given HTTP method.
92
+ * \param method HTTP method to retrieve traits for.
93
+ * \return A %HTTPMethodTraits for given method.
94
+ */
95
+ extern HTTPMethodTraits GetMethodTrait(HTTPMethod method);
96
+
97
+ /**
98
+ * \brief Retrieve response traits for given status code.
99
+ * \param code A HTTP status code to retrieve traits for.
100
+ * \return A %StatusCodeTraits for given code.
101
+ */
102
+ extern StatusCodeTraits GetStatusCodeTrait(HTTPStatusCode code);
103
+ }
104
+
105
+ #endif
@@ -0,0 +1,289 @@
1
+ //
2
+ // HeaderParser.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 5/22/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_HEADERPARSER_H
10
+ #define SNOWCRASH_HEADERPARSER_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
+
19
+ namespace snowcrashconst {
20
+
21
+ /** Headers matching regex */
22
+ const char* const HeadersRegex = "^[[:blank:]]*[Hh]eaders?[[:blank:]]*$";
23
+ }
24
+
25
+ namespace snowcrash {
26
+
27
+ // Internal type alias for Collection of Headers
28
+ typedef Collection<Header>::type HeaderCollection;
29
+
30
+ // Query header signature a of given block
31
+ FORCEINLINE bool HasHeaderSignature(const BlockIterator& begin,
32
+ const BlockIterator& end) {
33
+
34
+ if (begin->type == ListBlockBeginType || begin->type == ListItemBlockBeginType) {
35
+
36
+ BlockIterator cur = ListItemNameBlock(begin, end);
37
+ if (cur == end)
38
+ return false;
39
+
40
+ if (cur->type != ParagraphBlockType &&
41
+ cur->type != ListItemBlockEndType)
42
+ return false;
43
+
44
+ std::string content = GetFirstLine(cur->content);
45
+ return RegexMatch(content, snowcrashconst::HeadersRegex);
46
+ }
47
+
48
+ return false;
49
+ }
50
+
51
+ // Header iterator in its containment group
52
+ typedef Collection<Header>::const_iterator HeaderIterator;
53
+
54
+ // Finds a header in its containment group by its key (first)
55
+ FORCEINLINE HeaderIterator FindHeader(const HeaderCollection& headers,
56
+ const Header& header) {
57
+
58
+ return std::find_if(headers.begin(),
59
+ headers.end(),
60
+ std::bind2nd(MatchFirsts<Header>(), header));
61
+ }
62
+
63
+ /** Internal list items classifier, Headers Context */
64
+ template <>
65
+ FORCEINLINE SectionType ClassifyInternaListBlock<HeaderCollection>(const BlockIterator& begin,
66
+ const BlockIterator& end) {
67
+ return UndefinedSectionType;
68
+ }
69
+
70
+ /** Children List Block Classifier, HeaderCollection context. */
71
+ template <>
72
+ FORCEINLINE SectionType ClassifyChildrenListBlock<HeaderCollection>(const BlockIterator& begin,
73
+ const BlockIterator& end){
74
+ return UndefinedSectionType;
75
+ }
76
+
77
+ /** Block Classifier, Headers Context */
78
+ template <>
79
+ FORCEINLINE SectionType ClassifyBlock<HeaderCollection>(const BlockIterator& begin,
80
+ const BlockIterator& end,
81
+ const SectionType& context) {
82
+
83
+ if (context == UndefinedSectionType &&
84
+ HasHeaderSignature(begin, end)) {
85
+ return HeadersSectionType;
86
+ }
87
+ else if (context == HeadersSectionType) {
88
+
89
+ // SectionType closure
90
+ if (begin->type == ListItemBlockEndType ||
91
+ begin->type == ListBlockEndType)
92
+ return UndefinedSectionType;
93
+
94
+ // Adjacent list item
95
+ if (begin->type == ListItemBlockBeginType)
96
+ return UndefinedSectionType;
97
+ }
98
+
99
+ return (context == HeadersSectionType) ? context : UndefinedSectionType;
100
+ }
101
+
102
+ //
103
+ // Headers SectionType Parser
104
+ //
105
+ template<>
106
+ struct SectionParser<HeaderCollection> {
107
+
108
+ static ParseSectionResult ParseSection(const BlueprintSection& section,
109
+ const BlockIterator& cur,
110
+ BlueprintParserCore& parser,
111
+ HeaderCollection& headers) {
112
+
113
+ ParseSectionResult result = std::make_pair(Result(), cur);
114
+ switch (section.type) {
115
+ case HeadersSectionType:
116
+ result = HandleHeadersSectionBlock(section, cur, parser, headers);
117
+ break;
118
+
119
+ case UndefinedSectionType:
120
+ result.second = CloseList(cur, section.bounds.second);
121
+ break;
122
+
123
+ default:
124
+ result.first.error = UnexpectedBlockError(section, cur, parser.sourceData);
125
+ break;
126
+ }
127
+
128
+ return result;
129
+ }
130
+
131
+ static void Finalize(const SectionBounds& bounds,
132
+ BlueprintParserCore& parser,
133
+ HeaderCollection& headers,
134
+ Result& result) {}
135
+
136
+ static ParseSectionResult HandleHeadersSectionBlock(const BlueprintSection& section,
137
+ const BlockIterator& cur,
138
+ BlueprintParserCore& parser,
139
+ HeaderCollection& headers) {
140
+
141
+ SourceData data;
142
+ SourceDataBlock sourceMap;
143
+ ParseSectionResult result = ParseListPreformattedBlock<HeaderCollection>(section,
144
+ cur,
145
+ parser,
146
+ data,
147
+ sourceMap);
148
+ if (result.first.error.code != Error::OK ||
149
+ parser.sourceData.empty())
150
+ return result;
151
+
152
+ // Proces raw data
153
+ std::vector<std::string> lines = Split(data, '\n');
154
+ for (std::vector<std::string>::iterator line = lines.begin();
155
+ line != lines.end();
156
+ ++line) {
157
+
158
+ Header header;
159
+ if (KeyValueFromLine(*line, header)) {
160
+
161
+ if (FindHeader(headers, header) != headers.end()) {
162
+ // WARN: duplicate header on this level
163
+ std::stringstream ss;
164
+ ss << "duplicate definition of '" << header.first << "' header";
165
+
166
+ result.first.warnings.push_back(Warning(ss.str(),
167
+ DuplicateWarning,
168
+ MapSourceDataBlock(sourceMap, parser.sourceData)));
169
+
170
+ }
171
+
172
+ headers.push_back(header);
173
+ }
174
+ else {
175
+ // WARN: unable to parse header
176
+ result.first.warnings.push_back(Warning("unable to parse HTTP header, expected"
177
+ " '<header name> : <header value>', one header per line",
178
+ FormattingWarning,
179
+ MapSourceDataBlock(sourceMap, parser.sourceData)));
180
+ }
181
+ }
182
+
183
+ return result;
184
+ }
185
+ };
186
+
187
+ typedef BlockParser<HeaderCollection, SectionParser<HeaderCollection> > HeadersParser;
188
+
189
+ /**
190
+ * Generic HeaderSection parser handler
191
+ */
192
+ template <class T>
193
+ ParseSectionResult HandleHeaders(const BlueprintSection& section,
194
+ const BlockIterator& cur,
195
+ BlueprintParserCore& parser,
196
+ T& t)
197
+ {
198
+ size_t headerCount = t.headers.size();
199
+ ParseSectionResult result = HeadersParser::Parse(cur,
200
+ section.bounds.second,
201
+ section,
202
+ parser,
203
+ t.headers);
204
+ if (result.first.error.code != Error::OK)
205
+ return result;
206
+
207
+ if (t.headers.size() == headerCount) {
208
+ BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
209
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
210
+ result.first.warnings.push_back(Warning("no headers specified",
211
+ FormattingWarning,
212
+ sourceBlock));
213
+ }
214
+ return result;
215
+ }
216
+
217
+
218
+ /** Helper for handling parsing of deprecated header sections */
219
+ template <typename T>
220
+ ParseSectionResult HandleDeprecatedHeaders(const BlueprintSection& section,
221
+ const BlockIterator& cur,
222
+ BlueprintParserCore& parser,
223
+ T& t) {
224
+
225
+ ParseSectionResult result = HandleHeaders<T>(section, cur, parser, t);
226
+
227
+ // WARN: Deprecated header sections
228
+ std::stringstream ss;
229
+ ss << "the 'headers' section at this level is deprecated and will be removed in a future, use respective payload header section(s) instead";
230
+ BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
231
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
232
+ result.first.warnings.push_back(Warning(ss.str(),
233
+ DeprecatedWarning,
234
+ sourceBlock));
235
+ return result;
236
+ }
237
+
238
+ /** \brief Copy headers into example paylods headers. */
239
+ FORCEINLINE void InjectDeprecatedHeaders(const Collection<Header>::type& headers,
240
+ Collection<TransactionExample>::type& examples)
241
+ {
242
+ for (Collection<TransactionExample>::iterator exampleIt = examples.begin();
243
+ exampleIt != examples.end();
244
+ ++exampleIt) {
245
+
246
+ // Requests
247
+ for (Collection<Request>::iterator reqIt = exampleIt->requests.begin();
248
+ reqIt != exampleIt->requests.end();
249
+ ++reqIt) {
250
+
251
+ reqIt->headers.insert(reqIt->headers.begin(),
252
+ headers.begin(),
253
+ headers.end());
254
+ }
255
+
256
+ // Responses
257
+ for (Collection<Response>::iterator resIt = exampleIt->responses.begin();
258
+ resIt != exampleIt->responses.end();
259
+ ++resIt) {
260
+
261
+ resIt->headers.insert(resIt->headers.begin(),
262
+ headers.begin(),
263
+ headers.end());
264
+ }
265
+ }
266
+ }
267
+
268
+ // Checks T's headers for occurence of R's headers, warns if a match is found.
269
+ template <class T, class R>
270
+ void CheckHeaderDuplicates(const T& left,
271
+ const R& right,
272
+ const SourceDataBlock& rightSourceMap,
273
+ const SourceData& sourceData,
274
+ Result& result) {
275
+
276
+ for (HeaderIterator it = right.headers.begin(); it != right.headers.end(); ++it) {
277
+ if (FindHeader(left.headers, *it) != left.headers.end()) {
278
+ // WARN: overshadowing header definition
279
+ std::stringstream ss;
280
+ ss << "overshadowing previous '" << it->first << "' header definition";
281
+ result.warnings.push_back(Warning(ss.str(),
282
+ RedefinitionWarning,
283
+ MapSourceDataBlock(rightSourceMap, sourceData)));
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ #endif
@@ -0,0 +1,273 @@
1
+ //
2
+ // ListBlockUtility.h
3
+ // snowcrash
4
+ //
5
+ // All the cool kids from ListUtility.h live here.
6
+ //
7
+ // Created by Zdenek Nemec on 11/11/13.
8
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
9
+ //
10
+
11
+ #ifndef SNOWCRASH_LISTBLOCKUTILITY_H
12
+ #define SNOWCRASH_LISTBLOCKUTILITY_H
13
+
14
+ #include "ListUtility.h"
15
+
16
+ namespace snowcrash {
17
+
18
+ /**
19
+ * \brief Return a first non-signature content block of a list(item).
20
+ * \param begin Begin of the block buffer to examine.
21
+ * \param end End of the block buffer.
22
+ * \return First non-signature content block or begin.
23
+ *
24
+ * Returns first block with the actual content of a list or list item.
25
+ */
26
+ FORCEINLINE BlockIterator ContentBlock(const BlockIterator& begin,
27
+ const BlockIterator& end) {
28
+
29
+ BlockIterator cur = begin;
30
+ if (cur->type == ListBlockBeginType) {
31
+ if (++cur == end)
32
+ return end;
33
+
34
+ return cur;
35
+ }
36
+
37
+ if (cur->type == ListItemBlockBeginType) {
38
+ if (++cur == end)
39
+ return end;
40
+
41
+ if (cur->type == ListItemBlockEndType)
42
+ return begin;
43
+
44
+ if (cur->type == ParagraphBlockType)
45
+ if (++cur == end)
46
+ return end;
47
+ }
48
+
49
+ return cur;
50
+ }
51
+
52
+ /**
53
+ * \brief Skips first list item signature block.
54
+ *
55
+ * This function effectively returns the first content block of
56
+ * a list item that is not a signature block. If no such a block exists.
57
+ * a block following the list item is returned. If a list is provided it
58
+ * uses its first list item.
59
+ */
60
+ FORCEINLINE BlockIterator SkipSignatureBlock(const BlockIterator& begin,
61
+ const BlockIterator& end) {
62
+
63
+ BlockIterator cur = begin;
64
+
65
+ // Skip to fist list item if appropriate
66
+ if (cur->type == ListBlockBeginType) {
67
+ cur = ContentBlock(cur, end);
68
+ }
69
+
70
+ // Skip to first list item content
71
+ if (cur->type == ListItemBlockBeginType) {
72
+ BlockIterator firstContent = ContentBlock(cur, end);
73
+ if (cur != firstContent) {
74
+ cur = firstContent;
75
+ }
76
+ else {
77
+ // No content, just move to the next block
78
+ ++cur;
79
+ }
80
+ }
81
+
82
+ return cur;
83
+ }
84
+
85
+ // Return name block of list item; that is either FirstContentBlock() or
86
+ // matching closing item block for inline items
87
+ FORCEINLINE BlockIterator ListItemNameBlock(const BlockIterator& begin,
88
+ const BlockIterator& end) {
89
+
90
+ BlockIterator cur = FirstContentBlock(begin, end);
91
+ if (cur == end ||
92
+ cur->type != ListBlockBeginType)
93
+ return cur;
94
+
95
+ // Inline list block
96
+ cur = SkipToClosingBlock(cur, end, ListBlockBeginType, ListBlockEndType);
97
+ if (cur != end)
98
+ return ++cur;
99
+
100
+ return cur;
101
+ }
102
+
103
+ /**
104
+ * \brief Eats closing blocks of a list / list item block.
105
+ * \param begin Cursor to a list or list item closing block.
106
+ * \param end End of a block buffer.
107
+ * \return Block AFTER closed list / list item.
108
+ *
109
+ * Skips over subsequent ListItemBlockEndType and ListBlockEndType returning the fist
110
+ * other block after.
111
+ */
112
+ FORCEINLINE BlockIterator CloseList(const BlockIterator& begin,
113
+ const BlockIterator& end) {
114
+
115
+ BlockIterator cur = begin;
116
+ if (cur != end &&
117
+ cur->type == ListItemBlockEndType) {
118
+ ++cur; // eat list item end
119
+ }
120
+
121
+ if (cur != end &&
122
+ cur->type == ListBlockEndType) {
123
+ ++cur; // eat list end
124
+ }
125
+
126
+ return cur;
127
+ }
128
+
129
+ /**
130
+ * \brief Skips COMPLETE consecutive (nested) closing elements of a list or a list item.
131
+ * \param begin The begin of a list or a list item.
132
+ * \param end End of markdown block buffer.
133
+ * \return An iterator pointing AFTER the last closing list / list item block.
134
+ */
135
+ FORCEINLINE BlockIterator CloseNestedList(const BlockIterator& begin,
136
+ const BlockIterator& end) {
137
+ BlockIterator cur = begin;
138
+ while (cur != end &&
139
+ (cur->type == ListItemBlockEndType || cur->type == ListBlockEndType)) {
140
+ cur = CloseList(cur, end);
141
+ }
142
+ return cur;
143
+ }
144
+
145
+ /**
146
+ * \brief Extract the first line of a list item content - its signature
147
+ * \param cur The begining of the list item to get its signature.
148
+ * \param end The begining of a block buffer.
149
+ * \param remainingContent Any additonal content after the first line of signature.
150
+ * \return First line of the list item signature.
151
+ */
152
+ FORCEINLINE SourceData GetListItemSignature(const BlockIterator& cur,
153
+ const BlockIterator& end,
154
+ SourceData& remainingContent) {
155
+
156
+ BlockIterator sectionCur = ListItemNameBlock(cur, end);
157
+ if (sectionCur == end)
158
+ return SourceData();
159
+
160
+ ContentParts content = ExtractFirstLine(*sectionCur);
161
+ if (content.empty() ||
162
+ content.front().empty())
163
+ return SourceData();
164
+
165
+ if (content.size() == 2)
166
+ remainingContent = content[1];
167
+
168
+ return content[0];
169
+ }
170
+
171
+ /**
172
+ * \brief Check List Item signature for an addtional content and issue a warning.
173
+ * \param section Current section to be checked.
174
+ * \param cur The begining of the list item to check.
175
+ * \param bounds Bounds within the block buffer.
176
+ * \param sourceData Source data byte buffer.
177
+ * \param placeHint A string explaining the possible place of failure. Might be empty.
178
+ * \param expectedHint A string defining expected content. Might be empty.
179
+ * \param result Result to append the possible warning into.
180
+ * \return True if signagure contains no additional content, false otherwise.
181
+ */
182
+ FORCEINLINE bool CheckSignatureAdditionalContent(const BlueprintSection& section,
183
+ const BlockIterator& cur,
184
+ const SourceData& sourceData,
185
+ const std::string& placeHint,
186
+ const std::string& expectedHint,
187
+ Result& result)
188
+ {
189
+ SourceData remainingContent;
190
+ SourceData signature = GetListItemSignature(cur, section.bounds.second, remainingContent);
191
+
192
+ if (!remainingContent.empty()) {
193
+ // WARN: Superfluous content in signature
194
+
195
+ std::stringstream ss;
196
+ ss << "ignoring additional content";
197
+
198
+ if (!placeHint.empty())
199
+ ss << " after " << placeHint;
200
+
201
+ if (!expectedHint.empty())
202
+ ss << ", expected " << expectedHint;
203
+
204
+ BlockIterator nameBlock = ListItemNameBlock(cur, section.bounds.second);
205
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, sourceData);
206
+ result.warnings.push_back(Warning(ss.str(),
207
+ IgnoringWarning,
208
+ sourceBlock));
209
+ }
210
+
211
+ return remainingContent.empty();
212
+ }
213
+
214
+ /**
215
+ * \brief Parses list (item) block as a preformatted code block.
216
+ * \param section Actual section being parsed.
217
+ * \param cur Cursor within the section boundaries.
218
+ * \param parser Parser instance.
219
+ * \param action An output data buffer.
220
+ * \param sourceMap An output source map buffer.
221
+ * \return A block parser section result, pointing AFTER the last block parsed.
222
+ */
223
+ template <class T>
224
+ FORCEINLINE ParseSectionResult ParseListPreformattedBlock(const BlueprintSection& section,
225
+ const BlockIterator& cur,
226
+ BlueprintParserCore& parser,
227
+ SourceData& data,
228
+ SourceDataBlock& sourceMap) {
229
+
230
+ ParseSectionResult result = std::make_pair(Result(), cur);
231
+ BlockIterator sectionCur = cur;
232
+
233
+ if (sectionCur != section.bounds.first) {
234
+ // Parse subsequent blocks as standalone pre blocks.
235
+ return ParsePreformattedBlock<T>(section, sectionCur, parser, data, sourceMap);
236
+ }
237
+
238
+ // Parse first block of list, throwing away its first line (signature)
239
+ SourceData content;
240
+ SourceData signature = GetListItemSignature(cur, section.bounds.second, content);
241
+
242
+ // Retrieve any extra lines after signature & warn
243
+ if (!content.empty()) {
244
+
245
+ data = content;
246
+
247
+ // WARN: not a preformatted code block
248
+ std::stringstream ss;
249
+
250
+ size_t level = CodeBlockIndentationLevel(section);
251
+ ss << SectionName(section.type) << " asset ";
252
+ ss << "is expected to be a pre-formatted code block, separate it by a newline and ";
253
+ ss << "indent every of its line by ";
254
+ ss << level * 4 << " spaces or " << level << " tabs";
255
+
256
+ BlockIterator nameBlock = ListItemNameBlock(sectionCur, section.bounds.second);
257
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(nameBlock, cur, section.bounds, parser.sourceData);
258
+ result.first.warnings.push_back(Warning(ss.str(),
259
+ IndentationWarning,
260
+ sourceBlock));
261
+ }
262
+
263
+ sectionCur = FirstContentBlock(cur, section.bounds.second);
264
+ sourceMap = sectionCur->sourceMap;
265
+
266
+ if (sectionCur != section.bounds.second)
267
+ result.second = ++sectionCur;
268
+
269
+ return result;
270
+ }
271
+ }
272
+
273
+ #endif