redsnow 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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