1 /*
2 This file is part of adms - http://sourceforge.net/projects/mot-adms.
3
4 adms is a code generator for the Verilog-AMS language.
5
6 Copyright (C) 2002-2012 Laurent Lemaitre <r29173@users.sourceforge.net>
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /*
23 * RCS Info
24 * $Id: preprocessorMain.c 1154 2008-11-04 10:25:43Z r29173 $
25 *
26 * Log
27 * $Log$
28 * Revision 1.12 2005/06/17 16:44:25 r29173
29 * debug memory allocation with valgrind
30 *
31 * Revision 1.11 2005/06/16 07:12:45 r29173
32 * debug memory allocation with valgrind
33 *
34 * Revision 1.10 2005/05/09 14:38:30 r29173
35 * cleaned-up source directory structure
36 *
37 * Revision 1.9 2005/05/03 09:35:15 r29173
38 * cleaned-up header file dependencies
39 *
40 * Revision 1.8 2005/05/03 07:58:21 r29173
41 * moved admsNS into admsFile
42 *
43 * Revision 1.7 2004/11/19 12:29:56 r29173
44 * renamed _C into CAT
45 * saved argc, argv into admsmain element
46 * added adms:setenv transform
47 *
48 * Revision 1.6 2004/11/01 09:37:37 r29173
49 * changed messaging macros (avoid useless computation of arguments)
50 * improved the coding of transforms in xmlProgram.c
51 *
52 * Revision 1.5 2004/10/20 15:33:52 r29173
53 * tons of changes
54 * 1- introduced element whileloop (marat)
55 * 2- reshaped the handling of the messaging system
56 * 3- fixed bug in admsCheck/Makefile.am
57 * 4- started implementation of implicit adms transforms
58 *
59 * Revision 1.4 2004/08/19 16:45:47 r29173
60 * cleaned-up i/o file handling
61 *
62 * Revision 1.3 2004/08/03 12:33:55 r29173
63 * import adms-1.21.0 from local CVS
64 *
65 * Revision 1.3 2004/07/09 14:39:11 r29173
66 * removed data structure ns
67 *
68 * Revision 1.2 2004/05/26 13:02:48 r29173
69 * added default values to all enumerations
70 *
71 * Revision 1.1.1.1 2004/05/21 12:20:01 r29173
72 * recreated cvs data structure (crashed after revision 1.13.0!)
73 *
74 * Revision 1.14 2004/03/08 13:58:06 r29173
75 * all code lower-cased
76 *
77 * Revision 1.13 2004/02/13 14:28:39 r29173
78 * started implementing code builder in yacc parser
79 *
80 * Revision 1.12 2004/02/06 09:06:03 r29173
81 * started implementing code builder in yacc parser
82 *
83 * Revision 1.11 2004/01/21 14:35:47 r29173
84 * started implementing code builder in yacc parser
85 *
86 * Revision 1.10 2004/01/09 16:23:47 r29173
87 * cleaned-up use of #include
88 *
89 * Revision 1.9 2004/01/08 10:28:50 r29173
90 * moved code to always.[ch]
91 *
92 * Revision 1.8 2004/01/06 12:35:29 r29173
93 * fixed the use of globals: input file and output file
94 *
95 * Revision 1.7 2003/12/12 15:08:35 r29173
96 * changed construct (a==NULL) to (!a)
97 *
98 * Revision 1.6 2003/12/12 14:43:38 r29173
99 * changed construct (a==NULL) to (!a)
100 *
101 * Revision 1.5 2003/12/12 14:33:26 r29173
102 * changed construct (a!=NULL) into (a) or (a)?1:0
103 *
104 * Revision 1.4 2003/12/11 20:14:07 r29173
105 * cleaned-up after compilation with CFLAG+=-Wall
106 *
107 * Revision 1.3 2003/12/11 16:01:53 r29173
108 * changed prefix [epst]_adms_ to [epst]_
109 *
110 * Revision 1.2 2003/05/21 14:18:01 r29173
111 * add rcs info
112 *
113 */
114
115 #include "admsPreprocessor.h"
116
117 #define strdup_before_ptr(s,sptr,offset) adms_knclone(s+offset,sptr-s-offset)
118 #define strdup_after_ptr(s,sptr,offset) adms_knclone(sptr+offset,strlen(s)-(sptr-s)-offset)
119
120 extern int adms_preprocessor_leng;
121 static p_preprocessor_main adms_preprocessor_main;
adms_preprocessor_valueto_main(p_preprocessor_main myadms_preprocessor_main)122 void adms_preprocessor_valueto_main (p_preprocessor_main myadms_preprocessor_main)
123 {
124 adms_preprocessor_main=myadms_preprocessor_main;
125 }
pproot()126 p_preprocessor_main pproot ()
127 {
128 return adms_preprocessor_main;
129 }
adms_preprocessor_get_define_from_argv(const int argc,const char ** argv)130 void adms_preprocessor_get_define_from_argv (const int argc,const char** argv)
131 {
132 int i;
133 for (i=1; i<argc; i++)
134 {
135 char *value=strdup(argv[i]);
136 char *defineName = NULL;
137 char *defineValue = NULL;
138 if ( (strlen(value)>2) && ((value[0])=='-') && ((value[1])=='D') )
139 {
140 char *equal = NULL;
141 char *arg = strdup_after_ptr (value,value+2,0);
142 char *argPtr = arg;
143 while (*argPtr && (!equal))
144 {
145 if (*argPtr=='=')
146 equal= argPtr;
147 argPtr++;
148 }
149 if (*arg == '=')
150 adms_message_verbose(("at command line argument, bad syntax ... '%s'\n",value))
151 else if (equal == last_char (arg))
152 defineName = strdup_before_ptr (arg,equal,0);
153 else if (!equal)
154 defineName = strdup(arg);
155 else
156 {
157 defineName = strdup_before_ptr (arg,equal,0);
158 defineValue = strdup_after_ptr (arg,equal,1);
159 }
160 if (defineName)
161 {
162 if (defineValue)
163 adms_preprocessor_define_add_default_with_text (defineName, defineValue);
164 else
165 adms_preprocessor_define_add_default (defineName);
166 }
167 free(arg);
168 }
169 if (defineName)
170 adms_message_verbose(("set pragma ... '%s'\n",defineName))
171 free(value);
172 }
173 }
adms_preprocessor_add_message(char * message)174 int adms_preprocessor_add_message ( char *message)
175 {
176 adms_message_info((message))
177 return 0;
178 }
adms_preprocessor_new_text_as_string(char * name)179 p_preprocessor_text adms_preprocessor_new_text_as_string(char *name)
180 {
181 p_preprocessor_text text=(p_preprocessor_text)malloc(sizeof(t_preprocessor_text));
182 text->_str = name;
183 text->_isarg = 0;
184 return text;
185 }
adms_preprocessor_pragma_substitute_text(p_preprocessor_substitutor substitutor)186 static int adms_preprocessor_pragma_substitute_text (p_preprocessor_substitutor substitutor)
187 {
188 if (adms_preprocessor_pragma_define_is_def (substitutor->_pragma))
189 {
190 p_preprocessor_text space = adms_preprocessor_new_text_as_string(" ");
191 p_slist l; for(l=substitutor->_pragma->text;l;l=l->next)
192 {
193 p_preprocessor_text text=(p_preprocessor_text)(l->data);
194 p_slist arg=adms_slist_copy(substitutor->_pragma->arg);
195 adms_slist_inreverse(&arg);
196 substitutor->_cr_text=text;
197 substitutor->_cr_newarg=adms_slist_copy(substitutor->_newarg);
198 adms_slist_inreverse(&substitutor->_cr_newarg);
199 if (text->_isarg==1)
200 {
201 p_slist ll; for(ll=arg;ll;ll=ll->next)
202 {
203 char* arg=(char*)ll->data;
204 if(!strcmp(substitutor->_cr_text->_str,arg))
205 {
206 if(substitutor->_cr_newarg)
207 {
208 p_slist newarg=adms_slist_copy((p_slist)(substitutor->_cr_newarg->data));
209 adms_slist_inreverse(&newarg);
210 adms_slist_concat(&newarg,substitutor->_newtext);
211 substitutor->_newtext=newarg;
212 }
213 else
214 adms_slist_push(&(substitutor->_newtext),(p_adms)substitutor->_cr_text);
215 }
216 substitutor->_cr_newarg = substitutor->_cr_newarg->next;
217 }
218 }
219 else
220 {
221 p_preprocessor_text newtext = adms_preprocessor_new_text_as_string(text->_str);
222 newtext->_isarg = -1;
223 adms_slist_push(&(substitutor->_newtext),(p_adms)newtext);
224 }
225 adms_slist_free(arg);
226 adms_slist_free(substitutor->_cr_newarg);
227 }
228 adms_slist_push(&(substitutor->_newtext),(p_adms)space);
229 }
230 else
231 {
232 p_preprocessor_text name = adms_preprocessor_new_text_as_string(substitutor->_pragma->name);
233 adms_slist_push(&(substitutor->_newtext),(p_adms)name);
234 }
235 return 0;
236 }
adms_preprocessor_new_text_as_substitutor(p_preprocessor_pragma_define define,p_slist newarg)237 p_slist adms_preprocessor_new_text_as_substitutor (p_preprocessor_pragma_define define, p_slist newarg)
238 {
239 p_preprocessor_substitutor substitutor=(p_preprocessor_substitutor)malloc(sizeof(t_preprocessor_substitutor));
240 substitutor->_newtext=NULL;
241 substitutor->_cr_text=NULL;
242 substitutor->_cr_newarg=NULL;
243 substitutor->_pragma = define;
244 substitutor->_newarg = newarg;
245 adms_preprocessor_pragma_substitute_text(substitutor);
246 adms_slist_inreverse(&substitutor->_newtext);
247 return substitutor->_newtext;
248 }
adms_preprocessor_pragma_define_has_arg(p_preprocessor_pragma_define pragma)249 int adms_preprocessor_pragma_define_has_arg (p_preprocessor_pragma_define pragma)
250 {
251 return (pragma->hasArg==1);
252 }
adms_preprocessor_pragma_define_is_def(p_preprocessor_pragma_define pragma)253 int adms_preprocessor_pragma_define_is_def (p_preprocessor_pragma_define pragma)
254 {
255 return (pragma->isDefined==1);
256 }
adms_preprocessor_identifier_is_def(char * name)257 int adms_preprocessor_identifier_is_def (char * name)
258 {
259 int test;
260 p_preprocessor_pragma_define pragma;
261 if(
262 (pragma = adms_preprocessor_pragma_define_exists (name))
263 &&
264 adms_preprocessor_pragma_define_is_def(pragma)
265 )
266 test = ( pragma->isDefined == 1 );
267 else
268 test = 0;
269 return test;
270 }
adms_preprocessor_identifer_set_undef(char * name)271 p_preprocessor_pragma_define adms_preprocessor_identifer_set_undef (char * name)
272 {
273 p_preprocessor_pragma_define pragma = adms_preprocessor_pragma_define_exists (name);
274 if(!pragma)
275 pragma = adms_preprocessor_define_add (name);
276 pragma->isDefined = 0;
277 return pragma;
278 }
adms_preprocessor_identifier_is_ndef(char * name)279 int adms_preprocessor_identifier_is_ndef (char * name)
280 {
281 return (!adms_preprocessor_identifier_is_def (name) );
282 }
adms_preprocessor_pragma_define_is_ndef(p_preprocessor_pragma_define pragma)283 int adms_preprocessor_pragma_define_is_ndef (p_preprocessor_pragma_define pragma)
284 {
285 return (!adms_preprocessor_pragma_define_is_def(pragma));
286 }
adms_preprocessor_pragma_define_has_noarg(p_preprocessor_pragma_define pragma)287 int adms_preprocessor_pragma_define_has_noarg (p_preprocessor_pragma_define pragma)
288 {
289 return (!adms_preprocessor_pragma_define_has_arg(pragma));
290 }
adms_preprocessor_pragma_define_has_nullarg(p_preprocessor_pragma_define pragma)291 int adms_preprocessor_pragma_define_has_nullarg (p_preprocessor_pragma_define pragma)
292 {
293 return adms_preprocessor_pragma_define_has_arg(pragma) && (adms_slist_length( pragma->arg )==0);
294 }
adms_preprocessor_pragma_define_has_text(p_preprocessor_pragma_define pragma)295 int adms_preprocessor_pragma_define_has_text (p_preprocessor_pragma_define pragma)
296 {
297 return ((pragma->text)?1:0);
298 }
adms_preprocessor_pragma_define_has_notext(p_preprocessor_pragma_define pragma)299 int adms_preprocessor_pragma_define_has_notext (p_preprocessor_pragma_define pragma)
300 {
301 return (!adms_preprocessor_pragma_define_has_text(pragma));
302 }
adms_preprocessor_pragma_define_has_noarg_and_notext(p_preprocessor_pragma_define pragma)303 int adms_preprocessor_pragma_define_has_noarg_and_notext (p_preprocessor_pragma_define pragma)
304 {
305 int test;
306 test = adms_preprocessor_pragma_define_has_noarg(pragma)
307 &&
308 adms_preprocessor_pragma_define_has_notext(pragma)
309 ;
310 return test;
311 }
adms_preprocessor_pragma_define_has_noarg_and_text(p_preprocessor_pragma_define pragma)312 int adms_preprocessor_pragma_define_has_noarg_and_text (p_preprocessor_pragma_define pragma)
313 {
314 int test;
315 test = adms_preprocessor_pragma_define_has_noarg(pragma)
316 &&
317 adms_preprocessor_pragma_define_has_text(pragma)
318 ;
319 return test;
320 }
adms_preprocessor_pragma_define_has_nullarg_and_notext(p_preprocessor_pragma_define pragma)321 int adms_preprocessor_pragma_define_has_nullarg_and_notext (p_preprocessor_pragma_define pragma)
322 {
323 int test;
324 test = adms_preprocessor_pragma_define_has_nullarg(pragma)
325 &&
326 adms_preprocessor_pragma_define_has_notext(pragma)
327 ;
328 return test;
329 }
adms_preprocessor_pragma_define_has_nullarg_and_text(p_preprocessor_pragma_define pragma)330 int adms_preprocessor_pragma_define_has_nullarg_and_text (p_preprocessor_pragma_define pragma)
331 {
332 int test;
333 test = adms_preprocessor_pragma_define_has_nullarg(pragma)
334 &&
335 adms_preprocessor_pragma_define_has_text(pragma)
336 ;
337 return test;
338 }
adms_preprocessor_pragma_define_has_arg_and_notext(p_preprocessor_pragma_define pragma)339 int adms_preprocessor_pragma_define_has_arg_and_notext (p_preprocessor_pragma_define pragma)
340 {
341 int test;
342 test = adms_preprocessor_pragma_define_has_arg(pragma)
343 &&
344 adms_preprocessor_pragma_define_has_notext(pragma)
345 ;
346 return test;
347 }
adms_preprocessor_pragma_define_has_arg_and_text(p_preprocessor_pragma_define pragma)348 int adms_preprocessor_pragma_define_has_arg_and_text (p_preprocessor_pragma_define pragma)
349 {
350 int test;
351 test = adms_preprocessor_pragma_define_has_arg(pragma)
352 &&
353 adms_preprocessor_pragma_define_has_text(pragma)
354 ;
355 return test;
356 }
adms_preprocessor_identifier_is_pragma_cb(p_preprocessor_pragma_define pragma,char * identifier)357 static int adms_preprocessor_identifier_is_pragma_cb (p_preprocessor_pragma_define pragma, char * identifier)
358 {
359 return (!!strcmp(pragma->name,identifier));
360 }
361 typedef int (*Binary) (const void* d1,const void* d2);
adms_slist_find_custom(p_slist l,const void * data,Binary func)362 static p_slist adms_slist_find_custom (p_slist l,const void* data,Binary func)
363 {
364 while(l)
365 {
366 if(!func(l->data,data))
367 return l;
368 l=l->next;
369 }
370 return ((void *)0);
371 }
adms_preprocessor_pragma_define_exists(char * name)372 p_preprocessor_pragma_define adms_preprocessor_pragma_define_exists (char * name)
373 {
374 p_slist Data;
375 p_preprocessor_pragma_define pragma;
376 if((Data=adms_slist_find_custom ( pproot()->Defined,name,(Binary)adms_preprocessor_identifier_is_pragma_cb)))
377 pragma=(p_preprocessor_pragma_define) Data->data;
378 else
379 pragma=NULL;
380 return pragma;
381 }
adms_preprocessor_define_add(char * name)382 p_preprocessor_pragma_define adms_preprocessor_define_add (char * name)
383 {
384 p_preprocessor_pragma_define pragma;
385 if ((pragma = adms_preprocessor_pragma_define_exists(name)))
386 {
387 if( pragma->isDefined == 1 )
388 adms_message_warning(("pragma redefined ... '%s'\n",name))
389 pragma->hasArg = 0;
390 pragma->arg = NULL;
391 pragma->text = NULL;
392 }
393 else
394 {
395 pragma=(p_preprocessor_pragma_define)malloc(sizeof(t_preprocessor_pragma_define));
396 pragma->hasArg = 0;
397 pragma->arg=NULL;
398 pragma->text=NULL;
399 pragma->name = name;
400 adms_slist_push(&(pproot()->Defined),(p_adms)pragma);
401 }
402 pragma->isDefined = 1;
403 return pragma;
404 }
adms_preprocessor_define_add_default(char * name)405 int adms_preprocessor_define_add_default (char * name)
406 {
407 p_preprocessor_pragma_define pragma;
408 pragma = adms_preprocessor_define_add (name);
409 adms_message_verbose(("define macro ... '%s'\n",name))
410 assert(adms_preprocessor_pragma_define_has_noarg_and_notext(pragma));
411 return 0;
412 }
adms_preprocessor_define_add_default_with_text(char * name,char * value)413 int adms_preprocessor_define_add_default_with_text (char * name, char * value)
414 {
415 p_slist Text;
416 p_preprocessor_text text;
417 p_preprocessor_pragma_define pragma;
418 text = adms_preprocessor_new_text_as_string(value);
419 Text = adms_slist_new((p_adms)text);
420 pragma = adms_preprocessor_define_add_with_text (name, Text);
421 adms_message_verbose(("define macro with value ... '%s=%s'\n",name, value))
422 assert(adms_preprocessor_pragma_define_has_noarg_and_text(pragma));
423 return 0;
424 }
adms_preprocessor_undefine_add(char * name)425 p_preprocessor_pragma_define adms_preprocessor_undefine_add (char * name)
426 {
427 p_preprocessor_pragma_define pragma;
428 pragma = adms_preprocessor_pragma_define_exists(name);
429 if(!pragma)
430 {
431 pragma=(p_preprocessor_pragma_define)malloc(sizeof(t_preprocessor_pragma_define));
432 pragma->arg=NULL;
433 pragma->text=NULL;
434 pragma->name = name;
435 adms_slist_push(&(pproot()->Defined),(p_adms)pragma);
436 }
437 pragma->isDefined = 0;
438 return pragma;
439 }
adms_preprocessor_define_add_with_arg(char * name,p_slist arg)440 p_preprocessor_pragma_define adms_preprocessor_define_add_with_arg (char * name, p_slist arg)
441 {
442 p_preprocessor_pragma_define pragma;
443 pragma = adms_preprocessor_define_add (name );
444 pragma->hasArg = 1;
445 pragma->arg = arg;
446 pragma->text = NULL;
447 return pragma;
448 }
adms_preprocessor_define_add_with_text(char * name,p_slist text)449 p_preprocessor_pragma_define adms_preprocessor_define_add_with_text (char * name, p_slist text)
450 {
451 p_preprocessor_pragma_define pragma;
452 pragma = adms_preprocessor_define_add (name );
453 pragma->hasArg = 0;
454 pragma->arg = NULL;
455 pragma->text = text;
456 return pragma;
457 }
adms_preprocessor_define_add_with_arg_and_text(char * name,p_slist arg,p_slist text)458 p_preprocessor_pragma_define adms_preprocessor_define_add_with_arg_and_text (char * name, p_slist arg, p_slist text)
459 {
460 p_preprocessor_pragma_define pragma;
461 p_slist l;
462 pragma = adms_preprocessor_define_add_with_arg (name, arg );
463 pragma->text = text;
464 for(l=pragma->text;l;l=l->next)
465 {
466 p_preprocessor_text text=(p_preprocessor_text)(l->data);
467 p_slist ll; for(ll=pragma->arg;ll;ll=ll->next)
468 {
469 if((text->_isarg != -1) && !strcmp(text->_str,(char*)(ll->data)))
470 text->_isarg = 1;
471 }
472 }
473 return pragma;
474 }
adms_preprocessor_get_line_position_cb(p_slist l,int mycharpos)475 static p_continuator adms_preprocessor_get_line_position_cb (p_slist l,int mycharpos)
476 {
477 while(l)
478 {
479 p_continuator mycontinuator=(p_continuator)(l->data);
480 if(mycharpos<=mycontinuator->char_position)
481 return mycontinuator;
482 l=l->next;
483 }
484 return NULL;
485 }
adms_preprocessor_get_line_position(p_preprocessor cr_preprocessor,int char_pos)486 int adms_preprocessor_get_line_position (p_preprocessor cr_preprocessor, int char_pos)
487 {
488 int line_pos=cr_preprocessor->cur_line_position;
489 p_continuator mycontinuator;
490 p_slist Reversed=adms_slist_reverse(cr_preprocessor->cur_continuator_position);
491 if((mycontinuator=adms_preprocessor_get_line_position_cb(Reversed,char_pos)))
492 line_pos=mycontinuator->line_position;
493 cr_preprocessor->cur_continuator_position = adms_slist_reverse(Reversed );
494 return line_pos;
495 }
496