~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* */
2
 
/*Copyright (C) 2002-2005  3Dlabs Inc. Ltd. */
3
 
/*All rights reserved. */
4
 
/* */
5
 
/*Redistribution and use in source and binary forms, with or without */
6
 
/*modification, are permitted provided that the following conditions */
7
 
/*are met: */
8
 
/* */
9
 
/*    Redistributions of source code must retain the above copyright */
10
 
/*    notice, this list of conditions and the following disclaimer. */
11
 
/* */
12
 
/*    Redistributions in binary form must reproduce the above */
13
 
/*    copyright notice, this list of conditions and the following */
14
 
/*    disclaimer in the documentation and/or other materials provided */
15
 
/*    with the distribution. */
16
 
/* */
17
 
/*    Neither the name of 3Dlabs Inc. Ltd. nor the names of its */
18
 
/*    contributors may be used to endorse or promote products derived */
19
 
/*    from this software without specific prior written permission. */
20
 
/* */
21
 
/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
22
 
/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
23
 
/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
24
 
/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
25
 
/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
26
 
/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
27
 
/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
28
 
/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
29
 
/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
30
 
/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
31
 
/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
32
 
/*POSSIBILITY OF SUCH DAMAGE. */
33
 
/* */
34
 
/****************************************************************************\
35
 
Copyright (c) 2002, NVIDIA Corporation.
36
 
 
37
 
NVIDIA Corporation("NVIDIA") supplies this software to you in
38
 
consideration of your agreement to the following terms, and your use,
39
 
installation, modification or redistribution of this NVIDIA software
40
 
constitutes acceptance of these terms.  If you do not agree with these
41
 
terms, please do not use, install, modify or redistribute this NVIDIA
42
 
software.
43
 
 
44
 
In consideration of your agreement to abide by the following terms, and
45
 
subject to these terms, NVIDIA grants you a personal, non-exclusive
46
 
license, under NVIDIA's copyrights in this original NVIDIA software (the
47
 
"NVIDIA Software"), to use, reproduce, modify and redistribute the
48
 
NVIDIA Software, with or without modifications, in source and/or binary
49
 
forms; provided that if you redistribute the NVIDIA Software, you must
50
 
retain the copyright notice of NVIDIA, this notice and the following
51
 
text and disclaimers in all such redistributions of the NVIDIA Software.
52
 
Neither the name, trademarks, service marks nor logos of NVIDIA
53
 
Corporation may be used to endorse or promote products derived from the
54
 
NVIDIA Software without specific prior written permission from NVIDIA.
55
 
Except as expressly stated in this notice, no other rights or licenses
56
 
express or implied, are granted by NVIDIA herein, including but not
57
 
limited to any patent rights that may be infringed by your derivative
58
 
works or by other works in which the NVIDIA Software may be
59
 
incorporated. No hardware is licensed hereunder. 
60
 
 
61
 
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
62
 
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
63
 
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
64
 
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
65
 
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
66
 
PRODUCTS.
67
 
 
68
 
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
69
 
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
70
 
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
71
 
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
72
 
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
73
 
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
74
 
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
75
 
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76
 
\****************************************************************************/
77
 
/* */
78
 
/* scanner.c */
79
 
/* */
80
 
 
81
 
#include <stdarg.h>
82
 
#include <stdio.h>
83
 
#include <stdlib.h>
84
 
#include <string.h>
85
 
 
86
 
#if 0
87
 
    #include <ieeefp.h>
88
 
    #else
89
 
    #define isinff(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
90
 
                       ((*(long *)&(x) & 0x007fffffL)==0000000000L))
91
 
#endif
92
 
 
93
 
#include "slglobals.h"
94
 
 
95
 
 
96
 
typedef struct StringInputSrc {
97
 
    InputSrc base;
98
 
    char *p;
99
 
} StringInputSrc;
100
 
 
101
 
static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
102
 
{
103
 
    return EOF;
104
 
} /* eof_scan */
105
 
 
106
 
