fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / idlc / source / scanner.l
blob16ee27a93fe4e626cac5284b75626cf992c51209
1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  *   Licensed to the Apache Software Foundation (ASF) under one or more
11  *   contributor license agreements. See the NOTICE file distributed
12  *   with this work for additional information regarding copyright
13  *   ownership. The ASF licenses this file to you under the Apache
14  *   License, Version 2.0 (the "License"); you may not use this file
15  *   except in compliance with the License. You may obtain a copy of
16  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
19 %option yylineno
23  * scanner.ll - Lexical scanner for IDLC 1.0
24  */
26 #include "sal/config.h"
28 #include <ctype.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #include <idlc/idlc.hxx>
33 #include <idlc/errorhandler.hxx>
34 #include <idlc/fehelper.hxx>
36 #include "attributeexceptions.hxx"
39 class AstExpression;
40 class AstMember;
42 #include <parser.hxx>
44 /* handle locations */
45 int yycolumn = 1;
47 #define YY_USER_ACTION idlc()->setOffset(yycolumn, yycolumn+yyleng-1); \
48     yycolumn += yyleng;
50 sal_Int32               beginLine = 0;
51 ::rtl::OString  docu;
53 static int asciiToInteger(char const * s, sal_Int64  * sval, sal_uInt64 * uval) {
54     bool neg = false;
55     if (*s == '-') {
56         neg = true;
57         ++s;
58     }
59     unsigned int base = 10;
60     if (*s == '0') {
61         base = 8;
62         ++s;
63         if (*s == 'X' || *s == 'x') {
64             base = 16;
65             ++s;
66         }
67     }
68     sal_uInt64 val = 0;
69     for (; *s != 0; ++s) {
70         unsigned int n;
71         if (*s >= '0' && *s <= '9') {
72             n = *s - '0';
73         } else {
74             switch (*s) {
75             case 'A':
76             case 'a':
77                 n = 10;
78                 break;
79             case 'B':
80             case 'b':
81                 n = 11;
82                 break;
83             case 'C':
84             case 'c':
85                 n = 12;
86                 break;
87             case 'D':
88             case 'd':
89                 n = 13;
90                 break;
91             case 'E':
92             case 'e':
93                 n = 14;
94                 break;
95             case 'F':
96             case 'f':
97                 n = 15;
98                 break;
99             default:
100                 goto done;
101             }
102         }
103         // The following guarantees the invariant val <= SAL_MAX_UINT64 (because
104         // base and n are sufficiently small), *if*
105         // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64:
106         sal_uInt64 nval = val * base + n;
107         if (nval < val) {
108             ErrorHandler::syntaxError(
109                 PS_NoState, idlc()->getLineNumber(),
110                 "integral constant too large");
111             val = 0;
112             break;
113         }
114         val = nval;
115     }
116  done:
117     if (neg) {
118         if (val < SAL_CONST_UINT64(0x8000000000000000)) {
119             *sval = -static_cast< sal_Int64 >(val);
120         } else if (val == SAL_CONST_UINT64(0x8000000000000000)) {
121             *sval = SAL_MIN_INT64;
122         } else {
123             ErrorHandler::syntaxError(
124                 PS_NoState, idlc()->getLineNumber(),
125                 "negative integral constant too large");
126             *sval = 0;
127         }
128         return IDL_INTEGER_LITERAL;
129     } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) {
130         *sval = static_cast< sal_Int64 >(val);
131         return IDL_INTEGER_LITERAL;
132     } else {
133         *uval = val;
134         return IDL_INTEGER_ULITERAL;
135     }
138 static double asciiToFloat(const sal_Char *s)
140         double          d = 0.0;
141         double          e, k;
142         sal_Int32       neg = 0;
144         if (*s == '-')
145         {
146         neg = 1;
147         s++;
148         }
149         while (*s >= '0' && *s <= '9')
150         {
151         d = (d * 10) + *s - '0';
152         s++;
153         }
154         if (*s == '.')
155         {
156         s++;
157         e = 10;
158         while (*s >= '0' && *s <= '9')
159         {
160                 d += (*s - '0') / (e * 1.0);
161                 e *= 10;
162                 s++;
163         }
164         }
165         if (*s == 'e' || *s == 'E')
166         {
167         s++;
168         if (*s == '-')
169         {
170                 s++;
171         } else
172         {
173                 if (*s == '+')
174                 s++;
175                 e = 0;
176                 while (*s >= '0' && *s <= '9')
177                 {
178                 e = (e * 10) + *s - '0';
179                 s++;
180                 }
181                 if (e > 0)
182                 {
183                 for (k = 1; e > 0; k *= 10, e--)
184                     ;
185                 d /= k;
186                 }
187                 }
188         }
189         if (neg) d *= -1.0;
190         return d;
193 static void     idlParsePragma(sal_Char* pPragma)
195         ::rtl::OString pragma(pPragma);
196         sal_Int32 index = pragma.indexOf("include");
197         sal_Char* begin = pPragma + index + 8;
198         sal_Char* offset = begin;
199         while (*offset != ',') offset++;
200         //::rtl::OString include = pragma.copy(index + 8, offset - begin);
201         //unused// idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin)));
202 }       
204 static void parseLineAndFile(sal_Char* pBuf)
206         sal_Char        *r = pBuf;
207         sal_Char    *h;
208         bool    bIsInMain = false;
210         /* Skip initial '#' */
211         if (*r != '#')
212                 return;
214         /* Find line number */
215         for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ;
216         h = r;
217         for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ;
218         *r++ = 0;
219         idlc()->setLineNumber((sal_uInt32)atol(h));
220     yylineno = atol(h);
222         /* Find file name, if present */
223         for (; *r != '"'; r++)
224         {
225                 if (*r == '\n' || *r == '\0')
226                         return;
227         }
228         h = ++r;
229         for (; *r != '"'; r++) ;
230         *r = 0;
231         if (*h == '\0')
232                 idlc()->setFileName(::rtl::OString("standard input"));
233         else
234                 idlc()->setFileName(::rtl::OString(h));
236         bIsInMain = idlc()->getFileName() == idlc()->getRealFileName();
237         idlc()->setInMainfile(bIsInMain);               
238 }       
240 // Suppress any warnings from generated code:
241 #ifdef __GNUC__
242 #pragma GCC diagnostic ignored "-Wunused-function"
243 #pragma GCC diagnostic ignored "-Wunused-label"
244 #elif defined _MSC_VER
245 #pragma warning(push, 1)
246 /**/
247 #ifdef yywrap
248 #undef  yywrap
249 #define yywrap() 1
250 #endif
251 /**/
252 #endif
253 #define YY_NO_UNISTD_H
256 %option noyywrap
257 %option never-interactive
259 %x DOCU
260 %x COMMENT
262 DIGIT           [0-9]
263 OCT_DIGIT       [0-7]
264 HEX_DIGIT       [a-fA-F0-9]
265 CAPITAL         [A-Z]
266 ALPHA           [a-zA-Z]
267 INT_LITERAL     [1-9][0-9]*
268 OCT_LITERAL     0{OCT_DIGIT}*
269 HEX_LITERAL     (0x|0X){HEX_DIGIT}*
271 IDENTIFIER_NEW  ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
272 IDENTIFIER      ("_"?({ALPHA}|{DIGIT})+)*
276 [ \t\r]+        ; /* eat up whitespace */
277 [\n]           {
278        idlc()->incLineNumber();
279        yycolumn = 1;
280        yylineno++;
283 attribute       return IDL_ATTRIBUTE;
284 bound           return IDL_BOUND;
285 const           return IDL_CONST;
286 constants       return IDL_CONSTANTS;
287 constrained     return IDL_CONSTRAINED;
288 enum            return IDL_ENUM;
289 exception       return IDL_EXCEPTION;
290 interface       return IDL_INTERFACE;
291 maybeambiguous  return IDL_MAYBEAMBIGUOUS;
292 maybedefault    return IDL_MAYBEDEFAULT;
293 maybevoid       return IDL_MAYBEVOID;
294 module          return IDL_MODULE;
295 needs           return IDL_NEEDS;
296 observes        return IDL_OBSERVES;
297 optional        return IDL_OPTIONAL;
298 property        return IDL_PROPERTY;
299 raises          return IDL_RAISES;
300 readonly        return IDL_READONLY;
301 removable       return IDL_REMOVABLE;
302 service         return IDL_SERVICE;
303 sequence        return IDL_SEQUENCE;
304 singleton       return IDL_SINGLETON;
305 struct          return IDL_STRUCT;
306 transient       return IDL_TRANSIENT;
307 typedef         return IDL_TYPEDEF;
309 any             return IDL_ANY;                         
310 boolean         return IDL_BOOLEAN;
311 byte            return IDL_BYTE;
312 char            return IDL_CHAR;
313 double          return IDL_DOUBLE;
314 float           return IDL_FLOAT;
315 hyper           return IDL_HYPER;
316 long            return IDL_LONG;
317 short           return IDL_SHORT;
318 string          return IDL_STRING;
319 type            return IDL_TYPE;
320 unsigned        return IDL_UNSIGNED;
321 void            return IDL_VOID;
323 TRUE            return IDL_TRUE;
324 True            return IDL_TRUE;
325 FALSE           return IDL_FALSE;
326 False           return IDL_FALSE;
328 in              return IDL_IN;
329 out             return IDL_OUT;
330 inout           return IDL_INOUT;
332 get             return IDL_GET;
333 set             return IDL_SET;
335 published       return IDL_PUBLISHED;
337 "..."           return IDL_ELLIPSIS;
339 ("-")?{INT_LITERAL}+(l|L|u|U)?    {
340                 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
341             }
343 ("-")?{OCT_LITERAL}+(l|L|u|U)?    {
344                 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
345             }
347 ("-")?{HEX_LITERAL}+(l|L|u|U)?    {
348                 return asciiToInteger(yytext, &yylval.ival, &yylval.uval);
349             }
351 ("-")?{DIGIT}+(e|E)(("+"|"-")?{DIGIT}+)?(f|F)?  |
352 ("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)?        {
353                 yylval.dval = asciiToFloat( yytext );
354                                 return IDL_FLOATING_PT_LITERAL;
355             }
357 {IDENTIFIER}    {
358                                 yylval.sval = new ::rtl::OString(yytext);
359                                 return IDL_IDENTIFIER;
360                         }
362 \<\<    {
363                 yylval.strval = yytext;
364                 return IDL_LEFTSHIFT;
365         }
366 \>\>    {
367                 yylval.strval = yytext;
368                 return IDL_RIGHTSHIFT;
369         }
370 \:\:    {
371                 yylval.strval = yytext;
372                 return IDL_SCOPESEPARATOR;
373         }
375 "/*"    { 
376                         BEGIN( COMMENT );
377                         docu = ::rtl::OString();
378                         beginLine = idlc()->getLineNumber();
379                 }
381 "/***"  { 
382                         BEGIN( COMMENT );
383                         docu = ::rtl::OString();
384                         beginLine = idlc()->getLineNumber();
385                 }
387 <COMMENT>[^*]+  {
388                                 docu += ::rtl::OString(yytext);
389                         } 
391 <COMMENT>"*"[^*/]+      {
392                                 docu += ::rtl::OString(yytext);
393                         }
395 <COMMENT>"**"   {
396                                 docu += ::rtl::OString(yytext);
397                         }
399 <COMMENT>[*]+"/"  {
400                                 docu = docu.trim();
401                 sal_Int32 nIndex = 0;
402                 int count = 0;
403                 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
404                                 idlc()->setLineNumber( beginLine + count - 1);
405                                 BEGIN( INITIAL );
406                         }
408 "/**"   {
409                         BEGIN( DOCU );
410                         docu = ::rtl::OString();
411                         beginLine = idlc()->getLineNumber();
412                 }
414 <DOCU>[^*\n]+   {
415                                 docu += ::rtl::OString(yytext);
416                         }
418 <DOCU>"\n"[ \t]*"*"{1}  {
419                                 idlc()->setLineNumber( idlc()->getLineNumber()  + 1);
420                                 docu += ::rtl::OString("\n");
421                         }
423 <DOCU>"\n"      {
424                                 idlc()->setLineNumber( idlc()->getLineNumber()  + 1);
425                                 docu += ::rtl::OString(yytext);
426                         }
428 <DOCU>"*"[^*^/\n]*      {
429                                 docu += ::rtl::OString(yytext);
430                         }
432 <DOCU>"\n"[ \t]*"*/"    {
433                                 docu = docu.trim();
434                                 sal_Int32 nIndex = 0;
435                                 int count = 0;
436                                 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
437                                 idlc()->setLineNumber( beginLine + count - 1);                
438                                 if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 )
439                                 {
440                     if ( 0 != nIndex &&
441                          (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
442                         ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
443                                                      "nested documentation strings are not allowed!");
444                                 }
445                                 idlc()->setDocumentation(docu);
446                                 BEGIN( INITIAL );
447                         }
449 <DOCU>"*/"      {
450                                 docu = docu.trim();
451                                 sal_Int32 nIndex = 0;
452                                 int count = 0;
453                                 do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 );
454                                 idlc()->setLineNumber( beginLine + count - 1);
455                                 if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 )
456                                 {
457                     if ( 0 != nIndex &&
458                          (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') )
459                         ErrorHandler::syntaxError(PS_NoState, idlc()->getLineNumber(),
460                                                      "nested documentation strings are not allowed!");
461                                 }
462                                 idlc()->setDocumentation(docu);
463                                 BEGIN( INITIAL );
464                         }
466 "//"[^/]{1}.*"\n" {
467                                 /* only a comment */
468                                 ::rtl::OString docStr(yytext);
469                                 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
470                                 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
471                                 docStr = docStr.trim();
472                                 idlc()->incLineNumber();
473                         }
475 "///".*"\n"  {
476                                 ::rtl::OString docStr(yytext);
477                                 docStr = docStr.copy( 0, docStr.lastIndexOf('\n') );
478                                 docStr = docStr.copy( docStr.lastIndexOf('/')+1 );
479                                 docStr = docStr.trim();
480                                 idlc()->incLineNumber();
481                                 idlc()->setDocumentation(docStr);
482                         }
484 .       return yytext[0];
486 ^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n    {
487         parseLineAndFile(yytext);
490 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n {
491         parseLineAndFile(yytext);
494 ^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n {
495         parseLineAndFile(yytext);
498 ^#[ \t]*[0-9]*\n {
499         parseLineAndFile(yytext);
502 ^#[ \t]*ident.*\n {
503         /* ignore cpp ident */
504         idlc()->incLineNumber();
507 ^#[ \t]*pragma[ \t].*\n        {       /* remember pragma */
508         idlParsePragma(yytext);
509         idlc()->incLineNumber();