Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison macro.c @ 18:c08a947d8f30
deal with macro parameters
author | David A. Holland |
---|---|
date | Mon, 20 Dec 2010 01:51:47 -0500 |
parents | 76da41da923f |
children | f9792a9ec704 |
comparison
equal
deleted
inserted
replaced
17:76da41da923f | 18:c08a947d8f30 |
---|---|
9 struct macro { | 9 struct macro { |
10 struct place defplace; | 10 struct place defplace; |
11 struct place expansionplace; | 11 struct place expansionplace; |
12 unsigned hash; | 12 unsigned hash; |
13 char *name; | 13 char *name; |
14 bool hasparams; | |
15 struct stringarray params; | |
14 char *expansion; | 16 char *expansion; |
15 }; | 17 }; |
16 DECLARRAY(macro); | 18 DECLARRAY(macro); |
17 DEFARRAY(macro, ); | 19 DEFARRAY(macro, ); |
18 DECLARRAY(macroarray); | 20 DECLARRAY(macroarray); |
25 //////////////////////////////////////////////////////////// | 27 //////////////////////////////////////////////////////////// |
26 // macro structure ops | 28 // macro structure ops |
27 | 29 |
28 static | 30 static |
29 struct macro * | 31 struct macro * |
30 macro_create(struct place *p1, struct place *p2, unsigned hash, | 32 macro_create(struct place *p1, const char *name, unsigned hash, |
31 const char *name, const char *expansion) | 33 struct place *p2, const char *expansion) |
32 { | 34 { |
33 struct macro *m; | 35 struct macro *m; |
34 | 36 |
35 m = domalloc(sizeof(*m)); | 37 m = domalloc(sizeof(*m)); |
36 m->defplace = *p1; | 38 m->defplace = *p1; |
37 m->expansionplace = *p2; | 39 m->expansionplace = *p2; |
38 m->hash = hash; | 40 m->hash = hash; |
39 m->name = dostrdup(name); | 41 m->name = dostrdup(name); |
42 m->hasparams = false; | |
43 stringarray_init(&m->params); | |
40 m->expansion = dostrdup(expansion); | 44 m->expansion = dostrdup(expansion); |
41 return m; | 45 return m; |
42 } | 46 } |
43 | 47 |
44 static | 48 static |
46 macro_destroy(struct macro *m) | 50 macro_destroy(struct macro *m) |
47 { | 51 { |
48 free(m->name); | 52 free(m->name); |
49 free(m->expansion); | 53 free(m->expansion); |
50 free(m); | 54 free(m); |
55 } | |
56 | |
57 static | |
58 bool | |
59 macro_eq(const struct macro *m1, const struct macro *m2) | |
60 { | |
61 unsigned num1, num2, i; | |
62 const char *p1, *p2; | |
63 | |
64 if (strcmp(m1->name, m2->name) != 0) { | |
65 return false; | |
66 } | |
67 | |
68 if (m1->hasparams != m2->hasparams) { | |
69 return false; | |
70 } | |
71 | |
72 if (strcmp(m1->expansion, m2->expansion) != 0) { | |
73 return false; | |
74 } | |
75 | |
76 num1 = stringarray_num(&m1->params); | |
77 num2 = stringarray_num(&m2->params); | |
78 if (num1 != num2) { | |
79 return false; | |
80 } | |
81 | |
82 for (i=0; i<num1; i++) { | |
83 p1 = stringarray_get(&m1->params, i); | |
84 p2 = stringarray_get(&m2->params, i); | |
85 if (strcmp(p1, p2) != 0) { | |
86 return false; | |
87 } | |
88 } | |
89 return true; | |
51 } | 90 } |
52 | 91 |
53 //////////////////////////////////////////////////////////// | 92 //////////////////////////////////////////////////////////// |
54 // macro table | 93 // macro table |
55 | 94 |
236 } | 275 } |
237 | 276 |
238 //////////////////////////////////////////////////////////// | 277 //////////////////////////////////////////////////////////// |
239 // external macro definition interface | 278 // external macro definition interface |
240 | 279 |
241 void | 280 static |
242 macro_define(struct place *p1, const char *macro, | 281 struct macro * |
243 struct place *p2, const char *expansion) | 282 macro_define_common_start(struct place *p1, const char *macro, |
244 { | 283 struct place *p2, const char *expansion) |
245 struct macro *m; | 284 { |
246 | 285 struct macro *m; |
247 m = macrotable_find(macro, false); | 286 |
248 if (m != NULL) { | 287 if (!is_identifier(macro)) { |
249 if (!strcmp(expansion, m->expansion)) { | 288 complain(p1, "Invalid macro name %s", macro); |
250 complain(p1, "Warning: redefinition of %s", macro); | 289 complain_fail(); |
290 } | |
291 | |
292 m = macro_create(p1, macro, hashfunc(macro), p2, expansion); | |
293 return m; | |
294 } | |
295 | |
296 static | |
297 void | |
298 macro_define_common_end(struct macro *m) | |
299 { | |
300 struct macro *oldm; | |
301 bool ok; | |
302 | |
303 oldm = macrotable_find(m->name, false); | |
304 if (oldm != NULL) { | |
305 ok = macro_eq(m, oldm); | |
306 if (ok) { | |
307 complain(&m->defplace, | |
308 "Warning: redefinition of %s", m->name); | |
251 if (mode.werror) { | 309 if (mode.werror) { |
252 complain_fail(); | 310 complain_fail(); |
253 } | 311 } |
254 return; | 312 } else { |
255 } | 313 complain(&m->defplace, |
256 complain(p1, "Redefinition of %s is not identical", macro); | 314 "Redefinition of %s is not identical", |
257 complain_fail(); | 315 m->name); |
316 complain_fail(); | |
317 } | |
318 complain(&oldm->defplace, "Previous definition was here"); | |
319 macro_destroy(m); | |
258 return; | 320 return; |
259 } | 321 } |
260 | |
261 m = macro_create(p1, p2, hashfunc(macro), macro, expansion); | |
262 macrotable_add(m); | 322 macrotable_add(m); |
323 } | |
324 | |
325 static | |
326 void | |
327 macro_parse_parameters(struct macro *m, struct place *p, const char *params) | |
328 { | |
329 size_t len; | |
330 const char *s; | |
331 char *param; | |
332 | |
333 while (params != NULL) { | |
334 len = strspn(params, ws); | |
335 params += len; | |
336 p->column += len; | |
337 s = strchr(params, ','); | |
338 if (s) { | |
339 len = s-params; | |
340 param = dostrndup(params, len); | |
341 s++; | |
342 } else { | |
343 len = strlen(params); | |
344 param = dostrndup(params, len); | |
345 } | |
346 notrailingws(param, strlen(param)); | |
347 if (!is_identifier(param)) { | |
348 complain(p, "Invalid macro parameter name %s", param); | |
349 complain_fail(); | |
350 } else { | |
351 stringarray_add(&m->params, param, NULL); | |
352 } | |
353 params = s; | |
354 p->column += len; | |
355 } | |
356 } | |
357 | |
358 void | |
359 macro_define_plain(struct place *p1, const char *macro, | |
360 struct place *p2, const char *expansion) | |
361 { | |
362 struct macro *m; | |
363 | |
364 m = macro_define_common_start(p1, macro, p2, expansion); | |
365 macro_define_common_end(m); | |
366 } | |
367 | |
368 void | |
369 macro_define_params(struct place *p1, const char *macro, | |
370 struct place *p2, const char *params, | |
371 struct place *p3, const char *expansion) | |
372 { | |
373 struct macro *m; | |
374 | |
375 m = macro_define_common_start(p1, macro, p3, expansion); | |
376 macro_parse_parameters(m, p2, params); | |
377 macro_define_common_end(m); | |
263 } | 378 } |
264 | 379 |
265 void | 380 void |
266 macro_undef(const char *macro) | 381 macro_undef(const char *macro) |
267 { | 382 { |