static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
107
 
 
108
 
static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
109
 
 
110
 
static int byte_scan(InputSrc *, yystypepp * yylvalpp);
111
 
 
112
 
#define EOL_SY '\n'
113
 
 
114
 
#if defined(_WIN32)
115
 
    #define DBG_BREAKPOINT() __asm int 3
116
 
    #elif defined(_M_AMD64)
117
 
    #define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
118
 
    #else
119
 
    #define DBG_BREAKPOINT()
120
 
    #endif
121
 
 
122
 
    #if defined(_WIN32) && !defined(_M_AMD64)
123
 
    __int64 RDTSC ( void ) {
124
 
 
125
 
        __int64 v;
126
 
    
127
 
        __asm __emit 0x0f
128
 
        __asm __emit 0x31
129
 
        __asm mov dword ptr v, eax
130
 
        __asm mov dword ptr v+4, edx
131
 
    
132
 
        return v;
133
 
    }
134
 
#endif
135
 
 
136
 
 
137
 
int InitScanner(CPPStruct *cpp)
138
 
{
139
 
    /* Add various atoms needed by the CPP line scanner: */
140
 
    if (!InitCPP())
141
 
        return 0;
142
 
 
143
 
    cpp->mostRecentToken = 0;
144
 
    cpp->tokenLoc = &cpp->ltokenLoc;
145
 
 
146
 
    cpp->ltokenLoc.file = 0;
147
 
    cpp->ltokenLoc.line = 0;
148
 
 
149
 
    cpp->currentInput = &eof_inputsrc;
150
 
    cpp->previous_token = '\n';
151
 
    cpp->notAVersionToken = 0;
152
 
 
153
 
    return 1;
154
 
} /* InitScanner */
155
 
 
156
 
int FreeScanner(void)
157
 
{
158
 
    return (FreeCPP());
159
 
}
160
 
 
161
 
/*
162
 
 * str_getch()
163
 
 * takes care of reading from multiple strings.
164
 
 * returns the next-char from the input stream.
165
 
 * returns EOF when the complete shader is parsed.
166
 
 */
167
 
static int str_getch(StringInputSrc *in)
168
 
{
169
 
        for(;;){
170
 
           if (*in->p){
171
 
              if (*in->p == '\n') {
172
 
             in->base.line++;
173
 
             IncLineNumber();
174
 
          }
175
 
          return *in->p++;
176
 
           }
177
 
           if(++(cpp->PaWhichStr) < cpp->PaArgc){
178
 
                  free(in);
179
 
                  SetStringNumber(cpp->PaWhichStr);
180
 
          SetLineNumber(1);
181
 
                  ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
182
 
                  in=(StringInputSrc*)cpp->currentInput;
183
 
              continue;             
184
 
           }
185
 
           else{
186
 
              cpp->currentInput = in->base.prev;
187
 
              cpp->PaWhichStr=0;
188
 
          free(in);
189
 
          return EOF;
190
 
       }  
191
 
        }
192
 
} /* str_getch */
193
 
 
194
 
static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
195
 
    if (in->p[-1] == ch)in->p--;
196
 
        else {
197
 
                *(in->p)='\0'; /*this would take care of shifting to the previous string. */
198
 
            cpp->PaWhichStr--;
199
 
        }  
200
 
        if (ch == '\n') {
201
 
        in->base.line--;
202
 
        DecLineNumber();
203
 
    }
204
 
} /* str_ungetch */
205
 
 
206
 
int ScanFromString(char *s)
207
 
{
208
 
    
209
 
        StringInputSrc *in = malloc(sizeof(StringInputSrc));
210
 
    memset(in, 0, sizeof(StringInputSrc));
211
 
        in->p = s;
212
 
    in->base.line = 1;
213
 
    in->base.scan = byte_scan;
214
 
    in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
215
 
    in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
216
 
    in->base.prev = cpp->currentInput;
217
 
    cpp->currentInput = &in->base;
218
 
 
219
 
    return 1;
220
 
} /* ScanFromString; */
221
 
 
222
 
 
223
 
