Added a parameter to semaphore constructor to avoid ambiguity
[pwlib.git] / tools / pwrc / pr_lex.l
bloba2b9208b44efdf93413418ed8aa6457e1ddd7c6f
1 %{
2 /*
3  * pr_lex.l
4  *
5  * Resource compiler lexical analyser
6  *
7  * Portable Windows Library
8  *
9  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10  *
11  * The contents of this file are subject to the Mozilla Public License
12  * Version 1.0 (the "License"); you may not use this file except in
13  * compliance with the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/
15  *
16  * Software distributed under the License is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18  * the License for the specific language governing rights and limitations
19  * under the License.
20  *
21  * The Original Code is Portable Windows Library.
22  *
23  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24  *
25  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
26  * All Rights Reserved.
27  *
28  * Contributor(s): ______________________________________.
29  *
30  * $Log$
31  * Revision 1.28  2002/12/02 02:40:05  robertj
32  * Changed due to compiler compatibility.
33  *
34  * Revision 1.27  2002/11/25 22:44:24  robertj
35  * Fixed MSVC v5 compatibility
36  *
37  * Revision 1.26  2002/04/26 05:38:09  robertj
38  * Removed assumption that GetAt() on a dictionary will automatically convert
39  *   the index to a POrdinalyKey. This breaks the PCollection semantics for
40  *   GetAt() which is to get based on the ordinal position not the hashed position.
41  *
42  * Revision 1.25  2001/02/22 06:26:42  robertj
43  * Fixed warning from flex.
44  *
45  * Revision 1.24  1999/10/29 11:44:25  robertj
46  * Fixed #ifdef conditional around the wrong way.
47  *
48  * Revision 1.24  1999/10/29 11:44:25  robertj
49  * Fixed #ifdef conditional around the wrong way.
50  *
51  * Revision 1.23  1999/10/19 07:08:23  robertj
52  * Added #ifdef/#ifndef condition compile functionality
53  *
54  * Revision 1.22  1999/02/06 08:45:33  robertj
55  * egcs compatibility
56  *
57  * Revision 1.21  1998/09/26 01:24:15  robertj
58  * Added open source license
59  *
60  * Revision 1.20  1998/09/26 00:40:27  robertj
61  * Fixed linkage mismatch of lex function.
62  *
63  * Revision 1.19  1998/09/14 13:48:05  robertj
64  * Allowed suppression of some warnings.
65  *
66  * Revision 1.18  1997/12/12 08:44:25  robertj
67  * Update to currect version of PWLIB
68  *
69  * Revision 1.17  1996/01/23 13:32:45  robertj
70  * More changes for editor
71  *
72  * Revision 1.16  1995/12/23 03:53:39  robertj
73  * Added extra collections for editor use.
74  *
75  * Revision 1.15  1995/12/10 12:12:05  robertj
76  * Changes to support graphical resource file editor.
77  *
78  * Revision 1.14  1995/08/24 12:48:13  robertj
79  * Added general control type for arbitrary dialog controls.
80  *
81  * Revision 1.13  1995/07/31 12:30:13  robertj
82  * Changed all generated resource IDs to be in the same "number space". This
83  *   is to avoid problems with IDs being used for more than one type of resource
84  *   eg a menu item and an image for a toolbar.
85  * Fixed the generated #line commands to include a relative path instead of an
86  *   absolute one.
87  *
88  * Revision 1.12  1995/01/27 11:25:43  robertj
89  * Added pattern resource.
90  *
91  * Revision 1.11  1994/12/12  13:14:04  robertj
92  * Changed RealEdit to FloatEdit.
93  *
94  * Revision 1.10  1994/12/05  11:38:01  robertj
95  * Added #line to generated code.
96  *
97  * Revision 1.9  1994/10/23  06:07:12  robertj
98  * Shortened OS error assert.
99  *
100  * Revision 1.8  1994/07/02  03:28:52  robertj
101  * Fixed accidentaly removed header keyword.
102  * Fixed comment parsing problem.
104  * Revision 1.6  1994/04/20  12:47:01  robertj
105  * *** empty log message ***
107  * Revision 1.5  1994/04/01  14:29:16  robertj
108  * New format PRC file
110  * Revision 1.4  1993/08/20  21:31:56  robertj
111  * Included ctype for unix compatibility.
113  * Revision 1.3  1993/07/16  12:48:13  robertj
114  * Added slash star style comments.
115  * General formatting.
117  * Revision 1.2  1993/07/15  04:38:31  robertj
118  * Rationalised lex.h, parse.h and main.h out of existance.
119  * Fixed literal string so can have embedded \" characters.
121  * Revision 1.1  1993/07/03  06:01:44  robertj
122  * Initial revision
124  * Revision 1.2  1993/06/24  19:48:57  craigs
125  * Added support for hash comments
127  * Revision 1.1  1993/06/24  19:23:17  craigs
128  * Initial revision
130  */
132 #include <ptlib.h>
133 #include "pwrc.h"
134 #include "pr_gramm.h"
136 #include <ctype.h>
138 extern FILE * yyin;
140 extern int yyparse();
142 extern ResourceFile * current_file;
143 extern ostream * inline_src;
144 extern ostream * inline_hdr;
147 ///////////////////////////////////////////
149 //  handling for "include" files
152 PDECLARE_CLASS(LexState, PObject)
153   public:
154     LexState(const PFilePath & fn)
155       : filename(fn) { line_number = 1; }
157     Comparison Compare(const PObject & obj) const
158       { return filename.Compare(((const LexState &)obj).filename); }
160     YY_BUFFER_STATE yy_state;
161     unsigned        line_number;
162     PFilePath       filename;
163     PDirectory      dir;
166 PSTACK(LexStack, LexState);
168 static LexStack LexFile;
170 static int in_define;
171 static int in_multiline_comment;
173 PStringArray IncludePath;
176 ResourceFile::ResourceFile(PFile & prcfile, BOOL suppress,
177                            const PString & predefinedSymbols)
179   nextResourceId  = 10000;
180   fatals = warnings = 0;
181   suppressInfoWarnings = suppress;
183   PStringArray symbols = predefinedSymbols.Lines();
184   for (PINDEX i = 0; i < symbols.GetSize(); i++)
185     defineDict.SetAt(symbols[i], new DefineValue(1, FALSE));
187   inline_src = &src_inline;
188   inline_hdr = &hdr_inline;
190   for (PINDEX type = 0; type < ResourceList::NumResTypes; type++) {
191     resources[type].type = (ResourceList::ResTypes)type;
192     resources[type].DisallowDeleteObjects();
193   }
195   resourceDict[ResourceList::StringRes] = &stringDict;
196   resourceDict[ResourceList::MenubarRes] = &menubarDict;
197   resourceDict[ResourceList::LayoutRes] = &dialogDict;
198   resourceDict[ResourceList::IconRes] = &iconDict;
199   resourceDict[ResourceList::CursorRes] = &cursorDict;
200   resourceDict[ResourceList::PatternRes] = &patternDict;
201   resourceDict[ResourceList::ImageRes] = &imageDict;
202   resourceDict[ResourceList::DataRes] = &dataDict;
204   current_file = this;
205   in_define = 0;
207   LexFile.Push(new LexState(prcfile.GetFilePath()));
209   yyin = _fdopen(prcfile.GetHandle(), "r");
210   PAssertNULL(yyin);
211   yyparse();
215 ostream & operator<<(ostream & out, const StdError & e)
217   if (e.e == Info && current_file->suppressInfoWarnings) {
218     static PStringStream dummy;
219     dummy = "";
220     return dummy;
221   }
223   out << e.l.filename << '(' << e.l.number << ") : ";
224   if (e.e == Fatal) {
225     current_file->fatals++;
226     out << "error";
227   }
228   else {
229     current_file->warnings++;
230     out << "warning";
231   }
232   return out << ": ";
236 void LineNumber::Set()
238   if (LexFile.IsEmpty()) {
239     filename = "";
240     number = 0;
241   }
242   else {
243     filename = LexFile.Top().filename;
244     number = LexFile.Top().line_number;
245   }
249 extern "C" int yywrap()
251   return 1;
257 %option never-interactive
259 %x hash_include hash_inline_src hash_inline_hdr comment_lines conditional_compilation
264 [Dd][Ee][Ff][Pp][Uu][Ss][Hh][Bb][Uu][Tt][Tt][Oo][Nn]  { return DEFPUSHBUTTON; }
266 [Aa][Cc][Cc][Ee][Ll][Ee][Rr][Aa][Tt][Oo][Rr][Ss]  { return ACCELERATORS; }
268 [Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd][Bb][Oo][Xx]  { return PASSWORDBOX; }
270 [Mm][Oo][Dd][Aa][Ll][Dd][Ii][Aa][Ll][Oo][Gg]  { return MODALDIALOG; }
272 [Rr][Aa][Dd][Ii][Oo][Bb][Uu][Tt][Tt][Oo][Nn]  { return RADIOBUTTON; }
274 [Mm][Uu][Ll][Tt][Ii][Ss][Ee][Ll][Ee][Cc][Tt]  { return MULTISELECT; }
276 [Mm][Uu][Ll][Tt][Ii][Cc][Oo][Ll][Uu][Mm][Nn]  { return MULTICOLUMN; }
278 [Ss][Tt][Rr][Ii][Nn][Gg][Ll][Ii][Ss][Tt]  { return STRINGLIST; }
280 [Pp][Uu][Ss][Hh][Bb][Uu][Tt][Tt][Oo][Nn]  { return PUSHBUTTON; }
282 [Ss][Tt][Aa][Tt][Ii][Cc][Ii][Cc][Oo][Nn]  { return STATICICON; }
284 [Cc][Ee][Nn][Tt][Rr][Ee][Tt][Ee][Xx][Tt]  { return CENTRETEXT; }
285 [Cc][Ee][Nn][Tt][Ee][Rr][Tt][Ee][Xx][Tt]  { return CENTRETEXT; }
287 [Hh][Ss][Cc][Rr][Oo][Ll][Ll][Bb][Aa][Rr]  { return HSCROLLBAR; }
289 [Vv][Ss][Cc][Rr][Oo][Ll][Ll][Bb][Aa][Rr]  { return VSCROLLBAR; }
291 [Tt][Ee][Xx][Tt][Ee][Dd][Ii][Tt][Oo][Rr]  { return TEXTEDITOR; }
293 [Dd][Ii][Mm][Ee][Nn][Ss][Ii][Oo][Nn][Ss]  { return DIMENSIONS; }
294 [Dd][Ii][Mm]                              { return DIMENSIONS; }
296 [Rr][Ii][Gg][Hh][Tt][Tt][Ee][Xx][Tt]  { return RIGHTTEXT; }
298 [Ss][Tt][Aa][Tt][Ii][Cc][Bb][Oo][Xx]  { return STATICBOX; }
300 [Ss][Ee][Pp][Aa][Rr][Aa][Tt][Oo][Rr]  { return SEPARATOR; }
302 [Cc][Hh][Oo][Ii][Cc][Ee][Bb][Oo][Xx]  { return CHOICEBOX; }
304 [Ff][Ll][Oo][Aa][Tt][Ee][Dd][Ii][Tt]  { return FLOATEDIT; }
306 [Cc][Hh][Ee][Cc][Kk]3[Ww][Aa][Yy]  { return CHECK3WAY; }
308 [Cc][Hh][Ee][Cc][Kk][Bb][Oo][Xx]  { return CHECKBOX; }
310 [Ll][Ee][Ff][Tt][Tt][Ee][Xx][Tt]  { return LEFTTEXT; }
312 [Pp][Oo][Ss][Ii][Tt][Ii][Oo][Nn]  { return POSITION; }
313 [Pp][Oo][Ss]                      { return POSITION; }
315 [Cc][Oo][Mm][Bb][Oo][Bb][Oo][Xx]  { return COMBOBOX; }
317 [Rr][Ee][Ss][Oo][Uu][Rr][Cc][Ee]  { return RESOURCE; }
319 [Oo][Pp][Tt][Ii][Oo][Nn][Ss]  { return OPTIONS; }
321 [Ee][Dd][Ii][Tt][Bb][Oo][Xx]  { return EDITBOX; }
323 [Ii][Nn][Tt][Ee][Dd][Ii][Tt]  { return INTEDIT; }
325 [Ll][Ii][Ss][Tt][Bb][Oo][Xx]  { return LISTBOX; }
327 [Mm][Ee][Nn][Uu][Bb][Aa][Rr]  { return MENUBAR; }
329 [Pp][Aa][Tt][Tt][Ee][Rr][Nn]  { return PATTERN_token; }
331 [Hh][Oo][Tt][Ss][Pp][Oo][Tt]  { return HOTSPOT; }
333 [Aa][Nn][Dd][Mm][Aa][Ss][Kk]  { return ANDMASK; }
335 [Xx][Oo][Rr][Mm][Aa][Ss][Kk]  { return XORMASK; }
338 [Cc][Oo][Ll][Oo][Uu][Rr][Ss]  { return COLOURS; }
339 [Cc][Oo][Ll][Oo][Rr][Ss]      { return COLOURS; }
341 [Dd][Ee][Ff][Aa][Uu][Ll][Tt]  { return DEFAULT; }
343 [Cc][Oo][Nn][Tt][Rr][Oo][Ll]  { return CONTROL; }
345 [Hh][Ee][Aa][Dd][Ee][Rr]  { return HEADER; }
347 [Ww][Ii][Nn][Dd][Oo][Ww]  { return WINDOW; }
349 [Nn][Oo][Tt][Ii][Ff][Yy]  { return NOTIFY; }
351 [Ll][Aa][Yy][Oo][Uu][Tt]  { return LAYOUT; }
353 [Ss][Tt][Rr][Ii][Nn][Gg]  { return STRING; }
355 [Dd][Ii][Aa][Ll][Oo][Gg]  { return DIALOG; }
357 [Ss][Oo][Rr][Tt][Ee][Dd]  { return SORTED; }
359 [Cc][Uu][Rr][Ss][Oo][Rr]  { return CURSOR; }
361 [Pp][Ii][Xx][Ee][Ll][Ss]  { return PIXELS; }
363 [Cc][Aa][Nn][Cc][Ee][Ll]  { return CANCEL; }
365 [Ll][Ii][Mm][Ii][Tt][Ss]  { return LIMITS; }
367 [Tt][Ii][Tt][Ll][Ee]  { return TITLE; }
369 [Ii][Mm][Aa][Gg][Ee]  { return IMAGE; }
371 [Bb][Ee][Gg][Ii][Nn]  { return BEGIN_token; }
373 [Vv][Aa][Ll][Uu][Ee]  { return VALUE; }
375 [Cc][Ll][Aa][Ss][Ss]  { return CLASS; }
377 [Ff][Ii][Ee][Ll][Dd]  { return FIELD; }
379 [Ff][Oo][Nn][Tt]  { return FONT; }
381 [Mm][Ee][Nn][Uu]  { return MENU; }
383 [Ii][Cc][Oo][Nn]  { return ICON; }
385 [Ii][Tt][Ee][Mm]  { return ITEM; }
387 [Hh][Ee][Ll][Pp]  { return HELP; }
389 [Ee][Nn][Dd]  { return END; }
391 [Ii][Dd]      { return ID; }
393 [Oo][Kk]      { return OK; }
396 ^"#inline"[ \t]+"src".*  {
397     BEGIN(hash_inline_src);
398     *inline_src << LineNumber();
399   }
401 <hash_inline_src>^"#inline"[ \t]+"end".*  { BEGIN(0); }
403 <hash_inline_src>^[^\n]*  { *inline_src << yytext; }
405 <hash_inline_src>\n  {
406     LexFile.Top().line_number++;
407     *inline_src << '\n';
408   }
411 ^"#inline"[ \t]+"hdr".*  {
412     BEGIN(hash_inline_hdr);
413     *inline_hdr << LineNumber();
414   }
416 <hash_inline_hdr>^"#inline"[ \t]+"end".*  { BEGIN(0); }
418 <hash_inline_hdr>^[^\n]*  { *inline_hdr << yytext; }
420 <hash_inline_hdr>\n  {
421     LexFile.Top().line_number++;
422     *inline_hdr << '\n'; 
423   }
426 ^\#include  { BEGIN(hash_include); }
428 <hash_include>[ \t]  { }
430 <hash_include>[^ \t\n]*  {
431     PString text(yytext);
432     PINDEX end = P_MAX_INDEX;
433     PINDEX start = text.FindOneOf("\"<");
434     if (start != P_MAX_INDEX)
435       end = text.Find(text[start] == '"' ? '"' : '>', start+1);
436     if (start == P_MAX_INDEX || end == P_MAX_INDEX)
437       PError << StdError(Warning) << "badly formed include.\n";
438     else {
439       PString fname = text(start+1, end-1);
441       FILE * file = NULL;
442       if (text[start] == '"')
443         file = fopen(fname, "r");
445       for (PINDEX i = 0; file == NULL && i < IncludePath.GetSize(); i++) {
446         if (PDirectory::Change(IncludePath[i]))
447           file = fopen(fname, "r");
448         else
449           PError << StdError(Warning) << "invalid path \""
450                  << IncludePath[i] << "\".\n";
451         if (file == NULL)
452           PAssertOS(LexFile.Top().dir.Change());
453       }
455       if (file == NULL)
456         PError << StdError(Warning)
457                << "include file " << fname << " not found.\n";
458       else {
459         LexFile.Top().yy_state = YY_CURRENT_BUFFER;
460         LexFile.Push(new LexState(fname));
461         yyin = file;
462         yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
463       }
464     }
465     BEGIN(INITIAL);
466   }
468 <<EOF>>  {
469     delete LexFile.Pop();
470     if (LexFile.IsEmpty()) 
471       yyterminate();
472     else  {
473       yy_switch_to_buffer(LexFile.Top().yy_state);
474       PAssertOS(LexFile.Top().dir.Change());
475     }
476   }
479 ^\#define  {
480     in_define = 1;
481     return HASH_DEFINE;
482   }
485 ^\#ifdef[ \t]+[^ \t\n]*  { 
486     PString text(yytext);
487     if (!current_file->IsNameDefined(text.Mid(text.Find(' ')).Trim()))
488       BEGIN(conditional_compilation);
489   }
491 ^\#ifndef[ \t]+[^ \t\n]*  {
492     PString text(yytext);
493     if (current_file->IsNameDefined(text.Mid(text.Find(' ')).Trim()))
494       BEGIN(conditional_compilation);
495   }
497 <conditional_compilation>^\#endif.*\n  {
498     BEGIN(INITIAL);
499   }
501 <conditional_compilation>\n  {
502     LexFile.Top().line_number++;
503   }
505 <conditional_compilation>.  { }
507 ^\#endif.*\n  { }
511 "//"  {
512     in_multiline_comment = FALSE;
513     BEGIN(comment_lines);
514   }
516 "/*"  {
517     in_multiline_comment = TRUE;
518     BEGIN(comment_lines);
519   }
521 <comment_lines>"*/"  {
522     if (in_multiline_comment)
523       BEGIN(INITIAL);
524   }
526 <comment_lines>\n  {
527     LexFile.Top().line_number++;
528     if (!in_multiline_comment)
529       BEGIN(INITIAL);
530   }
532 <comment_lines>.  { }
535 "@"  { return '@'; }
537 "{"  { return '{'; }
539 "}"  { return '}'; }
541 ";"  { return ';'; }
543 "("  { return '('; }
545 ")"  { return ')'; }
547 "+"  { return '+'; }
549 "-"  { return '-'; }
551 "*"  { return '*'; }
553 "/"  { return '/'; }
555 ","  { return ','; }
557 ":"  { return ':'; }
559 "="  { return '='; }
561 \"([^\"\n]|(\\\"))*\"  {
562     yylval.sval = new PString(yytext);
563     return LITERAL;
564   }
566 "0x"[0-9a-fA-F][0-9a-fA-F]*  {
567     yylval.ival = strtol(yytext+2, NULL, 16);
568     return INTEGER;
569   }
571 "0"[0-7]*  {
572     yylval.ival = strtol(yytext, NULL, 8);
573     return INTEGER;
574   }
576 [1-9][0-9]*  {
577     yylval.ival = strtol(yytext, NULL, 10);
578     return INTEGER;
579   }
581 [a-zA-Z_][a-zA-Z0-9_]*  {
582     PString name = yytext;
583     if (in_define ||
584         !current_file->defineDict.Contains(name) ||
585         !current_file->defineDict[name].IsString()) {
586       yylval.sval = new PString(name);
587       return IDENTIFIER;
588     }
589     else {
590       yylval.sval = new PString(current_file->defineDict[name].AsString());
591       return LITERAL;
592     }
593   }
595 [ \t\r]  { }
597 \n  {
598     LexFile.Top().line_number++;
599     if (in_define) {
600       in_define = 0;
601       return END_DEFINE;
602     }
603   }
605 .  { PError << StdError(Warning) << "unknown token " << yytext << endl; }
609 /* End PR_LEX.L */