ppy.y 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  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 char *add_new_marg(char *str);
  100. static int marg_index(char *id);
  101. static mtext_t *new_mtext(char *str, int idx, def_exp_t type);
  102. static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp);
  103. static char *merge_text(char *s1, char *s2);
  104. /*
  105. * Local variables
  106. */
  107. static char **macro_args; /* Macro parameters array while parsing */
  108. static int nmacro_args;
  109. %}
  110. %union{
  111. int sint;
  112. unsigned int uint;
  113. long slong;
  114. unsigned long ulong;
  115. __int64 sll;
  116. unsigned __int64 ull;
  117. int *iptr;
  118. char *cptr;
  119. cval_t cval;
  120. char *marg;
  121. mtext_t *mtext;
  122. }
  123. %token tRCINCLUDE
  124. %token tIF tIFDEF tIFNDEF tELSE tELIF tENDIF tDEFINED tNL
  125. %token tINCLUDE tLINE tGCCLINE tERROR tWARNING tPRAGMA tPPIDENT
  126. %token tUNDEF tMACROEND tCONCAT tELLIPSIS tSTRINGIZE
  127. %token <cptr> tIDENT tLITERAL tMACRO tDEFINE
  128. %token <cptr> tDQSTRING tSQSTRING tIQSTRING
  129. %token <uint> tUINT
  130. %token <sint> tSINT
  131. %token <ulong> tULONG
  132. %token <slong> tSLONG
  133. %token <ull> tULONGLONG
  134. %token <sll> tSLONGLONG
  135. %token <cptr> tRCINCLUDEPATH
  136. %right '?' ':'
  137. %left tLOGOR
  138. %left tLOGAND
  139. %left '|'
  140. %left '^'
  141. %left '&'
  142. %left tEQ tNE
  143. %left '<' tLTE '>' tGTE
  144. %left tLSHIFT tRSHIFT
  145. %left '+' '-'
  146. %left '*' '/'
  147. %right '~' '!'
  148. %type <cval> pp_expr
  149. %type <marg> emargs margs
  150. %type <mtext> opt_mtexts mtexts mtext
  151. %type <sint> allmargs
  152. %type <cptr> opt_text text
  153. /*
  154. **************************************************************************
  155. * The parser starts here
  156. **************************************************************************
  157. */
  158. %%
  159. pp_file : /* Empty */
  160. | pp_file preprocessor
  161. ;
  162. preprocessor
  163. : tINCLUDE tDQSTRING tNL { pp_do_include($2, 1); }
  164. | tINCLUDE tIQSTRING tNL { pp_do_include($2, 0); }
  165. | tIF pp_expr tNL { pp_next_if_state(boolean(&$2)); }
  166. | tIFDEF tIDENT tNL { pp_next_if_state(pplookup($2) != NULL); free($2); }
  167. | tIFNDEF tIDENT tNL {
  168. int t = pplookup($2) == NULL;
  169. if(pp_incl_state.state == 0 && t && !pp_incl_state.seen_junk)
  170. {
  171. pp_incl_state.state = 1;
  172. pp_incl_state.ppp = $2;
  173. pp_incl_state.ifdepth = pp_get_if_depth();
  174. }
  175. else if(pp_incl_state.state != 1)
  176. {
  177. pp_incl_state.state = -1;
  178. free($2);
  179. }
  180. else
  181. free($2);
  182. pp_next_if_state(t);
  183. if(pp_status.debug)
  184. fprintf(stderr, "tIFNDEF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
  185. pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
  186. }
  187. | tELIF pp_expr tNL {
  188. pp_if_state_t s = pp_pop_if();
  189. switch(s)
  190. {
  191. case if_true:
  192. case if_elif:
  193. pp_push_if(if_elif);
  194. break;
  195. case if_false:
  196. pp_push_if(boolean(&$2) ? if_true : if_false);
  197. break;
  198. case if_ignore:
  199. pp_push_if(if_ignore);
  200. break;
  201. case if_elsetrue:
  202. case if_elsefalse:
  203. ppy_error("#elif cannot follow #else");
  204. break;
  205. case if_error:
  206. break;
  207. default:
  208. pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #elif directive", s);
  209. }
  210. }
  211. | tELSE tNL {
  212. pp_if_state_t s = pp_pop_if();
  213. switch(s)
  214. {
  215. case if_true:
  216. pp_push_if(if_elsefalse);
  217. break;
  218. case if_elif:
  219. pp_push_if(if_elif);
  220. break;
  221. case if_false:
  222. pp_push_if(if_elsetrue);
  223. break;
  224. case if_ignore:
  225. pp_push_if(if_ignore);
  226. break;
  227. case if_elsetrue:
  228. case if_elsefalse:
  229. ppy_error("#else clause already defined");
  230. break;
  231. case if_error:
  232. break;
  233. default:
  234. pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #else directive", s);
  235. }
  236. }
  237. | tENDIF tNL {
  238. if(pp_pop_if() != if_error)
  239. {
  240. if(pp_incl_state.ifdepth == pp_get_if_depth() && pp_incl_state.state == 1)
  241. {
  242. pp_incl_state.state = 2;
  243. pp_incl_state.seen_junk = 0;
  244. }
  245. else if(pp_incl_state.state != 1)
  246. {
  247. pp_incl_state.state = -1;
  248. }
  249. if(pp_status.debug)
  250. fprintf(stderr, "tENDIF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
  251. pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
  252. }
  253. }
  254. | tUNDEF tIDENT tNL { pp_del_define($2); free($2); }
  255. | tDEFINE opt_text tNL { pp_add_define($1, $2); free($1); free($2); }
  256. | tMACRO res_arg allmargs tMACROEND opt_mtexts tNL {
  257. pp_add_macro($1, macro_args, nmacro_args, $5);
  258. }
  259. | tLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
  260. | tGCCLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
  261. | tGCCLINE tSINT tDQSTRING tSINT tNL
  262. { if($3) pp_writestring("# %d %s %d\n", $2, $3, $4); free($3); }
  263. | tGCCLINE tSINT tDQSTRING tSINT tSINT tNL
  264. { if($3) pp_writestring("# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
  265. | tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tNL
  266. { if($3) pp_writestring("# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
  267. | tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tSINT tNL
  268. { if($3) pp_writestring("# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
  269. | tGCCLINE tNL /* The null-token */
  270. | tERROR opt_text tNL { ppy_error("#error directive: '%s'", $2); free($2); }
  271. | tWARNING opt_text tNL { ppy_warning("#warning directive: '%s'", $2); free($2); }
  272. | tPRAGMA opt_text tNL { pp_writestring("#pragma %s\n", $2 ? $2 : ""); free($2); }
  273. | tPPIDENT opt_text tNL { if(pp_status.pedantic) ppy_warning("#ident ignored (arg: '%s')", $2); free($2); }
  274. | tRCINCLUDE tRCINCLUDEPATH {
  275. int nl=strlen($2) +3;
  276. char *fn=pp_xmalloc(nl);
  277. sprintf(fn,"\"%s\"",$2);
  278. pp_do_include(fn,1);
  279. free($2);
  280. }
  281. | tRCINCLUDE tDQSTRING {
  282. pp_do_include($2,1);
  283. }
  284. /*| tNL*/
  285. ;
  286. opt_text: /* Empty */ { $$ = NULL; }
  287. | text { $$ = $1; }
  288. ;
  289. text : tLITERAL { $$ = $1; }
  290. | tDQSTRING { $$ = $1; }
  291. | tSQSTRING { $$ = $1; }
  292. | text tLITERAL { $$ = merge_text($1, $2); }
  293. | text tDQSTRING { $$ = merge_text($1, $2); }
  294. | text tSQSTRING { $$ = merge_text($1, $2); }
  295. ;
  296. res_arg : /* Empty */ { macro_args = NULL; nmacro_args = 0; }
  297. ;
  298. allmargs: /* Empty */ { $$ = 0; macro_args = NULL; nmacro_args = 0; }
  299. | emargs { $$ = nmacro_args; }
  300. ;
  301. emargs : margs { $$ = $1; }
  302. | margs ',' tELLIPSIS { nmacro_args *= -1; }
  303. ;
  304. margs : margs ',' tIDENT { $$ = add_new_marg($3); }
  305. | tIDENT { $$ = add_new_marg($1); }
  306. ;
  307. opt_mtexts
  308. : /* Empty */ { $$ = NULL; }
  309. | mtexts {
  310. for($$ = $1; $$ && $$->prev; $$ = $$->prev)
  311. ;
  312. }
  313. ;
  314. mtexts : mtext { $$ = $1; }
  315. | mtexts mtext { $$ = combine_mtext($1, $2); }
  316. ;
  317. mtext : tLITERAL { $$ = new_mtext($1, 0, exp_text); }
  318. | tDQSTRING { $$ = new_mtext($1, 0, exp_text); }
  319. | tSQSTRING { $$ = new_mtext($1, 0, exp_text); }
  320. | tCONCAT { $$ = new_mtext(NULL, 0, exp_concat); }
  321. | tSTRINGIZE tIDENT {
  322. int mat = marg_index($2);
  323. if(mat < 0)
  324. ppy_error("Stringification identifier must be an argument parameter");
  325. else
  326. $$ = new_mtext(NULL, mat, exp_stringize);
  327. }
  328. | tIDENT {
  329. int mat = marg_index($1);
  330. if(mat >= 0)
  331. $$ = new_mtext(NULL, mat, exp_subst);
  332. else if($1)
  333. $$ = new_mtext($1, 0, exp_text);
  334. }
  335. ;
  336. pp_expr : tSINT { $$.type = cv_sint; $$.val.si = $1; }
  337. | tUINT { $$.type = cv_uint; $$.val.ui = $1; }
  338. | tSLONG { $$.type = cv_slong; $$.val.sl = $1; }
  339. | tULONG { $$.type = cv_ulong; $$.val.ul = $1; }
  340. | tSLONGLONG { $$.type = cv_sll; $$.val.sll = $1; }
  341. | tULONGLONG { $$.type = cv_ull; $$.val.ull = $1; }
  342. | tDEFINED tIDENT { $$.type = cv_sint; $$.val.si = pplookup($2) != NULL; }
  343. | tDEFINED '(' tIDENT ')' { $$.type = cv_sint; $$.val.si = pplookup($3) != NULL; }
  344. | tIDENT { $$.type = cv_sint; $$.val.si = 0; }
  345. | pp_expr tLOGOR pp_expr { $$.type = cv_sint; $$.val.si = boolean(&$1) || boolean(&$3); }
  346. | pp_expr tLOGAND pp_expr { $$.type = cv_sint; $$.val.si = boolean(&$1) && boolean(&$3); }
  347. | pp_expr tEQ pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, ==); }
  348. | pp_expr tNE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, !=); }
  349. | pp_expr '<' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <); }
  350. | pp_expr '>' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >); }
  351. | pp_expr tLTE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <=); }
  352. | pp_expr tGTE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >=); }
  353. | pp_expr '+' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, +); }
  354. | pp_expr '-' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, -); }
  355. | pp_expr '^' 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 '*' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, *); }
  359. | pp_expr '/' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, /); }
  360. | pp_expr tLSHIFT pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <<); }
  361. | pp_expr tRSHIFT pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >>); }
  362. | '+' pp_expr { $$ = $2; }
  363. | '-' pp_expr { UNARY_OP($$, $2, -); }
  364. | '~' pp_expr { UNARY_OP($$, $2, ~); }
  365. | '!' pp_expr { $$.type = cv_sint; $$.val.si = !boolean(&$2); }
  366. | '(' pp_expr ')' { $$ = $2; }
  367. | pp_expr '?' pp_expr ':' pp_expr { $$ = boolean(&$1) ? $3 : $5; }
  368. ;
  369. %%
  370. /*
  371. **************************************************************************
  372. * Support functions
  373. **************************************************************************
  374. */
  375. static void cast_to_sint(cval_t *v)
  376. {
  377. switch(v->type)
  378. {
  379. case cv_sint: break;
  380. case cv_uint: break;
  381. case cv_slong: v->val.si = v->val.sl; break;
  382. case cv_ulong: v->val.si = v->val.ul; break;
  383. case cv_sll: v->val.si = v->val.sll; break;
  384. case cv_ull: v->val.si = v->val.ull; break;
  385. }
  386. v->type = cv_sint;
  387. }
  388. static void cast_to_uint(cval_t *v)
  389. {
  390. switch(v->type)
  391. {
  392. case cv_sint: break;
  393. case cv_uint: break;
  394. case cv_slong: v->val.ui = v->val.sl; break;
  395. case cv_ulong: v->val.ui = v->val.ul; break;
  396. case cv_sll: v->val.ui = v->val.sll; break;
  397. case cv_ull: v->val.ui = v->val.ull; break;
  398. }
  399. v->type = cv_uint;
  400. }
  401. static void cast_to_slong(cval_t *v)
  402. {
  403. switch(v->type)
  404. {
  405. case cv_sint: v->val.sl = v->val.si; break;
  406. case cv_uint: v->val.sl = v->val.ui; break;
  407. case cv_slong: break;
  408. case cv_ulong: break;
  409. case cv_sll: v->val.sl = v->val.sll; break;
  410. case cv_ull: v->val.sl = v->val.ull; break;
  411. }
  412. v->type = cv_slong;
  413. }
  414. static void cast_to_ulong(cval_t *v)
  415. {
  416. switch(v->type)
  417. {
  418. case cv_sint: v->val.ul = v->val.si; break;
  419. case cv_uint: v->val.ul = v->val.ui; break;
  420. case cv_slong: break;
  421. case cv_ulong: break;
  422. case cv_sll: v->val.ul = v->val.sll; break;
  423. case cv_ull: v->val.ul = v->val.ull; break;
  424. }
  425. v->type = cv_ulong;
  426. }
  427. static void cast_to_sll(cval_t *v)
  428. {
  429. switch(v->type)
  430. {
  431. case cv_sint: v->val.sll = v->val.si; break;
  432. case cv_uint: v->val.sll = v->val.ui; break;
  433. case cv_slong: v->val.sll = v->val.sl; break;
  434. case cv_ulong: v->val.sll = v->val.ul; break;
  435. case cv_sll: break;
  436. case cv_ull: break;
  437. }
  438. v->type = cv_sll;
  439. }
  440. static void cast_to_ull(cval_t *v)
  441. {
  442. switch(v->type)
  443. {
  444. case cv_sint: v->val.ull = v->val.si; break;
  445. case cv_uint: v->val.ull = v->val.ui; break;
  446. case cv_slong: v->val.ull = v->val.sl; break;
  447. case cv_ulong: v->val.ull = v->val.ul; break;
  448. case cv_sll: break;
  449. case cv_ull: break;
  450. }
  451. v->type = cv_ull;
  452. }
  453. static void promote_equal_size(cval_t *v1, cval_t *v2)
  454. {
  455. #define cv_sizeof(v) ((int)(v->type & SIZE_MASK))
  456. int s1 = cv_sizeof(v1);
  457. int s2 = cv_sizeof(v2);
  458. #undef cv_sizeof
  459. if(s1 == s2)
  460. return;
  461. else if(s1 > s2)
  462. {
  463. switch(v1->type)
  464. {
  465. case cv_sint: cast_to_sint(v2); break;
  466. case cv_uint: cast_to_uint(v2); break;
  467. case cv_slong: cast_to_slong(v2); break;
  468. case cv_ulong: cast_to_ulong(v2); break;
  469. case cv_sll: cast_to_sll(v2); break;
  470. case cv_ull: cast_to_ull(v2); break;
  471. }
  472. }
  473. else
  474. {
  475. switch(v2->type)
  476. {
  477. case cv_sint: cast_to_sint(v1); break;
  478. case cv_uint: cast_to_uint(v1); break;
  479. case cv_slong: cast_to_slong(v1); break;
  480. case cv_ulong: cast_to_ulong(v1); break;
  481. case cv_sll: cast_to_sll(v1); break;
  482. case cv_ull: cast_to_ull(v1); break;
  483. }
  484. }
  485. }
  486. static int boolean(cval_t *v)
  487. {
  488. switch(v->type)
  489. {
  490. case cv_sint: return v->val.si != 0;
  491. case cv_uint: return v->val.ui != 0;
  492. case cv_slong: return v->val.sl != 0;
  493. case cv_ulong: return v->val.ul != 0;
  494. case cv_sll: return v->val.sll != 0;
  495. case cv_ull: return v->val.ull != 0;
  496. }
  497. return 0;
  498. }
  499. static char *add_new_marg(char *str)
  500. {
  501. char *ma;
  502. macro_args = pp_xrealloc(macro_args, (nmacro_args+1) * sizeof(macro_args[0]));
  503. macro_args[nmacro_args++] = ma = pp_xstrdup(str);
  504. return ma;
  505. }
  506. static int marg_index(char *id)
  507. {
  508. int t;
  509. if(!id)
  510. return -1;
  511. for(t = 0; t < nmacro_args; t++)
  512. {
  513. if(!strcmp(id, macro_args[t]))
  514. break;
  515. }
  516. return t < nmacro_args ? t : -1;
  517. }
  518. static mtext_t *new_mtext(char *str, int idx, def_exp_t type)
  519. {
  520. mtext_t *mt = pp_xmalloc(sizeof(mtext_t));
  521. if(str == NULL)
  522. mt->subst.argidx = idx;
  523. else
  524. mt->subst.text = str;
  525. mt->type = type;
  526. mt->next = mt->prev = NULL;
  527. return mt;
  528. }
  529. static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp)
  530. {
  531. if(!tail)
  532. return mtp;
  533. if(!mtp)
  534. return tail;
  535. if(tail->type == exp_text && mtp->type == exp_text)
  536. {
  537. tail->subst.text = pp_xrealloc(tail->subst.text, strlen(tail->subst.text)+strlen(mtp->subst.text)+1);
  538. strcat(tail->subst.text, mtp->subst.text);
  539. free(mtp->subst.text);
  540. free(mtp);
  541. return tail;
  542. }
  543. if(tail->type == exp_concat && mtp->type == exp_concat)
  544. {
  545. free(mtp);
  546. return tail;
  547. }
  548. if(tail->type == exp_concat && mtp->type == exp_text)
  549. {
  550. int len = strlen(mtp->subst.text);
  551. while(len)
  552. {
  553. /* FIXME: should delete space from head of string */
  554. if(isspace(mtp->subst.text[len-1] & 0xff))
  555. mtp->subst.text[--len] = '\0';
  556. else
  557. break;
  558. }
  559. if(!len)
  560. {
  561. free(mtp->subst.text);
  562. free(mtp);
  563. return tail;
  564. }
  565. }
  566. if(tail->type == exp_text && mtp->type == exp_concat)
  567. {
  568. int len = strlen(tail->subst.text);
  569. while(len)
  570. {
  571. if(isspace(tail->subst.text[len-1] & 0xff))
  572. tail->subst.text[--len] = '\0';
  573. else
  574. break;
  575. }
  576. if(!len)
  577. {
  578. mtp->prev = tail->prev;
  579. mtp->next = tail->next;
  580. if(tail->prev)
  581. tail->prev->next = mtp;
  582. free(tail->subst.text);
  583. free(tail);
  584. return mtp;
  585. }
  586. }
  587. tail->next = mtp;
  588. mtp->prev = tail;
  589. return mtp;
  590. }
  591. static char *merge_text(char *s1, char *s2)
  592. {
  593. int l1 = strlen(s1);
  594. int l2 = strlen(s2);
  595. s1 = pp_xrealloc(s1, l1+l2+1);
  596. memcpy(s1+l1, s2, l2+1);
  597. free(s2);
  598. return s1;
  599. }