/*///////////////////////////////////////////////////////////////////////////////////////////// */
224
 
/*///////////////////////////////// Floating point constants: ///////////////////////////////// */
225
 
/*///////////////////////////////////////////////////////////////////////////////////////////// */
226
 
/*
227
 
 * lBuildFloatValue() - Quick and dirty conversion to floating point.  Since all
228
 
 *         we need is single precision this should be quite precise.
229
 
 */
230
 
 
231
 
static float lBuildFloatValue(const char *str, int len, int exp)
232
 
{
233
 
    double val, expval, ten;
234
 
    int ii, llen, absexp;
235
 
    float rv;
236
 
 
237
 
    val = 0.0;
238
 
    llen = len;
239
 
    for (ii = 0; ii < len; ii++)
240
 
        val = val*10.0 + (str[ii] - '0');
241
 
    if (exp != 0) {
242
 
        absexp = exp > 0 ? exp : -exp;
243
 
        expval = 1.0f;
244
 
        ten = 10.0;
245
 
        while (absexp) {
246
 
            if (absexp & 1)
247
 
                expval *= ten;
248
 
            ten *= ten;
249
 
            absexp >>= 1;
250
 
        }
251
 
        if (exp >= 0) {
252
 
            val *= expval;
253
 
        } else {
254
 
            val /= expval;
255
 
        }
256
 
    }
257
 
    rv = (float)val;
258
 
    if (isinff(rv)) {
259
 
                CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW");
260
 
    }
261
 
    return rv;
262
 
} /* lBuildFloatValue */
263
 
 
264
 
 
265
 
/*
266
 
 * lFloatConst() - Scan a floating point constant.  Assumes that the scanner
267
 
 *         has seen at least one digit, followed by either a decimal '.' or the
268
 
 *         letter 'e'.
269
 
 */
270
 
 
271
 
static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
272
 
{
273
 
    int HasDecimal, declen, exp, ExpSign;
274
 
    int str_len;
275
 
    float lval;
276
 
    
277
 
    HasDecimal = 0;
278
 
    declen = 0;
279
 
    exp = 0;
280
 
        
281
 
    str_len=len;
282
 
    if (ch == '.') {
283
 
                str[len++]=ch;
284
 
        HasDecimal = 1;
285
 
        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
286
 
        while (ch >= '0' && ch <= '9') {
287
 
            if (len < MAX_SYMBOL_NAME_LEN) {
288
 
                declen++;
289
 
                if (len > 0 || ch != '0') {
290
 
                    str[len] = ch;
291
 
                    len++;str_len++;
292
 
                }
293
 
                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
294
 
            } else {
295
 
                CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
296
 
                len = 1,str_len=1;
297
 
            }
298
 
        }
299
 
    }
300
 
 
301
 
    /* Exponent: */
302
 
 
303
 
    if (ch == 'e' || ch == 'E') {
304
 
        ExpSign = 1;
305
 
                str[len++]=ch;
306
 
        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
307
 
        if (ch == '+') {
308
 
            str[len++]=ch;  
309
 
                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
310
 
        } else if (ch == '-') {
311
 
            ExpSign = -1;
312
 
                        str[len++]=ch;
313
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
314
 
        }
315
 
        if (ch >= '0' && ch <= '9') {
316
 
            while (ch >= '0' && ch <= '9') {
317
 
                exp = exp*10 + ch - '0';
318
 
                                str[len++]=ch;
319
 
                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
320
 
            }
321
 
        } else {
322
 
            CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
323
 
        }
324
 
        exp *= ExpSign;
325
 
    }
326
 
      
327
 
    if (len == 0) {
328
 
        lval = 0.0f;
329
 
                strcpy(str,"0.0");
330
 
    } else {
331
 
        str[len]='\0';      
332
 
        lval = lBuildFloatValue(str, str_len, exp - declen);
333
 
    }
334
 
    /* Suffix: */
335
 
    
336
 
    yylvalpp->sc_fval = lval;
337
 
    strcpy(yylvalpp->symbol_name,str);
338
 
    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);            
