ppnumsplit fix
[mala.git] / std / std_pp.c
blobc2893d6e0fc48d5ff4bc4b64d7a517af3a835410
1 /*
2 std_pp.c - MaLa standard preprocessor
4 Copyright (C) 2007, Christian Thaeter <ct@pipapo.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, contact me.
20 #include <ctype.h>
21 #include "mala.h"
22 #include "std_pp.h"
24 static
25 mala_actioninit std_pp[] =
28 MALA_PARSER_SUBSTITUTE("--PREPROCESS", "--PREPROCESS-ARGV"),
30 MALA_PARSER_EXPAND("--PREPROCESS-ARGV",
31 ("--DEF", "--LITERAL", "--ERROR-MISSING-ARGUMENT",
32 "--BEGIN","--DEL", "--LITERAL", "--ERROR-MISSING-ARGUMENT", "--END",
33 "--PP-ARGV")),
35 MALA_PARSER_SUBSTITUTE("--PP-ARGV", "--PP-BACKQUOTE-ARGV"),
37 MALA_PARSER_MACRO("--PP-ARGV-RESTART",("--LITERAL","%^1", "--PP-ARGV")),
39 MALA_PARSER_SIMPLE("--PP-BACKQUOTE-ARGV", mala_ppbackquote_parser),
40 MALA_PARSER_SUBSTITUTE("--PP-BACKQUOTE-ARGV-START", "--PP-ARGV"),
41 MALA_PARSER_SUBSTITUTE("--PP-BACKQUOTE-ARGV-CONTINUE", "--PP-NUMSPLIT-ARGV"),
43 MALA_PARSER_SIMPLE("--PP-NUMSPLIT-ARGV", mala_ppnumsplit_parser),
44 MALA_PARSER_SUBSTITUTE("--PP-NUMSPLIT-ARGV-CONTINUE", "--PP-EXCLAM-ARGV"),
45 //MALA_PARSER_SUBSTITUTE("--PP-NUMSPLIT-ARGV-CONTINUE", "--PP-EXCLAM-ARGV"), // TODO state to bypass EXLAM (optimization)
47 MALA_PARSER_SIMPLE("--PP-EXCLAM-ARGV", mala_ppexclam_parser),
48 MALA_PARSER_SUBSTITUTE("--PP-EXCLAM-ARGV-START", "--PP-ARGV-RESTART"),
49 MALA_PARSER_SUBSTITUTE("--PP-EXCLAM-ARGV-CONTINUE", "--PP-ARGV-RESTART"),
53 MALA_PARSER_SIMPLE("--PP-QUOTED", mala_ppquoted_parser),
54 MALA_PARSER_SIMPLE("--PP-DQUOTED", mala_ppdquoted_parser),
55 MALA_PARSER_SIMPLE("--PP-NUMSPLIT", mala_ppnumsplit_parser),
56 MALA_PARSER_SIMPLE("--PP-EXCLAM", mala_ppexclam_parser),
57 MALA_PARSER_SIMPLE("--PP-NO", mala_ppno_parser),
58 MALA_PARSER_SIMPLE("--PP-ASSIGN", mala_ppassign_parser),
59 MALA_PARSER_SIMPLE("--PP-CHAR", mala_ppchar_parser),
60 MALA_PARSER_SIMPLE("--PP-PLUS", mala_ppplus_parser),
61 MALA_PARSER_SIMPLE("--PP_UNDERSCORE", mala_ppunderscore_parser),
62 MALA_PARSER_SIMPLE("--PP-SECTION", mala_ppsection_parser),
63 MALA_PARSER_SIMPLE("--PP-ASSIGNCONCAT", mala_ppassignconcat_parser),
64 MALA_PARSER_SIMPLE("--PP-ENVSUBST", mala_ppenvsubst_parser),
65 MALA_PARSER_SIMPLE("--PP-SETENV", mala_ppsetenv_parser),
66 MALA_PARSER_SIMPLE("--PP-BRACE", mala_ppbrace_parser),
67 MALA_PARSER_SIMPLE("--PP-SIMPLE", mala_pplist_parser),
68 MALA_PARSER_SIMPLE("--PP-COMMAND", mala_ppcommand_parser),
69 MALA_PARSER_SIMPLE("--PP-TOKENIZE", mala_pptokenize_parser),
70 MALA_PARSER_SIMPLE("--PP-DASHDASH", mala_ppdashdash_parser),
72 MALA_ACTIONS_END
78 HOWTO
79 envsubst in literal?
81 note: want a --PP-STOP?
83 --PREPROCESS should be defined to the proper preprocessor
85 --PREPROCESS-ARGV-MINIMAL
88 --PREPROCESS-ARGV preprocessor for commandline options
89 --PP-BACKQUOTE --PP-NUMSPLIT --PP-EXCLAM --PP-NO --PP-ASSIGN --PP-CHAR --PP-PLUS --PP-UNDERSCORE --PP-SECTION --PP-ASSIGN-CONCAT --PP-ENVSUBST --PP-SETENV
91 --PREPROCESS-CONF preprocessor for config files
92 --PP-QUOTED --PP-DQUOTED --PP-NUMSPLIT --PP-EXCLAM --PP-NO --PP-ASSIGN --PP-CHAR --PP-PLUS --PP-UNDERSCORE --PP-SECTION --PP-ASSIGN-CONCAT --PP-ENVSUBST --PP-SETENV --PP-BRACE --PP-LIST --PP-COMMAND
94 --PREPROCESS-CMD preprocessor for commandline
95 --PP-TOKENINZE --PP-LITERAL --PP-NUMSPLIT --PP-EXCLAM --PP-NO --PP-ASSIGN --PP-CHAR --PP-PLUS --PP-UNDERSCORE --PP-SECTION --PP-ASSIGN-CONCAT --PP-ENVSUBST --PP-SETENV --PP-BRACE --PP-LIST --PP-COMMAND
101 Preprocessing applies different parsers to works which might in turn modify them. When finished
102 with a word it may iterate to the next word and restart the preprocessing.
104 This is done as state-machine where each parser uses
105 %0-NEXT to restart on the next word
107 %0-CONTINUE to
110 parser 1) 2)
111 --PP-BACKQUOTE-ARG --PP-ARGV --PP-NUMSPLIT-ARGV
112 --PP-NUMSPLIT-ARGV --PP-ARGV --PP-EXCLAM-ARGV
113 --PP-EXCLAM-ARGV --PP-ARGV --PP-NO-ARGV
114 --PP-NO-ARGV --PP-ARGV --PP-ASSIGN-ARGV
115 --PP-ASSIGN-ARGV --PP-ARGV --PP-CHAR-ARGV
116 --PP-CHAR-ARGV --PP-ARGV --PP-PLUS-ARGV
117 --PP-PLUS-ARGV --PP-ARGV --PP-UNDERSCORE-ARGV
118 --PP-UNDERSCORE-ARGV --PP-ARGV
124 --PP-BACKQUOTE
125 literal_expansion `foo becomes --LITERAL foo, where ` is the default of --BACKQUOTE-EXPANSION-CHAR
126 backquote_expansion ``foo becomes `foo without literal expansion (escaping of literal expansion)
128 mala_state
129 mala_ppbackquote_parser (MalaProgram prg)
131 int args = 0;
132 TRACE (mala_module_std);
134 MALA_MUTATOR_BEGIN
136 MalaStringList str = mala_stringlist_next(mala_stringlist_next(prg->pptr));
138 if (str != prg->program)
140 ACOGC_STACK_ENTER (&prg->engine->gcroot);
141 ACOGC_STACK_PTR(MalaString, s);
142 ACOGC_STACK_PTR(MalaStringList, n);
144 if (mala_stringlist_cstr (str)[0] == '`' && mala_stringlist_cstr (str)[1])
146 if (mala_stringlist_cstr (str)[1] != '`')
148 s.ptr = mala_string_new_print (prg->engine->words, "%s-START",mala_program_pptr_cstr(prg));
149 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
150 mala_stringlist_insert_after (str, n.ptr);
152 n.ptr = mala_stringlist_node_new_cstr (mala_stringlist_cstr (str) + 1, prg->engine);
153 mala_stringlist_insert_after (str, n.ptr);
155 n.ptr = mala_stringlist_node_new (prg->engine->common_string[MALA_STRING_LITERAL], prg->engine);
156 mala_stringlist_insert_after (str, n.ptr);
158 s.ptr = mala_string_new_literal_cstr ("2", prg->engine->words);
159 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
160 mala_stringlist_insert_after (str, n.ptr);
162 s.ptr = mala_string_new_literal_cstr ("--SKIP", prg->engine->words);
163 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
164 mala_stringlist_insert_after (str, n.ptr);
166 args = 1;
168 else
170 n.ptr = mala_stringlist_node_new_cstr (mala_stringlist_cstr (str) + 1, prg->engine);
171 mala_stringlist_insert_after (str, n.ptr);
173 s.ptr = mala_string_new_print (prg->engine->words, "%s-CONTINUE",mala_program_pptr_cstr(prg));
174 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
175 mala_stringlist_insert_after (str, n.ptr);
177 args = 1;
180 else
182 s.ptr = mala_string_new_print (prg->engine->words, "%s-CONTINUE",mala_program_pptr_cstr(prg));
183 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
184 mala_stringlist_insert_after (mala_stringlist_next(prg->pptr), n.ptr);
185 args = 0;
188 ACOGC_STACK_LEAVE;
191 MALA_MUTATOR_END;
193 mala_program_action_done (prg, args);
194 return MALA_STATEMENT;
199 --PP-NUMSPLIT
200 numsplit_expansion -a10 becomes -a 10
202 mala_state
203 mala_ppnumsplit_parser (MalaProgram prg)
205 int args = 0;
206 TRACE (mala_module_std);
208 MALA_MUTATOR_BEGIN
210 MalaStringList str = mala_stringlist_next(mala_stringlist_next(prg->pptr));
211 if (str != prg->program)
213 ACOGC_STACK_ENTER (&prg->engine->gcroot);
214 ACOGC_STACK_PTR(MalaString, s);
215 ACOGC_STACK_PTR(MalaStringList, n);
216 /* starts with -[^-0-9] */
217 const char* begin = mala_stringlist_cstr (str);
219 if (begin[0] == '-' && begin[1] && begin[1] != '-' && !isdigit(begin[1]))
221 const char* i;
222 for (i = begin + 2;
223 *i && !isdigit(*i);
224 ++i);
226 if (*i)
228 size_t len1 = i - begin;
230 s.ptr = mala_string_new_cstr_n (begin + len1,
231 mala_string_length (mala_stringlist_string (str)) - len1,
232 prg->engine->words);
233 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
234 mala_stringlist_insert_after (str, n.ptr);
236 s.ptr = mala_string_new_cstr_n (begin,
237 len1,
238 prg->engine->words);
239 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
240 mala_stringlist_insert_after (str, n.ptr);
242 s.ptr = mala_string_new_print (prg->engine->words, "%s-CONTINUE",mala_program_pptr_cstr(prg));
243 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
244 mala_stringlist_insert_after (str, n.ptr);
246 args = 1;
249 else
251 s.ptr = mala_string_new_print (prg->engine->words, "%s-CONTINUE",mala_program_pptr_cstr(prg));
252 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
253 mala_stringlist_insert_before (str, n.ptr);
254 args = 0;
256 ACOGC_STACK_LEAVE;
259 MALA_MUTATOR_END;
261 mala_program_action_done (prg, args);
262 return MALA_STATEMENT;
267 --PP-EXCLAM
268 exclam_expansion ! becomes --NO
270 mala_state
271 mala_ppexclam_parser (MalaProgram prg)
273 int args = 0;
274 TRACE (mala_module_std);
276 MALA_MUTATOR_BEGIN
278 MalaStringList str = mala_stringlist_next(mala_stringlist_next(prg->pptr));
279 if (str != prg->program)
281 ACOGC_STACK_ENTER (&prg->engine->gcroot);
282 ACOGC_STACK_PTR(MalaString, s);
283 ACOGC_STACK_PTR(MalaStringList, n);
285 if (mala_stringlist_string(str) == prg->engine->common_string[MALA_STRING_EXCLAMATIONMARK])
287 s.ptr = mala_string_new_print (prg->engine->words, "%s-CONTINUE",mala_program_pptr_cstr(prg));
288 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
289 mala_stringlist_insert_after (str, n.ptr);
291 n.ptr = mala_stringlist_node_new (prg->engine->common_string[MALA_STRING_NO], prg->engine);
292 mala_stringlist_insert_after (str, n.ptr);
294 n.ptr = mala_stringlist_node_new (prg->engine->common_string[MALA_STRING_LITERAL], prg->engine);
295 mala_stringlist_insert_after (str, n.ptr);
296 args = 1;
298 else
300 s.ptr = mala_string_new_print (prg->engine->words, "%s-CONTINUE",mala_program_pptr_cstr(prg));
301 n.ptr = mala_stringlist_node_new (s.ptr , prg->engine);
302 mala_stringlist_insert_before (str, n.ptr);
303 args = 0;
305 ACOGC_STACK_LEAVE;
308 MALA_MUTATOR_END;
310 mala_program_action_done (prg, args);
311 return MALA_STATEMENT;
325 --PP-QUOTED
326 literal_expansion 'foo' becomes --LITERAL foo, where '..' are the default of --QUOTED-EXPANSION-CHAR
327 backquote_expansion ``foo becomes `foo without literal expansion (escaping of literal expansion)
329 mala_state
330 mala_ppquoted_parser (MalaProgram prg)
332 TRACE (mala_module_std);
334 MALA_MUTATOR_BEGIN
337 MALA_MUTATOR_END;
339 mala_program_action_done (prg, 0);
340 return MALA_SUCCESS;
345 --PP-DQUOTED
346 literal_expansion "foo" becomes --LITERAL foo, where ".." are the default of --DQUOTED-EXPANSION-CHAR
347 backquote_expansion ``foo becomes `foo without literal expansion (escaping of literal expansion)
349 mala_state
350 mala_ppdquoted_parser (MalaProgram prg)
352 TRACE (mala_module_std);
354 MALA_MUTATOR_BEGIN
357 MALA_MUTATOR_END;
359 return MALA_STATEMENT;
364 --PP-NO
365 no_expansion --NO-foo or --no-foo becomes --NO --foo
367 mala_state
368 mala_ppno_parser (MalaProgram prg)
370 TRACE (mala_module_std);
372 MALA_MUTATOR_BEGIN
375 MALA_MUTATOR_END;
377 return MALA_STATEMENT;
382 --PP-ASSIGN
383 assign_expansion --foo=bar becomes --foo bar
385 mala_state
386 mala_ppassign_parser (MalaProgram prg)
388 TRACE (mala_module_std);
390 MALA_MUTATOR_BEGIN
393 MALA_MUTATOR_END;
395 return MALA_STATEMENT;
400 --PP-CHAR
401 char_expansion -abc+def123 becomes -a -b -c +d +e +f 123
403 mala_state
404 mala_ppchar_parser (MalaProgram prg)
406 TRACE (mala_module_std);
408 MALA_MUTATOR_BEGIN
411 MALA_MUTATOR_END;
413 return MALA_STATEMENT;
418 --PP-PLUS
419 plus_expansion +a becomes --NO -a
421 mala_state
422 mala_ppplus_parser (MalaProgram prg)
424 TRACE (mala_module_std);
426 MALA_MUTATOR_BEGIN
429 MALA_MUTATOR_END;
431 return MALA_STATEMENT;
436 --PP_UNDERSCORE
437 underscore_expansion --foo_bar becomes --foo-bar
439 mala_state
440 mala_ppunderscore_parser (MalaProgram prg)
442 TRACE (mala_module_std);
444 MALA_MUTATOR_BEGIN
447 MALA_MUTATOR_END;
449 return MALA_STATEMENT;
454 --PP-SECTION
455 bracket_expansion [foo bar] becomes --SECTION foo bar
457 mala_state
458 mala_ppsection_parser (MalaProgram prg)
460 TRACE (mala_module_std);
462 MALA_MUTATOR_BEGIN
465 MALA_MUTATOR_END;
467 return MALA_STATEMENT;
472 --PP-ASSIGN-CONCAT
473 assign_concat foo = bar becomes foo=bar for setenv_expansion
475 mala_state
476 mala_ppassignconcat_parser (MalaProgram prg)
478 TRACE (mala_module_std);
480 MALA_MUTATOR_BEGIN
483 MALA_MUTATOR_END;
485 return MALA_STATEMENT;
490 --PP-ENVSUBST
491 envvar_expansion foo$bar or foo${bar} becomes --ENVSUBST foo${bar}
493 wordexp()
495 mala_state
496 mala_ppenvsubst_parser (MalaProgram prg)
498 TRACE (mala_module_std);
500 MALA_MUTATOR_BEGIN
503 MALA_MUTATOR_END;
505 return MALA_STATEMENT;
510 --PP-SETENV
511 setenv_expansion foo=bar becomes --SETENV foo bar
513 mala_state
514 mala_ppsetenv_parser (MalaProgram prg)
516 TRACE (mala_module_std);
518 MALA_MUTATOR_BEGIN
521 MALA_MUTATOR_END;
523 return MALA_STATEMENT;
528 --PP-BRACE
529 brace_expansion { becomes --BEGIN and } becomes --END where { is the default value of --OPENING-BRACE and } is the default value of --CLOSING-BRACE
531 mala_state
532 mala_ppbrace_parser (MalaProgram prg)
534 TRACE (mala_module_std);
536 MALA_MUTATOR_BEGIN
539 MALA_MUTATOR_END;
541 return MALA_STATEMENT;
546 --PP-LIST
547 list_expansion foo,bar,baz becomes --BEGIN foo bar baz --END where , is the default value of --LIST-SEPARATOR
550 mala_state
551 mala_pplist_parser (MalaProgram prg)
553 TRACE (mala_module_std);
555 MALA_MUTATOR_BEGIN
558 MALA_MUTATOR_END;
560 return MALA_STATEMENT;
565 --PP-COMMAND
566 comand_expansion foo becomes --foo when --foo is a defined action
568 mala_state
569 mala_ppcommand_parser (MalaProgram prg)
571 TRACE (mala_module_std);
573 MALA_MUTATOR_BEGIN
576 MALA_MUTATOR_END;
578 return MALA_STATEMENT;
583 --PP-TOKENIZE
584 tokenizes a string with respect of quotes
586 mala_state
587 mala_pptokenize_parser (MalaProgram prg)
589 TRACE (mala_module_std);
591 MALA_MUTATOR_BEGIN
594 MALA_MUTATOR_END;
596 return MALA_STATEMENT;
601 --PP-DASHDASH
602 quits preprocessor on --
604 mala_state
605 mala_ppdashdash_parser (MalaProgram prg)
607 TRACE (mala_module_std);
608 //--PP-DASHDASH for '--' doesnt add --PP-MARK, returns MALA_SUCCESS (or something other which breaks preprocessing instantly)
609 MALA_MUTATOR_BEGIN
612 MALA_MUTATOR_END;
614 return MALA_STATEMENT;
620 mala_module_std_pp_init (MalaEngine self)
622 return mala_engine_actions_register (self, std_pp);
627 // Local Variables:
628 // mode: C
629 // c-file-style: "gnu"
630 // End: