merge the formfield patch from ooo-build
[ooovba.git] / soltools / HIDCompiler / hidclex.l
blob700a044555c2f8cf373272a6b697eb25ff0ab3f4
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  * 
5  * Copyright 2008 by Sun Microsystems, Inc.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * $RCSfile: hidclex.l,v $
10  * $Revision: 1.9 $
11  *
12  * This file is part of OpenOffice.org.
13  *
14  * OpenOffice.org is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License version 3
16  * only, as published by the Free Software Foundation.
17  *
18  * OpenOffice.org is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU Lesser General Public License version 3 for more details
22  * (a copy is included in the LICENSE file that accompanied this code).
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * version 3 along with OpenOffice.org.  If not, see
26  * <http://www.openoffice.org/license.html>
27  * for a copy of the LGPLv3 License.
28  *
29  ************************************************************************/
31 // Suppress any warnings from generated code:
32 #if defined __GNUC__
33 #pragma GCC system_header
34 #elif defined __SUNPRO_CC
35 #pragma disable_warn
36 #elif defined _MSC_VER
37 #pragma warning(push, 1)
38 #endif
40 static char const Revision[]     = "$Revision: 1.9 $" ;
44 XX  XX     XXXX   XXXXXX
45 XX  XX      XX     XX  XX
46 XX  XX      XX     XX  XX
47 XXXXXX      XX     XX  XX
48 XX  XX      XX     XX  XX
49 XX  XX      XX     XX  XX
50 XX  XX     XXXX   XXXXXX
53   XXXX                                 XX      XXX
54  XX  XX                                         XX
55 XX         XXXX   XXX XX   XX XXX     XXX       XX     XXXXX   XX XXX
56 XX        XX  XX  XX X XX   XX  XX     XX       XX    XX    X   XXX XX
57 XX    X   XX  XX  XX X XX   XX  XX     XX       XX    XXXXXXX   XX
58  XX  XX   XX  XX  XX   XX   XXXXX      XX       XX    XX        XX
59   XXXX     XXXX   XXX  XXX  XX        XXXX     XXXX    XXXXX   XXXX
60                            XXXX
65 /* length of buffer for reading with lex */
66 /**/
67 /* enlarge token buffer to tokenize whole strings */
68 #undef YYLMAX
69 #define YYLMAX 64000
71 int exclude_bracelevel=0; /* count braces in that start state */
72 static YY_BUFFER_STATE InputFiles[127];         // for recursive parse
73 static int nInputFileDepth = 0;
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <string.h>
80 #include <ctype.h>
82 int alloc_cnt = 0;
83 static bool bVerbose = false;
84 void freestring( char const * ); //forward
86 char* dot2underline( char* str )
88         size_t len=strlen(str);
89         for( size_t i=0; i<len; i++ )
90                 if( str[i]=='.' ) str[i]='_';
91         return str;
94 void dotappend( char*& base, char const * suffix )
96         // append like "str.suffix" if suffix else "str"
98         if( suffix == NULL )
99                 return ;
101         size_t siz;
102         if( (siz=strlen(suffix)) == 0 )
103                 return ;
105         size_t siz2 = base==NULL ? 0 : strlen(base);
107         char* newstr;
109         {//do never forget to increment/decrement alloc_cnt
110         newstr = (char*) malloc( (siz2+siz+1) +1 /*for "." */ );
111         alloc_cnt++;
112         }
114         if( newstr == NULL )
115                 fprintf( stderr,"error: dotappend() could not malloc() \n"), exit(1);
117         if( base ) {
118                 strcpy( newstr, base );
119                 freestring( base );
120         }
121         else
122                 newstr[0] = '\0';
124         strcat( newstr, "." );
125         strcat( newstr, suffix );
126         base = newstr;
129 void dotsubtract( char*& base, char const * suffix )
131         // remove dotted suffix from base.suffix --> base
133         if( base == NULL || suffix == NULL )
134                 return;
135         if( strlen(suffix) == 0 )
136                 return;
137         if( (strlen(suffix)+1) > strlen(base) )
138                 return;
139         char * pos=strstr( base, suffix);
140         if( pos && (pos-1 >= base) && ( *(pos-1) == '.') )
141                 if( *(pos+strlen(suffix)) == '\0' ) //only if at end of base
142                         *(pos-1)= '\0';
143         return;
146 int level = 0;
147 char levelbuffer[512];
149 void adjust_levelbuffer()
151         int i;
152         for(i=0; i<level;i++) {
153                 levelbuffer[i] = '\t';
154         }
155         levelbuffer[i] = '\0';
158 void freestring( char const * ptr )
160     alloc_cnt--;
161     adjust_levelbuffer();
162     if ( bVerbose )
163             fprintf(stdout,"%sinfo: freestring line %d\n",levelbuffer, __LINE__);
164     free(const_cast< char * >(ptr)), ptr = NULL;
167 void makestring(char** newstr, char* oldstr)
169         alloc_cnt++;
170         adjust_levelbuffer();
171         if ( bVerbose )
172             fprintf(stdout,"%sinfo: makestring on line %d\n",levelbuffer,__LINE__);
173         strcpy( (*newstr=(char*)malloc(strlen(oldstr)+1)), oldstr);
174         if( *newstr==NULL ) {
175                 fprintf( stderr,
176                 "error: cannot malloc for makestring() alloc_cnt==%d \n", alloc_cnt);
177                 exit(1);
178         }
181 #ifndef WNT
182 int strcmpi(char const * stra, char const * strb)
184         // like strcmp() but case insensitive
185         size_t i;
186         char a,b;
187         for(i=0; ;i++){
188                 a = (char) tolower(stra[i]);
189                 b = (char) tolower(strb[i]);
190                 if( a < b )
191                         return -1;
192                 if( a > b )
193                         return 1;
194                 if( a == '\0' && b == '\0' )
195                         return 0;
196         }
198 #endif
200 /* variables for listfile ( with project + pathname of src file ) */
201 char* listfilename;
202 #define MAXSRCFILES 2048
203 char* filename_tab[MAXSRCFILES];
204 char* project_tab[MAXSRCFILES];
205 int tab_entries = 0;
206 //int fileno = 0; /* currently used filenumber */
208 /* globale variablen */
209 FILE* outfile;
210 char const *filename = ""; //incl. path
211 //char *basename = "";
212 char const *project = "";
213 char const *subpath = "";       //from project name downwards like source\ui\xxx.src
215 int firstprint = 1;
217 int in_define = 0;
219 class ident_ring
221         #define MAXRING 2
222         //nicht aendern wg externer Abfrage ->size() == 2
224         char*  ring[MAXRING];
225         int     ringpos;
226         int     last;
227         int     broken;
228 public:
229                 ident_ring()  {
230                                                         last = ringpos = -1;
231                                                         for(int i=0; i<MAXRING;i++)
232                                                                 ring[i]=NULL;
233                                                         broken = 0;
234                                                   }
236         void    set_zero()    {
237                                                         last = ringpos = -1;
238                                                         for(int i=0; i<MAXRING;i++) {
239                                                                 if( ring[i] != NULL )
240                                                                         freestring( ring[i] );
241                                                                 ring[i]=NULL;
242                                                         }
243                                                         broken = 0;
244                                                   }
245         void    set_broken()  { broken = 1; }
246         int     size()        {
247                                                         if( ringpos == -1 )
248                                                                 return 0;
250                                                         if( broken) {
251                                                                 if( ringpos==0 )
252                                                                         return 0;
253                                                                 else
254                                                                         return 1;
255                                                         } else {
256                                                                 if( ringpos==0 )
257                                                                         return 1;
258                                                                 else
259                                                                         return 2;
260                                                         }
261                                                   }
263         char*   extract_last(){
264                                                         if( last == -1 )  {
265                                                                 return NULL;
266                                                         } else {
267                                                                 char* ttt=ring[last];
268                                                                 ring[last]=NULL;
269                                                                 return ttt;
270                                                         }
271                                               }
273         char*   extract_actual()  {
274                                                         if(ringpos == -1) {
275                                                                 return NULL;
276                                                         } else {
277                                                                 char *ttt=ring[ringpos];
278                                                                 ring[ringpos]=NULL;
279                                                                 return ttt;
280                                                         }
281                                                   }
283         void    set(char* id) {
284                                                         ringpos= (++ringpos) % MAXRING;
285                                                         if( ring[ringpos] != NULL )
286                                                                 freestring( ring[ringpos] ); /*otherwise: memory lost*/
287                                                         ring[ ringpos ] = id;
288                                                         if ( bVerbose )
289                                                             fprintf(stdout,
290                                                                     "info: ring[%d] == %s broken==%d \n"
291                                                                     ,ringpos,ring[ringpos],broken
292                                                             );
294                                                         if( !(ringpos==0 && last==-1) )
295                                                                 last = (++last) % MAXRING;
296                                                   }
300 /* Notnagel: die letzten identifier/number merken, fuer klasse & globalID */
301 ident_ring *ring;
304 typedef int token;
306 #define TOK_SEMICOLON   ';'
307 #define TOK_EQUAL               '='
308 #define TOK_OPENBRACKET '['
309 #define TOK_CLOSEBRACKET ']'
310 #define TOK_OPENBRACE   '{'
311 #define TOK_CLOSEBRACE  '}'
312 #define TOK_KOMMA               ','
313 #define TOK_LESS                '<'
314 #define TOK_GREATER             '>'
315 #define TOK_OPENPAREN   '('
316 #define TOK_CLOSEPAREN  ')'
317 #define TOK_PLUS                '+'
318 #define TOK_MINUS               '-'
319 #define TOK_STAR                '*'
320 #define TOK_SLASH               '/'
322 #define TOK_POSorSIZE   146
323 #define TOK_POSSIZE             147
324 #define TOK_TEXTTAG             148
325 #define TOK_IDNUM               149
327 #define TOK_EXTRADATA   151
328 #define TOK_TEXT                152
329 #define TOK_MESSAGE             153
330 #define TOK_HELPTEXT    154
331 #define TOK_TRUE                155
332 #define TOK_FALSE               156
334 #define TOK_RESID       180
336 #define TOK_STRING              190
338 #define TOK_INVALID     (-1)
340 token  lasttoken = TOK_INVALID;
345 #define UNDEF (-1)
347 char *globalID = const_cast< char * >("");
348 char const *globalKLASSE = NULL;
350 void reset_globalID() {
351         //
352         if( globalID && (strlen(globalID) > 0 ) ) {
353                 freestring( globalID );
354                 globalID = const_cast< char * >("");
355         }
359 //--------------------------------------------------------------------
360 class resource
362 private:
363         resource ( const resource& );  //copy-ctor soll keiner benutzen
364         void operator=( const resource& ); // zuweisung auch nicht
365 public:
366         resource();
367         ~resource();
368 public:
369         int      lineno;
370         token  lasttoken; //before opening {
371         char const *klasse ;
372         char *localID;
373         char *helpID;
374         int  residfound;
377 resource *ares ; /* aktuell bearbeitete resource */
379 resource::~resource()
381         if( klasse != NULL )   freestring(klasse);
382         if( localID != NULL )  freestring(localID);
383         if( helpID != NULL )   freestring(helpID);
387 resource::resource()
389         lineno =   UNDEF;
390         lasttoken= TOK_INVALID;
391         klasse =    NULL ;
392         localID =  NULL ;
393         helpID =   NULL ;
394         residfound= 0;
397 int residfound = 0; // "Identifier = " auf momentanem level gefunden
399 #define   MAXSTACK 32
400 resource* stack[MAXSTACK]; /* resource stack */
401 #define   EMPTYSTACK (-1)
402 int       stackptr = EMPTYSTACK;
404 void push_resource( resource* r )
406         stackptr++;
407         if( stackptr >= MAXSTACK ) {
408                 fprintf( stderr, "error: resource stack is full %d \n", stackptr);
409                 exit(1);
410         }
411         stack[ stackptr ] = r;
414 resource* pop_resource()
416         if( stackptr < 0 ) {
417                 fprintf( stderr, "error: pop resource from empty stack \n");
418                 exit(1);
419         }
420         return stack[ stackptr-- ];
423 /* forward */
424 int eat_comment();
425 int eat_cpp_comment();
427 /*===================================================*/
429 // '+' im identifier wg basic\source\classes\sb.src
431 // '<' im identifier wg sc subtdlg.src
433 // '&' im identifier wg scerror.src so2..nocode.src svxerr.src scwarngs.src
436 //string                (\"[^"]*\") alter einfacher string ohne "
440 /* 89012 */
441 %option never-interactive
444 simple          ([^\n\"]*)
445 %p 7000
446 string          \"{simple}((((\\\\)*(\\\"))?){simple})*\"
448 %x MACRO_STATE
450 %x EXCLUDE_STATE
451 resfilelist         ([Ff][Ii][Ll][Ee][Ll][Ii][Ss][Tt])
452 resstringlist   ([Ss][Tt][Rr][Ii][Nn][Gg][Ll][Ii][Ss][Tt])
453 resstring       ([Ss][Tt][Rr][Ii][Nn][Gg])
455 identifier ([a-z_A-Z]+[a-z_A-Z<+&0-9]*)
456 number          (([0-9]+)|(0x[0-9a-fA-F]+))
457 residentifier ([Ii][Dd][Ee][Nn][Tt][Ii][Ff][Ii][Ee][Rr])
458 w                       ([ \t\n]*)
459 wspecial        ([\\ \t\n]*)
460 texttag         (([Tt][Ii][Tt][Ll][Ee])|([Tt][Ee][Xx][Tt])|([Mm][Ee][Ss][Ss][Aa][Gg][Ee]))
461 qhelptag        (([Qq][Uu][Ii][Cc][Kk])?([Hh][Ee][Ll][Pp][Tt][Ee][Xx][Tt]))
462 langtag         ([a-zA-Z_]+)
463 helptag         ([Hh][Ee][Ll][Pp][Ii][Dd])
464 helpid          ([a-zA-Z_0-9]+)
465 num2tag         (([Pp][Oo][Ss])|([Ss][Ii][Zz][Ee]))
466 num4tag         (([Pp][Oo][Ss][Ss][Ii][Zz][Ee]))
469 [ \t]           {
470                                 /* forget whitespace */;
471                         }
473 ^[ \t]*#include.*\.src[">].*    {
474                                 char NewFile[255];              //long names???
475                                 int i, j, GetIt;
477                                 GetIt = 0;
478                                 j = 0;
479                                 nInputFileDepth++;
480 //      nicht schoen aber geht...
481                                 for (i = 0; yytext[i+1] != 0; i++)
482                                 {
483                                         if ( GetIt == 1 )
484                                         {
485                                                 if ( yytext[i] == '"' || yytext[i] == '>' )
486                                                         GetIt = 0;
487                                                 else
488                                                         NewFile[j++] = yytext[i];
489                                         }
490                                         if ( yytext[i] == '"' || yytext[i] == '<' )
491                                                 GetIt = 1;
492                                 }
493                                 NewFile[j] = '\0';
494                                 FILE* pFile = NULL;
495                                 pFile = fopen( NewFile, "r" );
496                                 if( pFile == NULL ) {
497                                         fprintf( stdout, "warning: could not open inputfile %s \n", NewFile );
498                                         // try the new *_tmpl.src version instead
499                                         // this hack was introduced to allow localisation of included src files
500                                         const char* sStrTmpl = "_tmpl";
501                                         j -= 4;
502                                         for ( i = 0 ; i <5 ; i++,j++ )
503                                         {
504                                             NewFile[j+5] = NewFile[j];
505                                             NewFile[j] = sStrTmpl[i];
506                                         }
507                                 NewFile[j+4] = '\0';
508                                         fprintf( stderr, "trying inputfile %s \n", NewFile );
509                                 pFile = fopen( NewFile, "r" );
510                                     if( pFile == NULL ) {
511                                             fprintf( stderr, "error: could not open inputfile %s \n", NewFile );
512                                             exit(1);
513                             }
514                                 }
515                                 InputFiles[ nInputFileDepth ] = yy_create_buffer( pFile, YY_BUF_SIZE );
516                 yy_switch_to_buffer( InputFiles[ nInputFileDepth ] );
518                 if ( bVerbose )
519                                     fprintf( stdout, "%s //ATTENTION!! %s gets included here\n", yytext, NewFile );
520                                 fprintf( outfile, "// %s //ATTENTION!! %s gets included here\n\n", yytext, NewFile );
521                         }
523 ^[ \t]*#include.*       {
524                                 fprintf( outfile, "%s\n\n", yytext );
525                         }
527 ^[ \t]*#(if|ifdef|ifndef|elif).*                {
528                                 ;
529                         }
531 ^[ \t]*#else    {
532                                 ;
533                         }
534 ^[ \t]*#endif   {
535                                 ;
536                         }
538 ^[ \t]*#(undef|error|pragma).*  {
539                                 ;
540                         }
542 ^[ \t]*#define  {
543                                 fprintf( outfile, "%s", yytext );
544                                 BEGIN MACRO_STATE;
545                         }
547 <INITIAL,MACRO_STATE>"/*"               {
548                                 eat_comment();
549                         }
551 <INITIAL,MACRO_STATE>"//"               {
552                                 eat_cpp_comment();
553                         }
555 <MACRO_STATE>\n {
556                                 fprintf( outfile, "%s\n", yytext );
557                                 BEGIN INITIAL;
558                         }
560 <MACRO_STATE>\\\n {
561                                 fprintf( outfile, "\\\n" );
562                         ;/* macro schadet nicht, koennte gebraucht werden */
563                         }
566 <MACRO_STATE>. {
567                         fprintf( outfile, "%s", yytext );
568                         ;/* ignore all this unused input */
569                         }
571 ";"             {ring->set_zero(); lasttoken = TOK_SEMICOLON; }
572 "="             {ring->set_zero(); lasttoken = TOK_EQUAL; }
573 "["             {ring->set_broken(); lasttoken = TOK_OPENBRACKET; }
574 "]"             {ring->set_broken(); lasttoken = TOK_CLOSEBRACKET; }
577 <EXCLUDE_STATE>"{"              {
578                                 exclude_bracelevel += 1;
579                             if ( bVerbose )
580                                     fprintf( stdout,"info: lev %d : found {\n", exclude_bracelevel );
581                         }
584 \\\n            |
585 "{"             {
586                                 // define continues
587                                 // or a brace opens a block
589                                 if( in_define && !strcmp(yytext,"\\\n") ) {
591                                         if( in_define++ == 1 )
592                                                 ;// keep on working
593                                         else
594                                                 goto blockend;
595                                 }
597                                 level++;
598                                 if( ares != NULL ){
599                                         if( level > 1 )
600                                                 dotappend( globalID, ares->localID );
601                                         ares->residfound = residfound;
602                                         push_resource( ares );
603                                 }
604                                 ares = new resource;
606                                 residfound = 0;
607                                 ares->residfound = 0;
609                                 ares->lineno = yylineno;
610                                 ares->lasttoken = lasttoken;
611                                 if( ring->size() == 2 ) {
612                                         ares->klasse = ring->extract_last();
613                                         ares->localID = ring->extract_actual();
614                                 } else if(ring->size() == 1) {
615                                         ares->klasse = ring->extract_actual();
616                                 }
617                                 if( level==1 ){ //Ausnahme: Resource auf Ebene 1
618                                         globalID= ares->localID;
619                                         ares->localID = NULL;
620                                         globalKLASSE= ares->klasse;
621                                 }
623                 if ( bVerbose )
624                                     fprintf(stdout,"info: { level: %d\n", level);
626                                 lasttoken = TOK_OPENBRACE;
627                                 ring->set_zero();
628                         }
630 <EXCLUDE_STATE>"}"              {
631                                 //-----------------------------
632                                 exclude_bracelevel -= 1;
633                                 if ( bVerbose )
634                                     fprintf( stdout,"info: lev %d : found }\n", exclude_bracelevel );
635                                 if( exclude_bracelevel==1 ) {
636                                         BEGIN INITIAL;
637                                         exclude_bracelevel=0;
638                                 }
639                         }
642 \n                      |
643 "}"             {
644                                 if ( bVerbose )
645                                     fprintf(stdout,"info:   } level: %d\n",level);
647                                 if( !strcmp(yytext,"}") )
648                                         ;
649                                 else if( in_define && (!strcmp(yytext,"\n") )) {
650                                         if( in_define==1 ) {
651                                                 //no continuation line for #define
652                                                 in_define=0;
653                                                 goto blockend;
654                                         }
655                                         else {
656                                                 //there was a continuation line for #define
657                                                 in_define=0;
658                                         }
659                                 }
660                                 else
661                                         goto blockend;
663                                 // ares ausgeben
664                                 if( ares != NULL ) {
666                                         #define LEER "leer"
667                                         char const * globklasse =
668                       globalKLASSE==NULL ? LEER:globalKLASSE;
669                                         char const * local =
670                       ares->localID==NULL ? LEER:ares->localID;
671                                         char const * klasse =
672                       ares->klasse==NULL ? LEER:ares->klasse;
673                                         char const * glob =
674                       globalID==NULL ? LEER:globalID;
677                                         //wg. Starview-Klasse String in ehdl.c und doc.c
678                                         // wenn generierte C++-Quellen compiliert werden
679                                         //
680                                         //if( !strcmp(globklasse,"String" )) globklasse = "string";
681                                         //if( !strcmp(klasse,"String" )) klasse = "string";
684                                         //---------------------------------------------------
685                                         // generate the body of a new C main program,
686                                         // which is filled with printf statements
687                                         // to compute (via preproseccor & compiler)
688                                         // the codenumbers for resource names like menu$RID_SVX$xyz
690                                         if( firstprint ) {
691                                                 firstprint=0;
692                                                 fprintf(outfile, "#include \"starview.hid\" \n\n");
693                                                 fprintf(outfile, " int main() { \n\n\n");
694                                         }
696                                         char globunder[256];
697                                     strcpy(globunder,glob);
698                                         dot2underline( globunder );
699                                         char const * globsuffix = strrchr(glob,'.');
700                                         globsuffix = globsuffix==NULL ? glob:globsuffix+1;
702                                         if( ares->helpID ) {
703                                                 fprintf( outfile,"\n\t printf(\"%s \\t %cs %cu \\n\",\n",
704                                                 ares->helpID,'%','%');
705                                                 fprintf(outfile,"\t\"HelpID\", (%s) ); \n", ares->helpID);
706                                         }
707                                         else if( ares->localID ) {
708                                                 fprintf( outfile,"\n\t printf(\"%s:%s:%s:%s \\t %cs %cu %cs %cu \\n\",\n",
709                                                 project,klasse,globunder,local,'%','%','%','%');
710                                                 fprintf( outfile,"\t\"Norm %s\", (%s), \"%s\", (%s) );\n",
711                                                 globklasse,globsuffix, klasse,local);
712                                         }
713                                         else if( (strcmpi("MenuItem",klasse)==0) ||
714                                                     (strcmpi("ToolBoxItem",klasse)==0) ) {
715                                                         ; //no output (99% is a separator)
716                                         }
717                                         else {
718                                                 fprintf( outfile,"\n\t printf(\"%s:%s:%s \\t %cs %cu %cs \\n\",\n",
719                                                 project,klasse,globunder,'%','%','%');
720                                                 fprintf( outfile,"\t\"Norm %s\", (%s), \"%s\" );\n",
721                                                 globklasse,globsuffix, klasse);
722                                         }
724                                         delete ares;
725                                 }
728                                 // ein level zurueck
729                                 if( level == 1) {
730                                         reset_globalID();
731                                         globalKLASSE = NULL;
732                                 }
733                                 level--;
734                                 ares = pop_resource();
735                                 residfound = ares->residfound;
736                                 dotsubtract( globalID, ares->localID );
739                                 //
740                                 lasttoken = TOK_CLOSEBRACE;
741                                 ring->set_zero();
742                 blockend:       ;
743                         }
745 ","             {ring->set_broken(); lasttoken = TOK_KOMMA; }
747 "<"             {ring->set_broken(); lasttoken = TOK_LESS; }
748 ">"             {ring->set_broken(); lasttoken = TOK_GREATER; }
750 "("             {ring->set_broken(); lasttoken = TOK_OPENPAREN; }
751 ")"             {ring->set_broken(); lasttoken = TOK_CLOSEPAREN; }
752 "+"             {ring->set_broken(); lasttoken = TOK_PLUS; }
753 "-"             {ring->set_broken(); lasttoken = TOK_MINUS; }
754 "*"             {ring->set_broken(); lasttoken = TOK_STAR; }
755 "/"             {ring->set_broken(); lasttoken = TOK_SLASH; }
758 {helptag}{w}"="{w}{helpid}{w}";" {
760                         // extract text for helpid and put to ares
761                         char*     pos = strchr(yytext,'=');
762                         size_t offset = strspn(pos+1," \t\n");
763                         char*   start = pos+1+offset;
764                         size_t offset2= strcspn( start, "; \t\n");
765                         char*     end = start+offset2;
766                         *end = '\0';
767                         char *helpid;
768                         makestring( &helpid, start );
769                         ares->helpID = helpid;
770                         }
772 {residentifier}{w}"="[ \t\n]*({identifier}|{number}) {
773                         ring->set_zero();
774                         lasttoken = TOK_RESID;
775                         residfound=1;
777                         //extract resource id and store as localID
778                         char *after = strrchr(yytext,'=');
779                         char *resid = after + strspn(after,"= \t\n");
780                         char *localID;
781                         makestring( &localID, resid );
782                         ares->localID = localID;
783                         }
785 {resfilelist}   |
786 {resstring}     |
787 {resstringlist} {
788                         BEGIN EXCLUDE_STATE;
789                         exclude_bracelevel = 1;
790                         if ( bVerbose )
791                             fprintf( stdout,"info: lev %d : found exclusion\n", exclude_bracelevel );
792                         }
794 ^[ \t]*#define          |
795 {number}                |
796 {identifier} {
797                 /* identifier/number in einem ring ablegen */
798                 char *identifier;
799                 char *def=strstr(yytext,"#define");
800                 if( def ) {
801                         in_define = 1;
802                         makestring( &identifier, def+1 );
803                 }
804                 else
805                         makestring( &identifier, yytext );
806                 ring->set( identifier );
807                 lasttoken = TOK_IDNUM;
809         }
810 <INITIAL,EXCLUDE_STATE>{string} {
811                         ring->set_broken();
812             lasttoken = TOK_STRING;
813             if ( bVerbose )
814                             fprintf(stdout, "%6s %11s %8d %s \n",project,filename,yylineno, yytext);
815                         }
818 <INITIAL,EXCLUDE_STATE>.        { if ( bVerbose ) fprintf( stdout,"warning: unused input on line %d of %s \n%s\n",
819                                         yylineno, filename, yytext);
820         }
822 <EXCLUDE_STATE>\n       {
823                                                 ; //do nothing, ignore
824         }
830 void makeversion( char* version )
832         char const *pos = strpbrk( Revision, "0123456789." );
833         size_t siz = strspn( pos,      "0123456789." );
834         if( pos && siz ) {
835                 strncpy(version, pos, siz);
836                 strcat( version, " ");
837         }
838         else
839                 strcpy( version," unknown " );
842 int main( int argc, char* argv[] )
844         static char const *Compiler = "HID-Compiler ";
845         static char const *Author   = "OG ";
846         static char HIDCompiler[100];
847         static char Version[100];
849     // check for switches given on the command line
850     if ( ( argc > 0 ) && ( 0 == strcmp( argv[0], "-verbose" ) ) )
851     {
852         bVerbose = true;
853         for ( size_t i=0; i<argc-1; ++i )
854         {
855             argv[i] = argv[i+1];
856             --argc;
857         }
858     }
860         makeversion( Version );
861         strcpy( HIDCompiler, Compiler );
862         strcat( HIDCompiler, Version  );
863         strcat( HIDCompiler, Author   );
864         if ( bVerbose )
865             fprintf( stdout, "\n %s \n\n", HIDCompiler);
866         if(argc < 4) {
867                 fprintf(
868                 stderr,
869                 "usage: hidc [-verbose] file.src file.c project\n"
870                 "\n"
871                 "You must give exactly 3 arguments.\n"
872                 "1 - an existing SRC file.\n"
873                 "2 - C file to be generated (which generates the HID file when run).\n"
874                 "3 - the project name (an arbitrary name).\n\n"
875                 );
876                 exit(1);
877         }
879         project = argv[3];
881         char *outfilename = argv[2];
882         if( (outfile=fopen( outfilename , "w" )) ==NULL ) {
883                 fprintf(stderr,"error: could not open outputfile '%s' \n", outfilename);
884                 exit(1);
885         }
887         filename = argv[1];
888         nInputFileDepth = 0;
889         FILE* pFile;
890         pFile = fopen( filename, "r" );
891         if( pFile == NULL ) {
892                 fprintf( stderr, "error: could not open inputfile %s \n", filename );
893                 exit(1);
894         }
895         InputFiles[ nInputFileDepth ] = yy_create_buffer( pFile, YY_BUF_SIZE );
896     yy_switch_to_buffer( InputFiles[ nInputFileDepth ] );
897         ring = new ident_ring;
898         ares = new resource;
900         fprintf(outfile, "/* Generated from %s */\n\n", HIDCompiler );
901         fprintf(outfile, "/* Source was: %s */\n", filename );
903         yylineno = 1;
904         yylex(); /* do the real work here */
906         if( firstprint ) {
907                 fprintf(outfile, "#include \"starview.hid\" \n\n");
908                 fprintf(outfile, " int main() { \n\n\n");
909         }
910         fprintf(outfile, "\nreturn 0;");
911         fprintf(outfile, "\n} /*main*/\n");
912         return 0;
915 int yywrap()
917     yy_delete_buffer( InputFiles[ nInputFileDepth ] );
918         if ( nInputFileDepth == 0 )
919                 return 1;/* keine src files mehr */
920         else
921         {
922                 nInputFileDepth--;
923         fprintf(outfile, "// Done reading file\n\n");
924         yy_switch_to_buffer( InputFiles[ nInputFileDepth ] );
925                 return 0;
926         }
929 int eat_comment()
931         int c;
932         int lastc = ' ';
933         while( (c=yyinput()) != EOF ) {
934                 if( c=='\n')
935                         ;
936                 else if( c=='/' && lastc=='*' )
937                         break; /* end of comment found */
938                 lastc=c;
939         }
940         return 0;
943 int eat_cpp_comment()
945         int c;
946         while( (c=yyinput()) != EOF ) {
947                 if( c=='\n') {
948                         break;
949                 }
950         }
951         if( c != EOF )
952                 unput(c); /* because next #.... line was not found */
953         return 0;