339
 
    return CPP_FLOATCONSTANT;
340
 
} /* lFloatConst */
341
 
 
342
 
/*///////////////////////////////////////////////////////////////////////////////////////////// */
343
 
/*/////////////////////////////////////// Normal Scanner ////////////////////////////////////// */
344
 
/*///////////////////////////////////////////////////////////////////////////////////////////// */
345
 
    
346
 
static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
347
 
{
348
 
    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
349
 
    char string_val[MAX_STRING_LEN + 1];
350
 
    int AlreadyComplained;
351
 
    int len, ch, ii, ival = 0;
352
 
 
353
 
    for (;;) {
354
 
        yylvalpp->sc_int = 0;
355
 
        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
356
 
                
357
 
        while (ch == ' ' || ch == '\t' || ch == '\r') {
358
 
            yylvalpp->sc_int = 1;
359
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
360
 
        }
361
 
                
362
 
        cpp->ltokenLoc.file = cpp->currentInput->name;
363
 
        cpp->ltokenLoc.line = cpp->currentInput->line;
364
 
        len = 0;
365
 
        switch (ch) {
366
 
        default:
367
 
                        return ch; /* Single character token */
368
 
        case EOF:
369
 
            return -1;
370
 
                case 'A': case 'B': case 'C': case 'D': case 'E':
371
 
        case 'F': case 'G': case 'H': case 'I': case 'J':
372
 
        case 'K': case 'L': case 'M': case 'N': case 'O':
373
 
        case 'P': case 'Q': case 'R': case 'S': case 'T':
374
 
        case 'U': case 'V': case 'W': case 'X': case 'Y':
375
 
        case 'Z': case '_':
376
 
        case 'a': case 'b': case 'c': case 'd': case 'e':
377
 
        case 'f': case 'g': case 'h': case 'i': case 'j':
378
 
        case 'k': case 'l': case 'm': case 'n': case 'o':
379
 
        case 'p': case 'q': case 'r': case 's': case 't':
380
 
        case 'u': case 'v': case 'w': case 'x': case 'y':
381
 
        case 'z':            
382
 
            do {
383
 
                if (len < MAX_SYMBOL_NAME_LEN) {
384
 
                    symbol_name[len] = ch;
385
 
                    len++;
386
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
387
 
                } else {
388
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
389
 
                }
390
 
            } while ((ch >= 'a' && ch <= 'z') ||
391
 
                     (ch >= 'A' && ch <= 'Z') ||
392
 
                     (ch >= '0' && ch <= '9') ||
393
 
                     ch == '_');
394
 
            if (len >= MAX_SYMBOL_NAME_LEN)
395
 
                len = MAX_SYMBOL_NAME_LEN - 1;
396
 
            symbol_name[len] = '\0';
397
 
            cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
398
 
            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
399
 
            return CPP_IDENTIFIER;
400
 
            break;
401
 
        case '0':
402
 
            yylvalpp->symbol_name[len++] = ch;
403
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
404
 
            if (ch == 'x' || ch == 'X') {
405
 
                                yylvalpp->symbol_name[len++] = ch;
406
 
                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
407
 
                if ((ch >= '0' && ch <= '9') ||
408
 
                    (ch >= 'A' && ch <= 'F') ||
409
 
                    (ch >= 'a' && ch <= 'f'))
410
 
                {
411
 
                    AlreadyComplained = 0;
412
 
                    ival = 0;
413
 
                    do {
414
 
                                                yylvalpp->symbol_name[len++] = ch;
415
 
                        if (ival <= 0x0fffffff) {
416
 
                            if (ch >= '0' && ch <= '9') {
417
 
                                ii = ch - '0';
418
 
                            } else if (ch >= 'A' && ch <= 'F') {
419
 
                                ii = ch - 'A' + 10;
420
 
                            } else {
421
 
                                ii = ch - 'a' + 10;
422
 
                            }
423
 
                            ival = (ival << 4) | ii;
424
 
                        } else {
425
 
                            if (!AlreadyComplained)
426
 
                                CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
427
 
                            AlreadyComplained = 1;
428
 
                        }
429
 
                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
430
 
                    } while ((ch >= '0' && ch <= '9') ||
431
 
                             (ch >= 'A' && ch <= 'F') ||
432
 
                             (ch >= 'a' && ch <= 'f'));
433
 
                } else {
434
 
                    CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
435
 
                }
436
 
                yylvalpp->symbol_name[len] = '\0';
437
 
                                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
438
 
                                yylvalpp->sc_int = ival;
439
 
                return CPP_INTCONSTANT;
440
 
            } else if (ch >= '0' && ch <= '7') { /* octal integer constants */
441
 
                AlreadyComplained = 0;
442
 
                ival = 0;
443
 
                do {
444
 
                    yylvalpp->symbol_name[len++] = ch;
445
 
                    if (ival <= 0x1fffffff) {
446
 
                        ii = ch - '0';
447
 
                        ival = (ival << 3) | ii;
448
 
                    } else {
449
 
                        if (!AlreadyComplained)
450
 
                           CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
451
 
                        AlreadyComplained = 1;
452
 
                    }
453
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
454
 
                } while (ch >= '0' && ch <= '7');
455
 
                if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') 
456
 
                     return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
457
 
                yylvalpp->symbol_name[len] = '\0';
458
 
                                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
459
 
                                yylvalpp->sc_int = ival;
460
 
                return CPP_INTCONSTANT;
461
 
            } else {
462
 
                                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
463
 
                                ch = '0';
464
 
            }
465
 
            /* Fall through... */
466
 
        case '1': case '2': case '3': case '4':
467
 
        case '5': case '6': case '7': case '8': case '9':
468
 
            do {
469
 
                if (len < MAX_SYMBOL_NAME_LEN) {
470
 
                    if (len > 0 || ch != '0') {
471
 
                        yylvalpp->symbol_name[len] = ch;
472
 
                   len++;
473
 
                    }
474
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
475
 
                }
476
 
            } while (ch >= '0' && ch <= '9');
477
 
            if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
478
 
                return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
479
 
            } else {
480
 
                yylvalpp->symbol_name[len] = '\0';
481
 
                                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
482
 
                ival = 0;
483
 
                AlreadyComplained = 0;
484
 
                for (ii = 0; ii < len; ii++) {
485
 
                    ch = yylvalpp->symbol_name[ii] - '0';
486
 
                    if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
487
 
                        if (!AlreadyComplained)
488
 
                           CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
489
 
                        AlreadyComplained = 1;
490
 
                    }
491
 
                    ival = ival*10 + ch;
492
 
                }
493
 
                yylvalpp->sc_int = ival;
494
 
                if(ival==0)
495
 
                   strcpy(yylvalpp->symbol_name,"0");
496
 
                return CPP_INTCONSTANT;
497
 
            }
498
 
            break;
499
 
        case '-':
500
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
501
 
            if (ch == '-') {
502
 
                return CPP_DEC_OP;
503
 
            } else if (ch == '=') {
504
 
                return CPP_SUB_ASSIGN;
505
 
            } else {
506
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
507
 
                return '-';
508
 
            }
509
 
        case '+':
510
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
511
 
            if (ch == '+') {
512
 
                return CPP_INC_OP;
513
 
            } else if (ch == '=') {
514
 
                return CPP_ADD_ASSIGN;
515
 
            } else {
516
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
517
 
                return '+';
518
 
            }
519
 
        case '*':
520
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
521
 
            if (ch == '=') {
522
 
                return CPP_MUL_ASSIGN;
523
 
            } else {
524
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
525
 
                return '*';
526
 
            }
527
 
        case '%':
528
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
529
 
            if (ch == '=') {
530
 
                return CPP_MOD_ASSIGN;
531
 
            } else if (ch == '>'){
532
 
                return CPP_RIGHT_BRACE;
533
 
            } else {
534
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
535
 
                return '%';
536
 
            }
537
 
        case ':':
538
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
539
 
            if (ch == '>') {
540
 
                return CPP_RIGHT_BRACKET;
541
 
            } else {
542
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
543
 
                return ':';
544
 
            }
545
 
        case '^':
546
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
547
 
            if (ch == '^') {
548
 
                return CPP_XOR_OP;
549
 
            } else {
550
 
                if (ch == '=')
551
 
                    return CPP_XOR_ASSIGN;
552
 
                else{
553
 
                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
554
 
                  return '^';
555
 
                }
556
 
            }
557
 
        
558
 
        case '=':
559
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
560
 
            if (ch == '=') {
561
 
                return CPP_EQ_OP;
562
 
            } else {
563
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
564
 
                return '=';
565
 
            }
566
 
        case '!':
567
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
568
 
            if (ch == '=') {
569
 
                return CPP_NE_OP;
570
 
            } else {
571
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
572
 
                return '!';
573
 
            }
574
 
        case '|':
575
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
576
 
            if (ch == '|') {
577
 
                return CPP_OR_OP;
578
 
            } else {
579
 
                if (ch == '=')
580
 
                    return CPP_OR_ASSIGN;
581
 
                else{
582
 
                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
583
 
                  return '|';
584
 
                }
585
 
            }
586
 
        case '&':
587
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
588
 
            if (ch == '&') {
589
 
                return CPP_AND_OP;
590
 
            } else {
591
 
                if (ch == '=')
592
 
                    return CPP_AND_ASSIGN;
593
 
                else{
594
 
                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
595
 
                  return '&';
596
 
                }
597
 
            }
598
 
        case '<':
599
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
600
 
            if (ch == '<') {
601
 
                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
602
 
                if(ch == '=')
603
 
                    return CPP_LEFT_ASSIGN;
604
 
                else{
605
 
                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
606
 
                    return CPP_LEFT_OP;
607
 
                }
608
 
            } else {
609
 
                if (ch == '=') {
610
 
                    return CPP_LE_OP;
611
 
                } else {
612
 
                    if (ch == '%')
613
 
                        return CPP_LEFT_BRACE;
614
 
                    else if (ch == ':')
615
 
                        return CPP_LEFT_BRACKET;
616
 
                    else{
617
 
                        cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
618
 
                        return '<';
619
 
                    }
620
 
                }
621
 
            }
622
 
        case '>':
623
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
624
 
            if (ch == '>') {
625
 
                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
626
 
                if(ch == '=')
627
 
                    return CPP_RIGHT_ASSIGN;
628
 
                else{
629
 
                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
630
 
                    return CPP_RIGHT_OP;
631
 
                }
632
 
            } else {
633
 
                if (ch == '=') {
634
 
                    return CPP_GE_OP;
635
 
                } else {
636
 
                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
637
 
                    return '>';
638
 
                }
639
 
            }
640
 
        case '.':
641
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
642
 
            if (ch >= '0' && ch <= '9') {
643
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
644
 
                return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
645
 
            } else {
646
 
                if (ch == '.') {
647
 
                    return -1; /* Special EOF hack */
648
 
                } else {
649
 
                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
650
 
                    return '.';
651
 
                }
652
 
            }
653
 
        case '/':
654
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
655
 
            if (ch == '/') {
656
 
                do {
657
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
658
 
                } while (ch != '\n' && ch != EOF);
659
 
                if (ch == EOF)
660
 
                    return -1;
661
 
                return '\n';
662
 
            } else if (ch == '*') {
663
 
                int nlcount = 0;
664
 
                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
665
 
                do {
666
 
                    while (ch != '*') {
667
 
                        if (ch == '\n') nlcount++;
668
 
                        if (ch == EOF) {
669
 
                            CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
670
 
                            return -1;
671
 
                        }
672
 
                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
673
 
                    }
674
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
675
 
                    if (ch == EOF) {
676
 
                        CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
677
 
                        return -1;
678
 
                    }
679
 
                } while (ch != '/');
680
 
                if (nlcount) {
681
 
                    return '\n';
682
 
                }
683
 
                /* Go try it again... */
684
 
            } else if (ch == '=') {
685
 
                return CPP_DIV_ASSIGN;
686
 
            } else {
687
 
                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
688
 
                return '/';
689
 
            }
690
 
            break;
691
 
        case '"':
692
 
            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
693
 
            while (ch != '"' && ch != '\n' && ch != EOF) {
694
 
                if (ch == '\\') {
695
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
696
 
                    if (ch == '\n' || ch == EOF) {
697
 
                        break;
698
 
                    }
699
 
                }
700
 
                if (len < MAX_STRING_LEN) {
701
 
                    string_val[len] = ch;
702
 
                    len++;
703
 
                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
704
 
                }
705
 
            };
706
 
            string_val[len] = '\0';
707
 
            if (ch == '"') {
708
 
                yylvalpp->sc_ident = LookUpAddString(atable, string_val);
709
 
                return CPP_STRCONSTANT;
710
 
            } else {
711
 
                CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
712
 
                return ERROR_SY;
713
 
            }
714
 
        }
