ppy.y 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*
  2. * Wrc preprocessor syntax analysis
  3. *
  4. * Copyright 1999-2000 Bertho A. Stultiens (BS)
  5. *
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  20. *
  21. * History:
  22. * 24-Apr-2000 BS Restructured the lot to fit the new scanner
  23. * and reintegrate into the wine-tree.
  24. * 01-Jan-2000 BS FIXME: win16 preprocessor calculates with
  25. * 16 bit ints and overflows...?
  26. * 26-Dec-1999 BS Started this file
  27. *
  28. */
  29. %{
  30. #include "config.h"
  31. #include "wine/port.h"
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <stdarg.h>
  35. #include <assert.h>
  36. #include <ctype.h>
  37. #include <string.h>
  38. #include "wpp_private.h"
  39. #define UNARY_OP(r, v, OP) \
  40. switch(v.type) \
  41. { \
  42. case cv_sint: r.val.si = OP v.val.si; break; \
  43. case cv_uint: r.val.ui = OP v.val.ui; break; \
  44. case cv_slong: r.val.sl = OP v.val.sl; break; \
  45. case cv_ulong: r.val.ul = OP v.val.ul; break; \
  46. case cv_sll: r.val.sll = OP v.val.sll; break; \
  47. case cv_ull: r.val.ull = OP v.val.ull; break; \
  48. }
  49. #define cv_signed(v) ((v.type & FLAG_SIGNED) != 0)
  50. #define BIN_OP_INT(r, v1, v2, OP) \
  51. r.type = v1.type; \
  52. if(cv_signed(v1) && cv_signed(v2)) \
  53. r.val.si = v1.val.si OP v2.val.si; \
  54. else if(cv_signed(v1) && !cv_signed(v2)) \
  55. r.val.si = v1.val.si OP (signed) v2.val.ui; \
  56. else if(!cv_signed(v1) && cv_signed(v2)) \
  57. r.val.si = (signed) v1.val.ui OP v2.val.si; \
  58. else \
  59. r.val.ui = v1.val.ui OP v2.val.ui;
  60. #define BIN_OP_LONG(r, v1, v2, OP) \
  61. r.type = v1.type; \
  62. if(cv_signed(v1) && cv_signed(v2)) \
  63. r.val.sl = v1.val.sl OP v2.val.sl; \
  64. else if(cv_signed(v1) && !cv_signed(v2)) \
  65. r.val.sl = v1.val.sl OP (signed long) v2.val.ul; \
  66. else if(!cv_signed(v1) && cv_signed(v2)) \
  67. r.val.sl = (signed long) v1.val.ul OP v2.val.sl; \
  68. else \
  69. r.val.ul = v1.val.ul OP v2.val.ul;
  70. #define BIN_OP_LONGLONG(r, v1, v2, OP) \
  71. r.type = v1.type; \
  72. if(cv_signed(v1) && cv_signed(v2)) \
  73. r.val.sll = v1.val.sll OP v2.val.sll; \
  74. else if(cv_signed(v1) && !cv_signed(v2)) \
  75. r.val.sll = v1.val.sll OP (__int64) v2.val.ull; \
  76. else if(!cv_signed(v1) && cv_signed(v2)) \
  77. r.val.sll = (__int64) v1.val.ull OP v2.val.sll; \
  78. else \
  79. r.val.ull = v1.val.ull OP v2.val.ull;
  80. #define BIN_OP(r, v1, v2, OP) \
  81. switch(v1.type & SIZE_MASK) \
  82. { \
  83. case SIZE_INT: BIN_OP_INT(r, v1, v2, OP); break; \
  84. case SIZE_LONG: BIN_OP_LONG(r, v1, v2, OP); break; \
  85. case SIZE_LONGLONG: BIN_OP_LONGLONG(r, v1, v2, OP); break; \
  86. default: pp_internal_error(__FILE__, __LINE__, "Invalid type indicator (0x%04x)", v1.type); \
  87. }
  88. /*
  89. * Prototypes
  90. */
  91. static int boolean(cval_t *v);
  92. static void promote_equal_size(cval_t *v1, cval_t *v2);
  93. static void cast_to_sint(cval_t *v);
  94. static void cast_to_uint(cval_t *v);
  95. static void cast_to_slong(cval_t *v);
  96. static void cast_to_ulong(cval_t *v);
  97. static void cast_to_sll(cval_t *v);
  98. static void cast_to_ull(cval_t *v);
  99. static marg_t *new_marg(char *str, def_arg_t type);
  100. static marg_t *add_new_marg(char *str, def_arg_t type);
  101. static int marg_index(char *id);
  102. static mtext_t *new_mtext(char *str, int idx, def_exp_t type);
  103. static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp);
  104. static char *merge_text(char *s1, char *s2);
  105. /*
  106. * Local variables
  107. */
  108. static marg_t **macro_args; /* Macro parameters array while parsing */
  109. static int nmacro_args;
  110. %}
  111. %union{
  112. int sint;
  113. unsigned int uint;
  114. long slong;
  115. unsigned long ulong;
  116. __int64 sll;
  117. unsigned __int64 ull;
  118. int *iptr;
  119. char *cptr;
  120. cval_t cval;
  121. marg_t *marg;
  122. mtext_t *mtext;
  123. }
  124. %token tRCINCLUDE
  125. %token tIF tIFDEF tIFNDEF tELSE tELIF tENDIF tDEFINED tNL
  126. %token tINCLUDE tLINE tGCCLINE tERROR tWARNING tPRAGMA tPPIDENT
  127. %token tUNDEF tMACROEND tCONCAT tELIPSIS tSTRINGIZE
  128. %token <cptr> tIDENT tLITERAL tMACRO tDEFINE
  129. %token <cptr> tDQSTRING tSQSTRING tIQSTRING
  130. %token <uint> tUINT
  131. %token <sint> tSINT
  132. %token <ulong> tULONG
  133. %token <slong> tSLONG
  134. %token <ull> tULONGLONG
  135. %token <sll> tSLONGLONG
  136. %token <cptr> tRCINCLUDEPATH
  137. %right '?' ':'
  138. %left tLOGOR
  139. %left tLOGAND
  140. %left '|'
  141. %left '^'
  142. %left '&'
  143. %left tEQ tNE
  144. %left '<' tLTE '>' tGTE
  145. %left tLSHIFT tRSHIFT
  146. %left '+' '-'
  147. %left '*' '/'
  148. %right '~' '!'
  149. %type <cval> pp_expr
  150. %type <marg> emargs margs
  151. %type <mtext> opt_mtexts mtexts mtext
  152. %type <sint> allmargs
  153. %type <cptr> opt_text text
  154. /*
  155. **************************************************************************
  156. * The parser starts here
  157. **************************************************************************
  158. */
  159. %%
  160. pp_file : /* Empty */
  161. | pp_file preprocessor
  162. ;
  163. preprocessor
  164. : tINCLUDE tDQSTRING tNL { pp_do_include($2, 1); }
  165. | tINCLUDE tIQSTRING tNL { pp_do_include($2, 0); }
  166. | tIF pp_expr tNL { pp_next_if_state(boolean(&$2)); }
  167. | tIFDEF tIDENT tNL { pp_next_if_state(pplookup($2) != NULL); free($2); }
  168. | tIFNDEF tIDENT tNL {
  169. int t = pplookup($2) == NULL;
  170. if(pp_incl_state.state == 0 && t && !pp_incl_state.seen_junk)
  171. {
  172. pp_incl_state.state = 1;
  173. pp_incl_state.ppp = $2;
  174. pp_incl_state.ifdepth = pp_get_if_depth();
  175. }
  176. else if(pp_incl_state.state != 1)
  177. {
  178. pp_incl_state.state = -1;
  179. free($2);
  180. }
  181. else
  182. free($2);
  183. pp_next_if_state(t);
  184. if(pp_status.debug)
  185. fprintf(stderr, "tIFNDEF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
  186. pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
  187. }
  188. | tELIF pp_expr tNL {
  189. pp_if_state_t s = pp_pop_if();
  190. switch(s)
  191. {
  192. case if_true:
  193. case if_elif:
  194. pp_push_if(if_elif);
  195. break;
  196. case if_false:
  197. pp_push_if(boolean(&$2) ? if_true : if_false);
  198. break;
  199. case if_ignore:
  200. pp_push_if(if_ignore);
  201. break;
  202. case if_elsetrue:
  203. case if_elsefalse:
  204. ppy_error("#elif cannot follow #else");
  205. break;
  206. case if_error:
  207. break;
  208. default:
  209. pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #elif directive", s);
  210. }
  211. }
  212. | tELSE tNL {
  213. pp_if_state_t s = pp_pop_if();
  214. switch(s)
  215. {
  216. case if_true:
  217. pp_push_if(if_elsefalse);
  218. break;
  219. case if_elif:
  220. pp_push_if(if_elif);
  221. break;
  222. case if_false:
  223. pp_push_if(if_elsetrue);
  224. break;
  225. case if_ignore:
  226. pp_push_if(if_ignore);
  227. break;
  228. case if_elsetrue:
  229. case if_elsefalse:
  230. ppy_error("#else clause already defined");
  231. break;
  232. case if_error:
  233. break;
  234. default:
  235. pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #else directive", s);
  236. }
  237. }
  238. | tENDIF tNL {
  239. if(pp_pop_if() != if_error)
  240. {
  241. if(pp_incl_state.ifdepth == pp_get_if_depth() && pp_incl_state.state == 1)
  242. {
  243. pp_incl_state.state = 2;
  244. pp_incl_state.seen_junk = 0;
  245. }
  246. else if(pp_incl_state.state != 1)
  247. {
  248. pp_incl_state.state = -1;
  249. }
  250. if(pp_status.debug)
  251. fprintf(stderr, "tENDIF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
  252. pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
  253. }
  254. }
  255. | tUNDEF tIDENT tNL { pp_del_define($2); free($2); }
  256. | tDEFINE opt_text tNL { pp_add_define($1, $2); free($1); free($2); }
  257. | tMACRO res_arg allmargs tMACROEND opt_mtexts tNL {
  258. pp_add_macro($1, macro_args, nmacro_args, $5);
  259. }
  260. | tLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
  261. | tGCCLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
  262. | tGCCLINE tSINT tDQSTRING tSINT tNL
  263. { if($3) pp_writestring("# %d %s %d\n", $2, $3, $4); free($3); }
  264. | tGCCLINE tSINT tDQSTRING tSINT tSINT tNL
  265. { if($3) pp_writestring("# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
  266. | tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tNL
  267. { if($3) pp_writestring("# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
  268. | tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tSINT tNL
  269. { if($3) pp_writestring("# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
  270. | tGCCLINE tNL /* The null-token */
  271. | tERROR opt_text tNL { ppy_error("#error directive: '%s'", $2); free($2); }
  272. | tWARNING opt_text tNL { ppy_warning("#warning directive: '%s'", $2); free($2); }
  273. | tPRAGMA opt_text tNL { pp_writestring("#pragma %s\n", $2 ? $2 : ""); free($2); }
  274. | tPPIDENT opt_text tNL { if(pp_status.pedantic) ppy_warning("#ident ignored (arg: '%s')", $2); free($2); }
  275. | tRCINCLUDE tRCINCLUDEPATH {
  276. if($2)
  277. {
  278. int nl=strlen($2) +3;
  279. char *fn=pp_xmalloc(nl);
  280. if(fn)
  281. {
  282. sprintf(fn,"\"%s\"",$2);
  283. pp_do_include(fn,1);
  284. }
  285. free($2);
  286. }
  287. }
  288. | tRCINCLUDE tDQSTRING {
  289. pp_do_include($2,1);
  290. }
  291. /*| tNL*/
  292. ;
  293. opt_text: /* Empty */ { $$ = NULL; }
  294. | text { $$ = $1; }
  295. ;
  296. text : tLITERAL { $$ = $1; }
  297. | tDQSTRING { $$ = $1; }
  298. | tSQSTRING { $$ = $1; }
  299. | text tLITERAL { $$ = merge_text($1, $2); }
  300. | text tDQSTRING { $$ = merge_text($1, $2); }
  301. | text tSQSTRING { $$ = merge_text($1, $2); }
  302. ;
  303. res_arg : /* Empty */ { macro_args = NULL; nmacro_args = 0; }
  304. ;
  305. allmargs: /* Empty */ { $$ = 0; macro_args = NULL; nmacro_args = 0; }
  306. | emargs { $$ = nmacro_args; }
  307. ;
  308. emargs : margs { $$ = $1; }
  309. | margs ',' tELIPSIS { $$ = add_new_marg(NULL, arg_list); nmacro_args *= -1; }
  310. ;
  311. margs : margs ',' tIDENT { $$ = add_new_marg($3, arg_single); }
  312. | tIDENT { $$ = add_new_marg($1, arg_single); }
  313. ;
  314. opt_mtexts
  315. : /* Empty */ { $$ = NULL; }
  316. | mtexts {
  317. for($$ = $1; $$ && $$->prev; $$ = $$->prev)
  318. ;
  319. }
  320. ;
  321. mtexts : mtext { $$ = $1; }
  322. | mtexts mtext { $$ = combine_mtext($1, $2); }
  323. ;
  324. mtext : tLITERAL { $$ = new_mtext($1, 0, exp_text); }
  325. | tDQSTRING { $$ = new_mtext($1, 0, exp_text); }
  326. | tSQSTRING { $$ = new_mtext($1, 0, exp_text); }
  327. | tCONCAT { $$ = new_mtext(NULL, 0, exp_concat); }
  328. | tSTRINGIZE tIDENT {
  329. int mat = marg_index($2);
  330. if(mat < 0)
  331. ppy_error("Stringification identifier must be an argument parameter");
  332. else
  333. $$ = new_mtext(NULL, mat, exp_stringize);
  334. }
  335. | tIDENT {
  336. int mat = marg_index($1);
  337. if(mat >= 0)
  338. $$ = new_mtext(NULL, mat, exp_subst);
  339. else if($1)
  340. $$ = new_mtext($1, 0, exp_text);
  341. }
  342. ;
  343. pp_expr : tSINT { $$.type = cv_sint; $$.val.si = $1; }
  344. | tUINT { $$.type = cv_uint; $$.val.ui = $1; }
  345. | tSLONG { $$.type = cv_slong; $$.val.sl = $1; }
  346. | tULONG { $$.type = cv_ulong; $$.val.ul = $1; }
  347. | tSLONGLONG { $$.type = cv_sll; $$.val.sll = $1; }
  348. | tULONGLONG { $$.type = cv_ull; $$.val.ull = $1; }
  349. | tDEFINED tIDENT { $$.type = cv_sint; $$.val.si = pplookup($2) != NULL; }
  350. | tDEFINED '(' tIDENT ')' { $$.type = cv_sint; $$.val.si = pplookup($3) != NULL; }
  351. | tIDENT { $$.type = cv_sint; $$.val.si = 0; }
  352. | pp_expr tLOGOR pp_expr { $$.type = cv_sint; $$.val.si = boolean(&$1) || boolean(&$3); }
  353. | pp_expr tLOGAND pp_expr { $$.type = cv_sint; $$.val.si = boolean(&$1) && boolean(&$3); }
  354. | pp_expr tEQ pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, ==); }
  355. | pp_expr tNE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, !=); }
  356. | pp_expr '<' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <); }
  357. | pp_expr '>' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >); }
  358. | pp_expr tLTE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <=); }
  359. | pp_expr tGTE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >=); }
  360. | pp_expr '+' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, +); }
  361. | pp_expr '-' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, -); }
  362. | pp_expr '^' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, ^); }
  363. | pp_expr '&' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, &); }
  364. | pp_expr '|' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, |); }
  365. | pp_expr '*' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, *); }
  366. | pp_expr '/' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, /); }
  367. | pp_expr tLSHIFT pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <<); }
  368. | pp_expr tRSHIFT pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >>); }
  369. | '+' pp_expr { $$ = $2; }
  370. | '-' pp_expr { UNARY_OP($$, $2, -); }
  371. | '~' pp_expr { UNARY_OP($$, $2, ~); }
  372. | '!' pp_expr { $$.type = cv_sint; $$.val.si = !boolean(&$2); }
  373. | '(' pp_expr ')' { $$ = $2; }
  374. | pp_expr '?' pp_expr ':' pp_expr { $$ = boolean(&$1) ? $3 : $5; }
  375. ;
  376. %%
  377. /*
  378. **************************************************************************
  379. * Support functions
  380. **************************************************************************
  381. */
  382. static void cast_to_sint(cval_t *v)
  383. {
  384. switch(v->type)
  385. {
  386. case cv_sint: break;
  387. case cv_uint: break;
  388. case cv_slong: v->val.si = v->val.sl; break;
  389. case cv_ulong: v->val.si = v->val.ul; break;
  390. case cv_sll: v->val.si = v->val.sll; break;
  391. case cv_ull: v->val.si = v->val.ull; break;
  392. }
  393. v->type = cv_sint;
  394. }
  395. static void cast_to_uint(cval_t *v)
  396. {
  397. switch(v->type)
  398. {
  399. case cv_sint: break;
  400. case cv_uint: break;
  401. case cv_slong: v->val.ui = v->val.sl; break;
  402. case cv_ulong: v->val.ui = v->val.ul; break;
  403. case cv_sll: v->val.ui = v->val.sll; break;
  404. case cv_ull: v->val.ui = v->val.ull; break;
  405. }
  406. v->type = cv_uint;
  407. }
  408. static void cast_to_slong(cval_t *v)
  409. {
  410. switch(v->type)
  411. {
  412. case cv_sint: v->val.sl = v->val.si; break;
  413. case cv_uint: v->val.sl = v->val.ui; break;
  414. case cv_slong: break;
  415. case cv_ulong: break;
  416. case cv_sll: v->val.sl = v->val.sll; break;
  417. case cv_ull: v->val.sl = v->val.ull; break;
  418. }
  419. v->type = cv_slong;
  420. }
  421. static void cast_to_ulong(cval_t *v)
  422. {
  423. switch(v->type)
  424. {
  425. case cv_sint: v->val.ul = v->val.si; break;
  426. case cv_uint: v->val.ul = v->val.ui; break;
  427. case cv_slong: break;
  428. case cv_ulong: break;
  429. case cv_sll: v->val.ul = v->val.sll; break;
  430. case cv_ull: v->val.ul = v->val.ull; break;
  431. }
  432. v->type = cv_ulong;
  433. }
  434. static void cast_to_sll(cval_t *v)
  435. {
  436. switch(v->type)
  437. {
  438. case cv_sint: v->val.sll = v->val.si; break;
  439. case cv_uint: v->val.sll = v->val.ui; break;
  440. case cv_slong: v->val.sll = v->val.sl; break;
  441. case cv_ulong: v->val.sll = v->val.ul; break;
  442. case cv_sll: break;
  443. case cv_ull: break;
  444. }
  445. v->type = cv_sll;
  446. }
  447. static void cast_to_ull(cval_t *v)
  448. {
  449. switch(v->type)
  450. {
  451. case cv_sint: v->val.ull = v->val.si; break;
  452. case cv_uint: v->val.ull = v->val.ui; break;
  453. case cv_slong: v->val.ull = v->val.sl; break;
  454. case cv_ulong: v->val.ull = v->val.ul; break;
  455. case cv_sll: break;
  456. case cv_ull: break;
  457. }
  458. v->type = cv_ull;
  459. }
  460. static void promote_equal_size(cval_t *v1, cval_t *v2)
  461. {
  462. #define cv_sizeof(v) ((int)(v->type & SIZE_MASK))
  463. int s1 = cv_sizeof(v1);
  464. int s2 = cv_sizeof(v2);
  465. #undef cv_sizeof
  466. if(s1 == s2)
  467. return;
  468. else if(s1 > s2)
  469. {
  470. switch(v1->type)
  471. {
  472. case cv_sint: cast_to_sint(v2); break;
  473. case cv_uint: cast_to_uint(v2); break;
  474. case cv_slong: cast_to_slong(v2); break;
  475. case cv_ulong: cast_to_ulong(v2); break;
  476. case cv_sll: cast_to_sll(v2); break;
  477. case cv_ull: cast_to_ull(v2); break;
  478. }
  479. }
  480. else
  481. {
  482. switch(v2->type)
  483. {
  484. case cv_sint: cast_to_sint(v1); break;
  485. case cv_uint: cast_to_uint(v1); break;
  486. case cv_slong: cast_to_slong(v1); break;
  487. case cv_ulong: cast_to_ulong(v1); break;
  488. case cv_sll: cast_to_sll(v1); break;
  489. case cv_ull: cast_to_ull(v1); break;
  490. }
  491. }
  492. }
  493. static int boolean(cval_t *v)
  494. {
  495. switch(v->type)
  496. {
  497. case cv_sint: return v->val.si != 0;
  498. case cv_uint: return v->val.ui != 0;
  499. case cv_slong: return v->val.sl != 0;
  500. case cv_ulong: return v->val.ul != 0;
  501. case cv_sll: return v->val.sll != 0;
  502. case cv_ull: return v->val.ull != 0;
  503. }
  504. return 0;
  505. }
  506. static marg_t *new_marg(char *str, def_arg_t type)
  507. {
  508. marg_t *ma = pp_xmalloc(sizeof(marg_t));
  509. if(!ma)
  510. return NULL;
  511. ma->arg = str;
  512. ma->type = type;
  513. ma->nnl = 0;
  514. return ma;
  515. }
  516. static marg_t *add_new_marg(char *str, def_arg_t type)
  517. {
  518. marg_t **new_macro_args;
  519. marg_t *ma;
  520. if(!str)
  521. return NULL;
  522. new_macro_args = pp_xrealloc(macro_args, (nmacro_args+1) * sizeof(macro_args[0]));
  523. if(!new_macro_args)
  524. return NULL;
  525. macro_args = new_macro_args;
  526. ma = new_marg(str, type);
  527. if(!ma)
  528. return NULL;
  529. macro_args[nmacro_args] = ma;
  530. nmacro_args++;
  531. return ma;
  532. }
  533. static int marg_index(char *id)
  534. {
  535. int t;
  536. if(!id)
  537. return -1;
  538. for(t = 0; t < nmacro_args; t++)
  539. {
  540. if(!strcmp(id, macro_args[t]->arg))
  541. break;
  542. }
  543. return t < nmacro_args ? t : -1;
  544. }
  545. static mtext_t *new_mtext(char *str, int idx, def_exp_t type)
  546. {
  547. mtext_t *mt = pp_xmalloc(sizeof(mtext_t));
  548. if(!mt)
  549. return NULL;
  550. if(str == NULL)
  551. mt->subst.argidx = idx;
  552. else
  553. mt->subst.text = str;
  554. mt->type = type;
  555. mt->next = mt->prev = NULL;
  556. return mt;
  557. }
  558. static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp)
  559. {
  560. if(!tail)
  561. return mtp;
  562. if(!mtp)
  563. return tail;
  564. if(tail->type == exp_text && mtp->type == exp_text)
  565. {
  566. char *new_text;
  567. new_text = pp_xrealloc(tail->subst.text, strlen(tail->subst.text)+strlen(mtp->subst.text)+1);
  568. if(!new_text)
  569. return mtp;
  570. tail->subst.text = new_text;
  571. strcat(tail->subst.text, mtp->subst.text);
  572. free(mtp->subst.text);
  573. free(mtp);
  574. return tail;
  575. }
  576. if(tail->type == exp_concat && mtp->type == exp_concat)
  577. {
  578. free(mtp);
  579. return tail;
  580. }
  581. if(tail->type == exp_concat && mtp->type == exp_text)
  582. {
  583. int len = strlen(mtp->subst.text);
  584. while(len)
  585. {
  586. /* FIXME: should delete space from head of string */
  587. if(isspace(mtp->subst.text[len-1] & 0xff))
  588. mtp->subst.text[--len] = '\0';
  589. else
  590. break;
  591. }
  592. if(!len)
  593. {
  594. free(mtp->subst.text);
  595. free(mtp);
  596. return tail;
  597. }
  598. }
  599. if(tail->type == exp_text && mtp->type == exp_concat)
  600. {
  601. int len = strlen(tail->subst.text);
  602. while(len)
  603. {
  604. if(isspace(tail->subst.text[len-1] & 0xff))
  605. tail->subst.text[--len] = '\0';
  606. else
  607. break;
  608. }
  609. if(!len)
  610. {
  611. mtp->prev = tail->prev;
  612. mtp->next = tail->next;
  613. if(tail->prev)
  614. tail->prev->next = mtp;
  615. free(tail->subst.text);
  616. free(tail);
  617. return mtp;
  618. }
  619. }
  620. tail->next = mtp;
  621. mtp->prev = tail;
  622. return mtp;
  623. }
  624. static char *merge_text(char *s1, char *s2)
  625. {
  626. int l1;
  627. int l2;
  628. char *snew;
  629. if(!s1)
  630. return s2;
  631. if(!s2)
  632. return s1;
  633. l1 = strlen(s1);
  634. l2 = strlen(s2);
  635. snew = pp_xrealloc(s1, l1+l2+1);
  636. if(!snew)
  637. {
  638. free(s2);
  639. return s1;
  640. }
  641. s1 = snew;
  642. memcpy(s1+l1, s2, l2+1);
  643. free(s2);
  644. return s1;
  645. }