OTWO-1213 Works around lost encoding in Ruby/C binding layer
[ohcount] / src / parsers / xmlschema.rl
1 // xmlschema.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
2
3 /************************* Required for every parser *************************/
4 #ifndef OHCOUNT_XMLSCHEMA_PARSER_H
5 #define OHCOUNT_XMLSCHEMA_PARSER_H
6
7 #include "../parser_macros.h"
8
9 // the name of the language
10 const char *XMLSCHEMA_LANG = LANG_XMLSCHEMA;
11
12 // the languages entities
13 const char *xmlschema_entities[] = {
14   "space", "comment", "doctype",
15   "tag", "entity", "any"
16 };
17
18 // constants associated with the entities
19 enum {
20   XMLSCHEMA_SPACE = 0, XMLSCHEMA_COMMENT, XMLSCHEMA_DOCTYPE,
21   XMLSCHEMA_TAG, XMLSCHEMA_ENTITY, XMLSCHEMA_ANY
22 };
23
24 /*****************************************************************************/
25
26 %%{
27   machine xmlschema;
28   write data;
29   include common "common.rl";
30
31   # Line counting machine
32
33   action xmlschema_ccallback {
34     switch(entity) {
35     case XMLSCHEMA_SPACE:
36       ls
37       break;
38     case XMLSCHEMA_ANY:
39       code
40       break;
41     case INTERNAL_NL:
42       std_internal_newline(XMLSCHEMA_LANG)
43       break;
44     case NEWLINE:
45       std_newline(XMLSCHEMA_LANG)
46       break;
47     case CHECK_BLANK_ENTRY:
48       check_blank_entry(XMLSCHEMA_LANG)
49     }
50   }
51
52   xmlschema_comment =
53     '<!--' @comment (
54       newline %{ entity = INTERNAL_NL; } %xmlschema_ccallback
55       |
56       ws
57       |
58       (nonnewline - ws) @comment
59     )* :>> '-->';
60
61   xmlschema_sq_str = '\'' ([^\r\n\f'\\] | '\\' nonnewline)* '\'' @code;
62   xmlschema_dq_str = '"' ([^\r\n\f"\\] | '\\' nonnewline)* '"' @code;
63   xmlschema_cdata_str =
64     '<![CDATA[' @code (
65       newline %{ entity = INTERNAL_NL; } %xmlschema_ccallback
66       |
67       ws
68       |
69       (nonnewline - ws) @code
70     )* :>> ']]>';
71   xmlschema_string = xmlschema_sq_str | xmlschema_dq_str | xmlschema_cdata_str;
72
73   xmlschema_line := |*
74     spaces             ${ entity = XMLSCHEMA_SPACE; } => xmlschema_ccallback;
75     xmlschema_comment;
76     xmlschema_string;
77     newline            ${ entity = NEWLINE;         } => xmlschema_ccallback;
78     ^space             ${ entity = XMLSCHEMA_ANY;   } => xmlschema_ccallback;
79   *|;
80
81   # Entity machine
82
83   action xmlschema_ecallback {
84     callback(XMLSCHEMA_LANG, xmlschema_entities[entity], cint(ts), cint(te),
85              userdata);
86   }
87
88   xmlschema_comment_entity = '<!--' any* :>> '-->';
89
90   xmlschema_entity := |*
91     space+                   ${ entity = XMLSCHEMA_SPACE;   } => xmlschema_ecallback;
92     xmlschema_comment_entity ${ entity = XMLSCHEMA_COMMENT; } => xmlschema_ecallback;
93     # TODO:
94     ^space;
95   *|;
96
97 }%%
98
99 /************************* Required for every parser *************************/
100
101 /* Parses a string buffer with XML Schema markup.
102  *
103  * @param *buffer The string to parse.
104  * @param length The length of the string to parse.
105  * @param count Integer flag specifying whether or not to count lines. If yes,
106  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
107  *   machine optimized for returning entity positions.
108  * @param *callback Callback function. If count is set, callback is called for
109  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
110  *   'lblank' respectively. Otherwise callback is called for each entity found.
111  */
112 void parse_xmlschema(char *buffer, int length, int count,
113                      void (*callback) (const char *lang, const char *entity,
114                                        int s, int e, void *udata),
115                      void *userdata
116   ) {
117   init
118
119   %% write init;
120   cs = (count) ? xmlschema_en_xmlschema_line : xmlschema_en_xmlschema_entity;
121   %% write exec;
122
123   // if no newline at EOF; callback contents of last line
124   if (count) { process_last_line(XMLSCHEMA_LANG) }
125 }
126
127 #endif
128
129 /*****************************************************************************/