715
 
    }
716
 
} /* byte_scan */
717
 
 
718
 
int yylex_CPP(char* buf, int maxSize)
719
 
{    
720
 
        yystypepp yylvalpp;
721
 
    int token = '\n';
722
 
 
723
 
    for(;;) {
724
 
                
725
 
        char* tokenString = 0;
726
 
        token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
727
 
                if(check_EOF(token))
728
 
                   return 0;
729
 
                if (token == '#' && (cpp->previous_token == '\n'||cpp->previous_token==0)) {
730
 
                        token = readCPPline(&yylvalpp);
731
 
            if(check_EOF(token))
732
 
                return 0;
733
 
                        continue;
734
 
                }
735
 
        cpp->previous_token = token;
736
 
        /* expand macros */
737
 
        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
738
 
            cpp->notAVersionToken = 1;
739
 
            continue;
740
 
        }
741
 
        
742
 
        if (token == '\n')
743
 
            continue;
744
 
  
745
 
        if (token == CPP_IDENTIFIER) {
746
 
            cpp->notAVersionToken = 1;
747
 
            tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
748
 
        } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){ 
749
 
            cpp->notAVersionToken = 1;
750
 
            tokenString = yylvalpp.symbol_name;
751
 
                } else {
752
 
            cpp->notAVersionToken = 1;
753
 
            tokenString = GetStringOfAtom(atable,token);
754
 
            }
