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