2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * Copyright © 2006 Pierre Habouzit
24 static buffer_t *buffer_merge(buffer_t *A, buffer_t **B)
31 static inline int to_control(int c) {
32 return (toupper((unsigned char)c) - 'A' + 1) & 0x7f;
35 static buffer_t *buffer_escape(buffer_t *buf, const char *s, ssize_t len)
43 buffer_addch(buf, to_control(s[1]));
44 buffer_add(buf, s + 2, len - 2);
49 int i = (hexval(s[1]) << 4) | hexval(s[2]);
52 buffer_add(buf, s + 3, len - 3);
58 case '0': case '1': case '2': case '3':
60 int i = (octval(s[0]) << 6) | (octval(s[1]) << 3) | octval(s[2]);
63 buffer_add(buf, s + 3, len - 3);
69 case 'e': buffer_addch(buf, '\e'); return buf;
70 case 'f': buffer_addch(buf, '\f'); return buf;
71 case 'n': buffer_addch(buf, '\n'); return buf;
72 case 'r': buffer_addch(buf, '\r'); return buf;
73 case 't': buffer_addch(buf, '\t'); return buf;
74 case 'v': buffer_addch(buf, '\v'); return buf;
80 buffer_add(buf, s, len);
86 %token_type { segment }
89 /****************************************************************************/
91 /****************************************************************************/
94 spaces ::= spaces SPACE .
96 non_nl ::= ATOM|SPACE|BANG|BQUOTE|BSLASH|SHARP|DOLLAR|DQUOTE|EQUAL|LBRACE|PIPE|QUOTE|RBRACE|TILDE .
98 non_nl_star ::= non_nl_star non_nl .
101 to_eol ::= SHARP non_nl_star NL .
102 to_eol ::= spaces SHARP non_nl_star NL .
105 /****************************************************************************/
106 /* Our macro tokens */
107 /****************************************************************************/
109 %type sqtok { buffer_t* }
110 sqtok(C) ::= . { C = buffer_new(); }
111 sqtok(C) ::= sqtok(A) BSLASH BSLASH|QUOTE(B) . { buffer_addch(C = A, *B.s); }
112 sqtok(C) ::= sqtok(A) BSLASH ATOM|SPACE|BANG|BQUOTE|SHARP|DOLLAR|DQUOTE|EQUAL|LBRACE|PIPE|RBRACE|TILDE(B) . {
113 buffer_addch(C = A, '\\');
114 buffer_add(C, B.s, B.len);
116 sqtok(C) ::= sqtok(A) ATOM|SPACE|BANG|BQUOTE|SHARP|DOLLAR|DQUOTE|EQUAL|LBRACE|PIPE|RBRACE|TILDE(B) . {
117 buffer_add(C = A, B.s, B.len);
120 %type dqtok { buffer_t* }
121 dqtok(C) ::= . { C = buffer_new(); }
122 dqtok(C) ::= dqtok(A) BSLASH non_nl(T) . { C = buffer_escape(A, T.s, T.len); }
123 dqtok(C) ::= dqtok(A) ATOM|SPACE|BANG|SHARP|EQUAL|LBRACE|PIPE|RBRACE|TILDE(T) . {
124 buffer_add(C = A, T.s, T.len);
127 %type tok { buffer_t* }
128 tok(R) ::= ATOM|BANG|EQUAL|PIPE|TILDE(T) . {
130 buffer_add(R, T.s, T.len);
132 tok(R) ::= BSLASH non_nl(T) . { R = buffer_new(); buffer_add(R, T.s, T.len); }
133 tok(R) ::= QUOTE sqtok(T) QUOTE . { R = T; }
134 tok(R) ::= DQUOTE dqtok(T) DQUOTE . { R = T; }
136 %type token_acc { buffer_t* }
137 token_acc(A) ::= tok(T) . { A = T; }
138 token_acc(C) ::= token_acc(A) tok(B) . { C = buffer_merge(A, &B); }
140 %type token { buffer_t* }
141 token(R) ::= spaces token_acc(T) . { R = T; }
144 /****************************************************************************/
146 /****************************************************************************/
148 %type simple_list { string_list_t * }
150 simple_list(L) ::= simple_list(A) token(B) . {
151 string_list_t **last = string_list_last(&A);
152 *last = string_item_new();
153 (*last)->data = buffer_unwrap(&B);
158 /****************************************************************************/
159 /* Entry point : the rc lines */
160 /****************************************************************************/
164 rclines ::= rclines rcline .
167 rcline ::= ALT_ORDER simple_list(L) to_eol . {
168 string_list_append(&AlternativeOrderList, L);
172 /* vim: set indentexpr= cin: */