755
 
                 
756
 
        if (tokenString) {
757
 
            if ((signed)strlen(tokenString) >= maxSize) {
758
 
                cpp->tokensBeforeEOF = 1;
759
 
                return maxSize;
760
 
            } else  if (strlen(tokenString) > 0) {
761
 
                            strcpy(buf, tokenString);
762
 
                cpp->tokensBeforeEOF = 1;
763
 
                return (int)strlen(tokenString);
764
 
            }
765
 
 
766
 
            return 0;
767
 
        }
768
 
    }
769
 
 
770
 
    return 0;
771
 
} /* yylex */
772
 
 
773
 
/*Checks if the token just read is EOF or not. */
774
 
int check_EOF(int token)
775
 
{
776
 
   if(token==-1){
777
 
       if(cpp->ifdepth >0){
778
 
                CPPErrorToInfoLog("#endif missing!! Compilation stopped");
779
 
        cpp->CompileError=1;
780
 
       }
781
 
      return 1;
782
 
   }
783
 
   return 0;
784
 
}
785
 
 
786
 
/*///////////////////////////////////////////////////////////////////////////////////////////// */
787
 
/*///////////////////////////////////// End of scanner.c ////////////////////////////////////// */
788
 
/*///////////////////////////////////////////////////////////////////////////////////////////// */
789