00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include "system.h"
00029 #include "cpplib.h"
00030 #include "cpphash.h"
00031
00032 #ifdef MULTIBYTE_CHARS
00033 #include "mbchar.h"
00034 #include <locale.h>
00035 #endif
00036
00037 #ifdef SGI_MONGOOSE
00038
00039 #include "defaults.h"
00040 #endif
00041
00042
00043
00044 enum spell_type
00045 {
00046 SPELL_OPERATOR = 0,
00047 SPELL_CHAR,
00048 SPELL_IDENT,
00049 SPELL_NUMBER,
00050 SPELL_STRING,
00051 SPELL_NONE
00052 };
00053
00054 struct token_spelling
00055 {
00056 enum spell_type category;
00057 const unsigned char *name;
00058 };
00059
00060 static const unsigned char *const digraph_spellings[] =
00061 { U"%:", U"%:%:", U"<:", U":>", U"<%", U"%>" };
00062
00063 #define OP(e, s) { SPELL_OPERATOR, U s },
00064 #define TK(e, s) { s, U STRINGX (e) },
00065 static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE };
00066 #undef OP
00067 #undef TK
00068
00069 #define TOKEN_SPELL(token) (token_spellings[(token)->type].category)
00070 #define TOKEN_NAME(token) (token_spellings[(token)->type].name)
00071 #define BACKUP() do {buffer->cur = buffer->backup_to;} while (0)
00072
00073 static void handle_newline PARAMS ((cpp_reader *));
00074 static cppchar_t skip_escaped_newlines PARAMS ((cpp_reader *));
00075 static cppchar_t get_effective_char PARAMS ((cpp_reader *));
00076
00077 static int skip_block_comment PARAMS ((cpp_reader *));
00078 static int skip_line_comment PARAMS ((cpp_reader *));
00079 static void adjust_column PARAMS ((cpp_reader *));
00080 static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
00081 static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *));
00082 static uchar *parse_slow PARAMS ((cpp_reader *, const uchar *, int,
00083 unsigned int *));
00084 static void parse_number PARAMS ((cpp_reader *, cpp_string *, int));
00085 static int unescaped_terminator_p PARAMS ((cpp_reader *, const uchar *));
00086 static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
00087 static bool trigraph_p PARAMS ((cpp_reader *));
00088 static void save_comment PARAMS ((cpp_reader *, cpp_token *, const uchar *,
00089 cppchar_t));
00090 static bool continue_after_nul PARAMS ((cpp_reader *));
00091 static int name_p PARAMS ((cpp_reader *, const cpp_string *));
00092 static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **,
00093 const unsigned char *, cppchar_t *));
00094 static tokenrun *next_tokenrun PARAMS ((tokenrun *));
00095
00096 static unsigned int hex_digit_value PARAMS ((unsigned int));
00097 static _cpp_buff *new_buff PARAMS ((size_t));
00098
00099
00100
00101
00102
00103 int
00104 cpp_ideq (token, string)
00105 const cpp_token *token;
00106 const char *string;
00107 {
00108 if (token->type != CPP_NAME)
00109 return 0;
00110
00111 return !ustrcmp (NODE_NAME (token->val.node), (const uchar *) string);
00112 }
00113
00114 #ifdef KEY
00115 extern bool in_omp_pragma;
00116 bool seen_omp_paren = FALSE;
00117 #endif
00118
00119
00120
00121 static void
00122 handle_newline (pfile)
00123 cpp_reader *pfile;
00124 {
00125 cpp_buffer *buffer = pfile->buffer;
00126
00127
00128
00129 if (buffer->cur[-1] + buffer->cur[0] == '\r' + '\n')
00130 buffer->cur++;
00131
00132 buffer->line_base = buffer->cur;
00133 buffer->col_adjust = 0;
00134 pfile->line++;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 static bool
00144 trigraph_p (pfile)
00145 cpp_reader *pfile;
00146 {
00147 cpp_buffer *buffer = pfile->buffer;
00148 cppchar_t from_char = buffer->cur[1];
00149 bool accept;
00150
00151 if (!_cpp_trigraph_map[from_char])
00152 return false;
00153
00154 accept = CPP_OPTION (pfile, trigraphs);
00155
00156
00157 if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
00158 {
00159 if (accept)
00160 cpp_error_with_line (pfile, DL_WARNING,
00161 pfile->line, CPP_BUF_COL (buffer) - 1,
00162 "trigraph ??%c converted to %c",
00163 (int) from_char,
00164 (int) _cpp_trigraph_map[from_char]);
00165 else if (buffer->cur != buffer->last_Wtrigraphs)
00166 {
00167 buffer->last_Wtrigraphs = buffer->cur;
00168 cpp_error_with_line (pfile, DL_WARNING,
00169 pfile->line, CPP_BUF_COL (buffer) - 1,
00170 "trigraph ??%c ignored", (int) from_char);
00171 }
00172 }
00173
00174 return accept;
00175 }
00176
00177
00178
00179
00180
00181 static cppchar_t
00182 skip_escaped_newlines (pfile)
00183 cpp_reader *pfile;
00184 {
00185 cpp_buffer *buffer = pfile->buffer;
00186 cppchar_t next = buffer->cur[-1];
00187
00188
00189 if (!buffer->from_stage3)
00190 {
00191 const unsigned char *saved_cur;
00192 cppchar_t next1;
00193
00194 do
00195 {
00196 if (next == '?')
00197 {
00198 if (buffer->cur[0] != '?' || !trigraph_p (pfile))
00199 break;
00200
00201
00202 next = _cpp_trigraph_map[buffer->cur[1]];
00203 buffer->cur += 2;
00204 if (next != '\\')
00205 break;
00206 }
00207
00208 if (buffer->cur == buffer->rlimit)
00209 break;
00210
00211
00212
00213 saved_cur = buffer->cur;
00214 do
00215 next1 = *buffer->cur++;
00216 while (is_nvspace (next1) && buffer->cur < buffer->rlimit);
00217
00218 if (!is_vspace (next1))
00219 {
00220 buffer->cur = saved_cur;
00221 break;
00222 }
00223
00224 if (saved_cur != buffer->cur - 1
00225 && !pfile->state.lexing_comment)
00226 cpp_error (pfile, DL_WARNING,
00227 "backslash and newline separated by space");
00228
00229 handle_newline (pfile);
00230 buffer->backup_to = buffer->cur;
00231 if (buffer->cur == buffer->rlimit)
00232 {
00233 cpp_error (pfile, DL_PEDWARN,
00234 "backslash-newline at end of file");
00235 next = EOF;
00236 }
00237 else
00238 next = *buffer->cur++;
00239 }
00240 while (next == '\\' || next == '?');
00241 }
00242
00243 return next;
00244 }
00245
00246
00247
00248
00249
00250
00251 static cppchar_t
00252 get_effective_char (pfile)
00253 cpp_reader *pfile;
00254 {
00255 cppchar_t next;
00256 cpp_buffer *buffer = pfile->buffer;
00257
00258 buffer->backup_to = buffer->cur;
00259 next = *buffer->cur++;
00260 if (__builtin_expect (next == '?' || next == '\\', 0))
00261 next = skip_escaped_newlines (pfile);
00262
00263 return next;
00264 }
00265
00266
00267
00268
00269 static int
00270 skip_block_comment (pfile)
00271 cpp_reader *pfile;
00272 {
00273 cpp_buffer *buffer = pfile->buffer;
00274 cppchar_t c = EOF, prevc = EOF;
00275
00276 pfile->state.lexing_comment = 1;
00277 while (buffer->cur != buffer->rlimit)
00278 {
00279 prevc = c, c = *buffer->cur++;
00280
00281
00282
00283 if (c == '?' || c == '\\')
00284 c = skip_escaped_newlines (pfile);
00285
00286
00287
00288 if (c == '/')
00289 {
00290 if (prevc == '*')
00291 break;
00292
00293
00294
00295
00296 if (CPP_OPTION (pfile, warn_comments)
00297 && buffer->cur[0] == '*' && buffer->cur[1] != '/')
00298 cpp_error_with_line (pfile, DL_WARNING,
00299 pfile->line, CPP_BUF_COL (buffer),
00300 "\"/*\" within comment");
00301 }
00302 else if (is_vspace (c))
00303 handle_newline (pfile);
00304 else if (c == '\t')
00305 adjust_column (pfile);
00306 }
00307
00308 pfile->state.lexing_comment = 0;
00309 return c != '/' || prevc != '*';
00310 }
00311
00312
00313
00314
00315 static int
00316 skip_line_comment (pfile)
00317 cpp_reader *pfile;
00318 {
00319 cpp_buffer *buffer = pfile->buffer;
00320 unsigned int orig_line = pfile->line;
00321 cppchar_t c;
00322 #ifdef MULTIBYTE_CHARS
00323 wchar_t wc;
00324 int char_len;
00325 #endif
00326
00327 pfile->state.lexing_comment = 1;
00328 #ifdef MULTIBYTE_CHARS
00329
00330 (void) local_mbtowc (NULL, NULL, 0);
00331 #endif
00332 do
00333 {
00334 if (buffer->cur == buffer->rlimit)
00335 goto at_eof;
00336
00337 #ifdef MULTIBYTE_CHARS
00338 char_len = local_mbtowc (&wc, (const char *) buffer->cur,
00339 buffer->rlimit - buffer->cur);
00340 if (char_len == -1)
00341 {
00342 cpp_error (pfile, DL_WARNING,
00343 "ignoring invalid multibyte character");
00344 char_len = 1;
00345 c = *buffer->cur++;
00346 }
00347 else
00348 {
00349 buffer->cur += char_len;
00350 c = wc;
00351 }
00352 #else
00353 c = *buffer->cur++;
00354 #endif
00355 if (c == '?' || c == '\\')
00356 c = skip_escaped_newlines (pfile);
00357 }
00358 while (!is_vspace (c));
00359
00360
00361 buffer->cur--;
00362 at_eof:
00363
00364 pfile->state.lexing_comment = 0;
00365 return orig_line != pfile->line;
00366 }
00367
00368
00369
00370 static void
00371 adjust_column (pfile)
00372 cpp_reader *pfile;
00373 {
00374 cpp_buffer *buffer = pfile->buffer;
00375 unsigned int col = CPP_BUF_COL (buffer) - 1;
00376
00377
00378
00379 buffer->col_adjust += (CPP_OPTION (pfile, tabstop)
00380 - col % CPP_OPTION (pfile, tabstop)) - 1;
00381 }
00382
00383
00384
00385
00386 static int
00387 skip_whitespace (pfile, c)
00388 cpp_reader *pfile;
00389 cppchar_t c;
00390 {
00391 cpp_buffer *buffer = pfile->buffer;
00392 unsigned int warned = 0;
00393
00394 do
00395 {
00396
00397 if (c == ' ')
00398 ;
00399 else if (c == '\t')
00400 adjust_column (pfile);
00401
00402 else if (c == '\0')
00403 {
00404 if (buffer->cur - 1 == buffer->rlimit)
00405 return 0;
00406 if (!warned)
00407 {
00408 cpp_error (pfile, DL_WARNING, "null character(s) ignored");
00409 warned = 1;
00410 }
00411 }
00412 else if (pfile->state.in_directive && CPP_PEDANTIC (pfile))
00413 cpp_error_with_line (pfile, DL_PEDWARN, pfile->line,
00414 CPP_BUF_COL (buffer),
00415 "%s in preprocessing directive",
00416 c == '\f' ? "form feed" : "vertical tab");
00417
00418 c = *buffer->cur++;
00419 }
00420
00421 while (is_nvspace (c));
00422
00423 buffer->cur--;
00424 return 1;
00425 }
00426
00427
00428
00429 static int
00430 name_p (pfile, string)
00431 cpp_reader *pfile;
00432 const cpp_string *string;
00433 {
00434 unsigned int i;
00435
00436 for (i = 0; i < string->len; i++)
00437 if (!is_idchar (string->text[i]))
00438 return 0;
00439
00440 return 1;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 static cpp_hashnode *
00452 parse_identifier (pfile)
00453 cpp_reader *pfile;
00454 {
00455 cpp_hashnode *result;
00456 const uchar *cur, *base;
00457
00458
00459
00460 cur = pfile->buffer->cur;
00461 while (ISIDNUM (*cur))
00462 cur++;
00463
00464
00465 if (*cur == '?' || *cur == '\\' || *cur == '$')
00466 {
00467 unsigned int len;
00468
00469 base = parse_slow (pfile, cur, 0, &len);
00470 result = (cpp_hashnode *)
00471 ht_lookup (pfile->hash_table, base, len, HT_ALLOCED);
00472 }
00473 else
00474 {
00475 base = pfile->buffer->cur - 1;
00476 pfile->buffer->cur = cur;
00477 result = (cpp_hashnode *)
00478 ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC);
00479 }
00480
00481
00482
00483 if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC)
00484 && !pfile->state.skipping, 0))
00485 {
00486
00487 if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok)
00488 cpp_error (pfile, DL_ERROR, "attempt to use poisoned \"%s\"",
00489 NODE_NAME (result));
00490
00491
00492
00493 if (result == pfile->spec_nodes.n__VA_ARGS__
00494 && !pfile->state.va_args_ok)
00495 cpp_error (pfile, DL_PEDWARN,
00496 "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro");
00497 }
00498
00499 return result;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 static uchar *
00509 parse_slow (pfile, cur, number_p, plen)
00510 cpp_reader *pfile;
00511 const uchar *cur;
00512 int number_p;
00513 unsigned int *plen;
00514 {
00515 cpp_buffer *buffer = pfile->buffer;
00516 const uchar *base = buffer->cur - 1;
00517 struct obstack *stack = &pfile->hash_table->stack;
00518 unsigned int c, prevc, saw_dollar = 0;
00519
00520
00521 if (number_p == 2)
00522 obstack_1grow (stack, '.');
00523
00524
00525 obstack_grow (stack, base, cur - base);
00526
00527
00528
00529 prevc = cur[-1];
00530 c = *cur++;
00531 buffer->cur = cur;
00532 for (;;)
00533 {
00534
00535 buffer->backup_to = buffer->cur - 1;
00536 if (c == '?' || c == '\\')
00537 c = skip_escaped_newlines (pfile);
00538
00539 if (!is_idchar (c))
00540 {
00541 if (!number_p)
00542 break;
00543 if (c != '.' && !VALID_SIGN (c, prevc))
00544 break;
00545 }
00546
00547
00548 do
00549 {
00550 prevc = c;
00551 obstack_1grow (stack, c);
00552
00553 if (c == '$')
00554 saw_dollar++;
00555
00556 c = *buffer->cur++;
00557 }
00558 while (is_idchar (c));
00559 }
00560
00561
00562 BACKUP ();
00563
00564
00565
00566
00567 if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->state.skipping)
00568 cpp_error (pfile, DL_PEDWARN, "'$' character(s) in identifier or number");
00569
00570
00571 *plen = obstack_object_size (stack);
00572 obstack_1grow (stack, '\0');
00573 return obstack_finish (stack);
00574 }
00575
00576
00577
00578
00579 static void
00580 parse_number (pfile, number, leading_period)
00581 cpp_reader *pfile;
00582 cpp_string *number;
00583 int leading_period;
00584 {
00585 const uchar *cur;
00586
00587
00588
00589 cur = pfile->buffer->cur;
00590 while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]))
00591 cur++;
00592
00593
00594 if (*cur == '?' || *cur == '\\' || *cur == '$')
00595 number->text = parse_slow (pfile, cur, 1 + leading_period, &number->len);
00596 else
00597 {
00598 const uchar *base = pfile->buffer->cur - 1;
00599 uchar *dest;
00600
00601 number->len = cur - base + leading_period;
00602 dest = _cpp_unaligned_alloc (pfile, number->len + 1);
00603 dest[number->len] = '\0';
00604 number->text = dest;
00605
00606 if (leading_period)
00607 *dest++ = '.';
00608 memcpy (dest, base, cur - base);
00609 pfile->buffer->cur = cur;
00610 }
00611 }
00612
00613
00614 static int
00615 unescaped_terminator_p (pfile, dest)
00616 cpp_reader *pfile;
00617 const unsigned char *dest;
00618 {
00619 const unsigned char *start, *temp;
00620
00621
00622 if (pfile->state.angled_headers)
00623 return 1;
00624
00625 start = BUFF_FRONT (pfile->u_buff);
00626
00627
00628
00629 for (temp = dest; temp > start && temp[-1] == '\\'; temp--)
00630 ;
00631
00632 return ((dest - temp) & 1) == 0;
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642 static void
00643 parse_string (pfile, token, terminator)
00644 cpp_reader *pfile;
00645 cpp_token *token;
00646 cppchar_t terminator;
00647 {
00648 cpp_buffer *buffer = pfile->buffer;
00649 unsigned char *dest, *limit;
00650 cppchar_t c;
00651 bool warned_nulls = false;
00652 #ifdef MULTIBYTE_CHARS
00653 wchar_t wc;
00654 int char_len;
00655 #endif
00656
00657 dest = BUFF_FRONT (pfile->u_buff);
00658 limit = BUFF_LIMIT (pfile->u_buff);
00659
00660 #ifdef MULTIBYTE_CHARS
00661
00662 (void) local_mbtowc (NULL, NULL, 0);
00663 #endif
00664 for (;;)
00665 {
00666
00667 if ((size_t) (limit - dest) < 1)
00668 {
00669 size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
00670 _cpp_extend_buff (pfile, &pfile->u_buff, 2);
00671 dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
00672 limit = BUFF_LIMIT (pfile->u_buff);
00673 }
00674
00675 #ifdef MULTIBYTE_CHARS
00676 char_len = local_mbtowc (&wc, (const char *) buffer->cur,
00677 buffer->rlimit - buffer->cur);
00678 if (char_len == -1)
00679 {
00680 cpp_error (pfile, DL_WARNING,
00681 "ignoring invalid multibyte character");
00682 char_len = 1;
00683 c = *buffer->cur++;
00684 }
00685 else
00686 {
00687 buffer->cur += char_len;
00688 c = wc;
00689 }
00690 #else
00691 c = *buffer->cur++;
00692 #endif
00693
00694
00695 if (c == '?' || c == '\\')
00696 c = skip_escaped_newlines (pfile);
00697
00698 if (c == terminator)
00699 {
00700 if (unescaped_terminator_p (pfile, dest))
00701 break;
00702 }
00703 else if (is_vspace (c))
00704 {
00705
00706
00707
00708
00709 unterminated:
00710 if (CPP_OPTION (pfile, lang) != CLK_ASM || terminator == '>')
00711 cpp_error (pfile, DL_ERROR, "missing terminating %c character",
00712 (int) terminator);
00713 buffer->cur--;
00714 break;
00715 }
00716 else if (c == '\0')
00717 {
00718 if (buffer->cur - 1 == buffer->rlimit)
00719 goto unterminated;
00720 if (!warned_nulls)
00721 {
00722 warned_nulls = true;
00723 cpp_error (pfile, DL_WARNING,
00724 "null character(s) preserved in literal");
00725 }
00726 }
00727 #ifdef MULTIBYTE_CHARS
00728 if (char_len > 1)
00729 {
00730 for ( ; char_len > 0; --char_len)
00731 *dest++ = (*buffer->cur - char_len);
00732 }
00733 else
00734 #endif
00735 *dest++ = c;
00736 }
00737
00738 *dest = '\0';
00739
00740 token->val.str.text = BUFF_FRONT (pfile->u_buff);
00741 token->val.str.len = dest - BUFF_FRONT (pfile->u_buff);
00742 BUFF_FRONT (pfile->u_buff) = dest + 1;
00743 }
00744
00745
00746 static void
00747 save_comment (pfile, token, from, type)
00748 cpp_reader *pfile;
00749 cpp_token *token;
00750 const unsigned char *from;
00751 cppchar_t type;
00752 {
00753 unsigned char *buffer;
00754 unsigned int len, clen;
00755
00756 len = pfile->buffer->cur - from + 1;
00757
00758
00759
00760 if (is_vspace (pfile->buffer->cur[-1]))
00761 len--;
00762
00763
00764
00765
00766
00767
00768
00769 clen = (pfile->state.in_directive && type == '/') ? len + 2 : len;
00770
00771 buffer = _cpp_unaligned_alloc (pfile, clen);
00772
00773 token->type = CPP_COMMENT;
00774 token->val.str.len = clen;
00775 token->val.str.text = buffer;
00776
00777 buffer[0] = '/';
00778 memcpy (buffer + 1, from, len - 1);
00779
00780
00781 if (pfile->state.in_directive && type == '/')
00782 {
00783 buffer[1] = '*';
00784 buffer[clen - 2] = '*';
00785 buffer[clen - 1] = '/';
00786 }
00787 }
00788
00789
00790 void
00791 _cpp_init_tokenrun (run, count)
00792 tokenrun *run;
00793 unsigned int count;
00794 {
00795 run->base = xnewvec (cpp_token, count);
00796 run->limit = run->base + count;
00797 run->next = NULL;
00798 }
00799
00800
00801 static tokenrun *
00802 next_tokenrun (run)
00803 tokenrun *run;
00804 {
00805 if (run->next == NULL)
00806 {
00807 run->next = xnew (tokenrun);
00808 run->next->prev = run;
00809 _cpp_init_tokenrun (run->next, 250);
00810 }
00811
00812 return run->next;
00813 }
00814
00815
00816
00817
00818
00819 cpp_token *
00820 _cpp_temp_token (pfile)
00821 cpp_reader *pfile;
00822 {
00823 cpp_token *old, *result;
00824
00825 old = pfile->cur_token - 1;
00826 if (pfile->cur_token == pfile->cur_run->limit)
00827 {
00828 pfile->cur_run = next_tokenrun (pfile->cur_run);
00829 pfile->cur_token = pfile->cur_run->base;
00830 }
00831
00832 result = pfile->cur_token++;
00833 result->line = old->line;
00834 result->col = old->col;
00835 return result;
00836 }
00837
00838 #ifdef KEY
00839 enum pragma_type
00840 {
00841 INVALID,
00842 OMP,
00843 OPTIONS,
00844 EXEC_FREQ
00845 #ifdef TARG_SL2 //fork_joint
00846 , SL2
00847 #endif
00848
00849 };
00850
00851 static enum pragma_type current_pragma = INVALID;
00852 bool last_token_omp_hash = FALSE;
00853 static cpp_token *
00854 _cpp_omp_token (cpp_reader * pfile)
00855 {
00856 cpp_buffer * buffer = pfile->buffer;
00857 cpp_token * result = NULL;
00858
00859 const unsigned char *c = buffer->cur;
00860 const unsigned char *rlimit = buffer->rlimit;
00861
00862 while (*c == ' ' || *c == '\t') c++;
00863
00864 int len = 6;
00865 if ((rlimit - c) < len || memcmp (c, "pragma", len))
00866 return NULL;
00867
00868 c += len;
00869
00870 while (c < rlimit && (*c == ' ' || *c == '\t')) c++;
00871
00872 len = 3;
00873 if ((rlimit - c) >= len && !memcmp (c, "omp", len))
00874 {
00875 result = _cpp_lex_direct (pfile);
00876 current_pragma = OMP;
00877 }
00878 else if ((rlimit - c) >= strlen ("options") &&
00879 !memcmp (c, "options", strlen ("options")))
00880 {
00881 result = _cpp_lex_direct (pfile);
00882 current_pragma = OPTIONS;
00883 }
00884 else if (((rlimit - c) >= strlen ("mips_frequency_hint") &&
00885 !memcmp (c, "mips_frequency_hint", strlen ("mips_frequency_hint")))
00886 || ((rlimit - c) >= strlen ("frequency_hint") &&
00887 !memcmp (c, "frequency_hint", strlen ("frequency_hint"))))
00888 {
00889 result = _cpp_lex_direct (pfile);
00890 current_pragma = EXEC_FREQ;
00891 }
00892
00893 #ifdef TARG_SL2 //fork_joint
00894 else if((rlimit -c)>=strlen("sl2") && !memcmp(c, "sl2", strlen("sl2")))
00895 {
00896 result = _cpp_lex_direct(pfile);
00897 current_pragma = SL2;
00898 }
00899 #endif
00900
00901 return result;
00902 }
00903
00904
00905
00906 static void
00907 skip_to_end_of_line (cpp_reader * pfile)
00908 {
00909 cpp_buffer * buffer = pfile->buffer;
00910 cppchar_t c;
00911
00912 while (buffer->cur != buffer->rlimit)
00913 {
00914 c = *buffer->cur++;
00915 if (c == '\n')
00916 {
00917
00918 buffer->cur--;
00919 break;
00920 }
00921 }
00922 }
00923
00924 extern int flag_openmp;
00925 #endif
00926
00927
00928
00929
00930 const cpp_token *
00931 _cpp_lex_token (pfile)
00932 cpp_reader *pfile;
00933 {
00934 cpp_token *result;
00935
00936 for (;;)
00937 {
00938 if (pfile->cur_token == pfile->cur_run->limit)
00939 {
00940 pfile->cur_run = next_tokenrun (pfile->cur_run);
00941 pfile->cur_token = pfile->cur_run->base;
00942 }
00943
00944 if (pfile->lookaheads)
00945 {
00946 pfile->lookaheads--;
00947 result = pfile->cur_token++;
00948 }
00949 else
00950 {
00951 result = _cpp_lex_direct (pfile);
00952 #ifdef KEY
00953 if (in_omp_pragma && *(pfile->buffer->cur-1) == '\n')
00954 return result;
00955 #endif
00956 }
00957
00958 #ifdef KEY
00959 if ((result->flags & BOL) && result->type == CPP_HASH &&
00960 pfile->state.parsing_args != 1)
00961 {
00962
00963 cpp_token * omp_res = _cpp_omp_token (pfile);
00964 if (omp_res)
00965 {
00966 if (flag_openmp && current_pragma == OMP)
00967 {
00968 last_token_omp_hash = TRUE;
00969 return omp_res;
00970 }
00971 else if (current_pragma == OPTIONS ||
00972 current_pragma == EXEC_FREQ)
00973 {
00974 last_token_omp_hash = TRUE;
00975 return omp_res;
00976 }
00977 #ifdef TARG_SL2 //fork_joint
00978 else if (current_pragma == SL2)
00979 {
00980 last_token_omp_hash = TRUE;
00981 return omp_res;
00982 }
00983 #endif
00984 else
00985 {
00986 skip_to_end_of_line (pfile);
00987 continue;
00988 }
00989 }
00990 }
00991 #endif // KEY
00992
00993 if (result->flags & BOL)
00994 {
00995
00996
00997 if (result->type == CPP_HASH
00998
00999
01000
01001 && pfile->state.parsing_args != 1
01002 && _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
01003 continue;
01004 if (pfile->cb.line_change && !pfile->state.skipping)
01005 (*pfile->cb.line_change)(pfile, result, pfile->state.parsing_args);
01006 }
01007
01008
01009 if (pfile->state.in_directive)
01010 break;
01011
01012
01013
01014
01015 pfile->mi_valid = false;
01016
01017 if (!pfile->state.skipping || result->type == CPP_EOF)
01018 break;
01019 }
01020
01021 return result;
01022 }
01023
01024
01025
01026
01027
01028 static bool
01029 continue_after_nul (pfile)
01030 cpp_reader *pfile;
01031 {
01032 cpp_buffer *buffer = pfile->buffer;
01033 bool more = false;
01034
01035 buffer->saved_flags = BOL;
01036 if (CPP_OPTION (pfile, traditional))
01037 {
01038 if (pfile->state.in_directive)
01039 return false;
01040
01041 _cpp_remove_overlay (pfile);
01042 more = _cpp_read_logical_line_trad (pfile);
01043 _cpp_overlay_buffer (pfile, pfile->out.base,
01044 pfile->out.cur - pfile->out.base);
01045 pfile->line = pfile->out.first_line;
01046 }
01047 else
01048 {
01049
01050
01051 if (!pfile->state.parsing_args)
01052 {
01053 if (buffer->cur != buffer->line_base)
01054 {
01055
01056
01057 if (!buffer->from_stage3)
01058 cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
01059 handle_newline (pfile);
01060 }
01061
01062
01063
01064 if (!pfile->state.in_directive && buffer->prev)
01065 {
01066 more = !buffer->return_at_eof;
01067 _cpp_pop_buffer (pfile);
01068 }
01069 }
01070 }
01071
01072 return more;
01073 }
01074
01075 #define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \
01076 do { \
01077 if (get_effective_char (pfile) == CHAR) \
01078 result->type = THEN_TYPE; \
01079 else \
01080 { \
01081 BACKUP (); \
01082 result->type = ELSE_TYPE; \
01083 } \
01084 } while (0)
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097 cpp_token *
01098 _cpp_lex_direct (pfile)
01099 cpp_reader *pfile;
01100 {
01101 cppchar_t c;
01102 cpp_buffer *buffer;
01103 const unsigned char *comment_start;
01104 cpp_token *result = pfile->cur_token++;
01105
01106 fresh_line:
01107 buffer = pfile->buffer;
01108 result->flags = buffer->saved_flags;
01109 buffer->saved_flags = 0;
01110 update_tokens_line:
01111 result->line = pfile->line;
01112
01113 skipped_white:
01114 c = *buffer->cur++;
01115 result->col = CPP_BUF_COLUMN (buffer, buffer->cur);
01116
01117 #ifdef KEY
01118 if (in_omp_pragma && c == '\n')
01119 {
01120 buffer->saved_flags = BOL;
01121 result->type = CPP_NAME;
01122 result->val.node = (cpp_hashnode *)
01123 ht_lookup (pfile->hash_table, buffer->cur-1, 1, HT_ALLOC);
01124 return result;
01125 }
01126 #endif
01127 trigraph:
01128 switch (c)
01129 {
01130 case ' ': case '\t': case '\f': case '\v': case '\0':
01131 result->flags |= PREV_WHITE;
01132 if (skip_whitespace (pfile, c))
01133 goto skipped_white;
01134
01135
01136 buffer->cur--;
01137 if (continue_after_nul (pfile))
01138 goto fresh_line;
01139 result->type = CPP_EOF;
01140 break;
01141
01142 case '\n': case '\r':
01143 handle_newline (pfile);
01144 buffer->saved_flags = BOL;
01145 if (! pfile->state.in_directive)
01146 {
01147 if (pfile->state.parsing_args == 2)
01148 buffer->saved_flags |= PREV_WHITE;
01149 if (!pfile->keep_tokens)
01150 {
01151 pfile->cur_run = &pfile->base_run;
01152 result = pfile->base_run.base;
01153 pfile->cur_token = result + 1;
01154 }
01155 goto fresh_line;
01156 }
01157 result->type = CPP_EOF;
01158 break;
01159
01160 case '?':
01161 case '\\':
01162
01163
01164 {
01165 unsigned int line = pfile->line;
01166
01167 c = skip_escaped_newlines (pfile);
01168 if (line != pfile->line)
01169 {
01170 buffer->cur--;
01171
01172
01173 goto update_tokens_line;
01174 }
01175 }
01176
01177
01178 if (c == '?')
01179 result->type = CPP_QUERY;
01180 else if (c == '\\')
01181 goto random_char;
01182 else
01183 goto trigraph;
01184 break;
01185
01186 case '0': case '1': case '2': case '3': case '4':
01187 case '5': case '6': case '7': case '8': case '9':
01188 result->type = CPP_NUMBER;
01189 parse_number (pfile, &result->val.str, 0);
01190 break;
01191
01192 case 'L':
01193
01194 {
01195 const unsigned char *pos = buffer->cur;
01196
01197 c = get_effective_char (pfile);
01198 if (c == '\'' || c == '"')
01199 {
01200 result->type = (c == '"' ? CPP_WSTRING: CPP_WCHAR);
01201 parse_string (pfile, result, c);
01202 break;
01203 }
01204 buffer->cur = pos;
01205 }
01206
01207
01208 start_ident:
01209 case '_':
01210 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
01211 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
01212 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
01213 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
01214 case 'y': case 'z':
01215 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
01216 case 'G': case 'H': case 'I': case 'J': case 'K':
01217 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
01218 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
01219 case 'Y': case 'Z':
01220 result->type = CPP_NAME;
01221 result->val.node = parse_identifier (pfile);
01222
01223
01224 if (result->val.node->flags & NODE_OPERATOR)
01225 {
01226 result->flags |= NAMED_OP;
01227 #ifdef SGI_MONGOOSE
01228 result->type = result->val.node->value.operator_code;
01229 #else
01230 result->type = result->val.node->value.operator;
01231 #endif
01232 }
01233 break;
01234
01235 case '\'':
01236 case '"':
01237 result->type = c == '"' ? CPP_STRING: CPP_CHAR;
01238 parse_string (pfile, result, c);
01239 break;
01240
01241 case '/':
01242
01243 comment_start = buffer->cur;
01244 c = get_effective_char (pfile);
01245
01246 if (c == '*')
01247 {
01248 if (skip_block_comment (pfile))
01249 cpp_error (pfile, DL_ERROR, "unterminated comment");
01250 }
01251 else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments)
01252 || CPP_IN_SYSTEM_HEADER (pfile)))
01253 {
01254
01255
01256 if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile)
01257 && ! buffer->warned_cplusplus_comments)
01258 {
01259 cpp_error (pfile, DL_PEDWARN,
01260 "C++ style comments are not allowed in ISO C90");
01261 cpp_error (pfile, DL_PEDWARN,
01262 "(this will be reported only once per input file)");
01263 buffer->warned_cplusplus_comments = 1;
01264 }
01265
01266 if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
01267 cpp_error (pfile, DL_WARNING, "multi-line comment");
01268 }
01269 else if (c == '=')
01270 {
01271 result->type = CPP_DIV_EQ;
01272 break;
01273 }
01274 else
01275 {
01276 BACKUP ();
01277 result->type = CPP_DIV;
01278 break;
01279 }
01280
01281 if (!pfile->state.save_comments)
01282 {
01283 result->flags |= PREV_WHITE;
01284 goto update_tokens_line;
01285 }
01286
01287
01288 save_comment (pfile, result, comment_start, c);
01289 break;
01290
01291 case '<':
01292 if (pfile->state.angled_headers)
01293 {
01294 result->type = CPP_HEADER_NAME;
01295 parse_string (pfile, result, '>');
01296 break;
01297 }
01298
01299 c = get_effective_char (pfile);
01300 if (c == '=')
01301 result->type = CPP_LESS_EQ;
01302 else if (c == '<')
01303 IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT);
01304 else if (c == '?' && CPP_OPTION (pfile, cplusplus))
01305 IF_NEXT_IS ('=', CPP_MIN_EQ, CPP_MIN);
01306 else if (c == ':' && CPP_OPTION (pfile, digraphs))
01307 {
01308 result->type = CPP_OPEN_SQUARE;
01309 result->flags |= DIGRAPH;
01310 }
01311 else if (c == '%' && CPP_OPTION (pfile, digraphs))
01312 {
01313 result->type = CPP_OPEN_BRACE;
01314 result->flags |= DIGRAPH;
01315 }
01316 else
01317 {
01318 BACKUP ();
01319 result->type = CPP_LESS;
01320 }
01321 break;
01322
01323 case '>':
01324 c = get_effective_char (pfile);
01325 if (c == '=')
01326 result->type = CPP_GREATER_EQ;
01327 else if (c == '>')
01328 IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT);
01329 else if (c == '?' && CPP_OPTION (pfile, cplusplus))
01330 IF_NEXT_IS ('=', CPP_MAX_EQ, CPP_MAX);
01331 else
01332 {
01333 BACKUP ();
01334 result->type = CPP_GREATER;
01335 }
01336 break;
01337
01338 case '%':
01339 c = get_effective_char (pfile);
01340 if (c == '=')
01341 result->type = CPP_MOD_EQ;
01342 else if (CPP_OPTION (pfile, digraphs) && c == ':')
01343 {
01344 result->flags |= DIGRAPH;
01345 result->type = CPP_HASH;
01346 if (get_effective_char (pfile) == '%')
01347 {
01348 const unsigned char *pos = buffer->cur;
01349
01350 if (get_effective_char (pfile) == ':')
01351 result->type = CPP_PASTE;
01352 else
01353 buffer->cur = pos - 1;
01354 }
01355 else
01356 BACKUP ();
01357 }
01358 else if (CPP_OPTION (pfile, digraphs) && c == '>')
01359 {
01360 result->flags |= DIGRAPH;
01361 result->type = CPP_CLOSE_BRACE;
01362 }
01363 else
01364 {
01365 BACKUP ();
01366 result->type = CPP_MOD;
01367 }
01368 break;
01369
01370 case '.':
01371 result->type = CPP_DOT;
01372 c = get_effective_char (pfile);
01373 if (c == '.')
01374 {
01375 const unsigned char *pos = buffer->cur;
01376
01377 if (get_effective_char (pfile) == '.')
01378 result->type = CPP_ELLIPSIS;
01379 else
01380 buffer->cur = pos - 1;
01381 }
01382
01383 else if (ISDIGIT (c))
01384 {
01385 result->type = CPP_NUMBER;
01386 parse_number (pfile, &result->val.str, 1);
01387 }
01388 else if (c == '*' && CPP_OPTION (pfile, cplusplus))
01389 result->type = CPP_DOT_STAR;
01390 else
01391 BACKUP ();
01392 break;
01393
01394 case '+':
01395 c = get_effective_char (pfile);
01396 if (c == '+')
01397 result->type = CPP_PLUS_PLUS;
01398 else if (c == '=')
01399 result->type = CPP_PLUS_EQ;
01400 else
01401 {
01402 BACKUP ();
01403 result->type = CPP_PLUS;
01404 }
01405 break;
01406
01407 case '-':
01408 c = get_effective_char (pfile);
01409 if (c == '>')
01410 {
01411 result->type = CPP_DEREF;
01412 if (CPP_OPTION (pfile, cplusplus))
01413 {
01414 if (get_effective_char (pfile) == '*')
01415 result->type = CPP_DEREF_STAR;
01416 else
01417 BACKUP ();
01418 }
01419 }
01420 else if (c == '-')
01421 result->type = CPP_MINUS_MINUS;
01422 else if (c == '=')
01423 result->type = CPP_MINUS_EQ;
01424 else
01425 {
01426 BACKUP ();
01427 result->type = CPP_MINUS;
01428 }
01429 break;
01430
01431 case '&':
01432 c = get_effective_char (pfile);
01433 if (c == '&')
01434 result->type = CPP_AND_AND;
01435 else if (c == '=')
01436 result->type = CPP_AND_EQ;
01437 else
01438 {
01439 BACKUP ();
01440 result->type = CPP_AND;
01441 }
01442 break;
01443
01444 case '|':
01445 c = get_effective_char (pfile);
01446 if (c == '|')
01447 result->type = CPP_OR_OR;
01448 else if (c == '=')
01449 result->type = CPP_OR_EQ;
01450 else
01451 {
01452 BACKUP ();
01453 result->type = CPP_OR;
01454 }
01455 break;
01456
01457 case ':':
01458 c = get_effective_char (pfile);
01459 if (c == ':' && CPP_OPTION (pfile, cplusplus))
01460 result->type = CPP_SCOPE;
01461 else if (c == '>' && CPP_OPTION (pfile, digraphs))
01462 {
01463 result->flags |= DIGRAPH;
01464 result->type = CPP_CLOSE_SQUARE;
01465 }
01466 else
01467 {
01468 BACKUP ();
01469 result->type = CPP_COLON;
01470 }
01471 break;
01472
01473 case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break;
01474 case '=': IF_NEXT_IS ('=', CPP_EQ_EQ, CPP_EQ); break;
01475 case '!': IF_NEXT_IS ('=', CPP_NOT_EQ, CPP_NOT); break;
01476 case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break;
01477 case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); break;
01478
01479 case '~': result->type = CPP_COMPL; break;
01480 case ',': result->type = CPP_COMMA; break;
01481 case '(': result->type = CPP_OPEN_PAREN;
01482 #ifdef KEY
01483 if (in_omp_pragma) seen_omp_paren = TRUE;
01484 #endif
01485 break;
01486 case ')': result->type = CPP_CLOSE_PAREN; break;
01487 case '[': result->type = CPP_OPEN_SQUARE; break;
01488 case ']': result->type = CPP_CLOSE_SQUARE; break;
01489 case '{': result->type = CPP_OPEN_BRACE; break;
01490 case '}': result->type = CPP_CLOSE_BRACE; break;
01491 case ';': result->type = CPP_SEMICOLON; break;
01492
01493
01494 case '@': result->type = CPP_ATSIGN; break;
01495
01496 case '$':
01497 if (CPP_OPTION (pfile, dollars_in_ident))
01498 goto start_ident;
01499
01500
01501 random_char:
01502 default:
01503 result->type = CPP_OTHER;
01504 result->val.c = c;
01505 break;
01506 }
01507
01508 return result;
01509 }
01510
01511
01512
01513 unsigned int
01514 cpp_token_len (token)
01515 const cpp_token *token;
01516 {
01517 unsigned int len;
01518
01519 switch (TOKEN_SPELL (token))
01520 {
01521 default: len = 0; break;
01522 case SPELL_NUMBER:
01523 case SPELL_STRING: len = token->val.str.len; break;
01524 case SPELL_IDENT: len = NODE_LEN (token->val.node); break;
01525 }
01526
01527 return len + 5;
01528 }
01529
01530
01531
01532
01533
01534 unsigned char *
01535 cpp_spell_token (pfile, token, buffer)
01536 cpp_reader *pfile;
01537 const cpp_token *token;
01538 unsigned char *buffer;
01539 {
01540 switch (TOKEN_SPELL (token))
01541 {
01542 case SPELL_OPERATOR:
01543 {
01544 const unsigned char *spelling;
01545 unsigned char c;
01546
01547 if (token->flags & DIGRAPH)
01548 spelling
01549 = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH];
01550 else if (token->flags & NAMED_OP)
01551 goto spell_ident;
01552 else
01553 spelling = TOKEN_NAME (token);
01554
01555 while ((c = *spelling++) != '\0')
01556 *buffer++ = c;
01557 }
01558 break;
01559
01560 case SPELL_CHAR:
01561 *buffer++ = token->val.c;
01562 break;
01563
01564 spell_ident:
01565 case SPELL_IDENT:
01566 memcpy (buffer, NODE_NAME (token->val.node), NODE_LEN (token->val.node));
01567 buffer += NODE_LEN (token->val.node);
01568 break;
01569
01570 case SPELL_NUMBER:
01571 memcpy (buffer, token->val.str.text, token->val.str.len);
01572 buffer += token->val.str.len;
01573 break;
01574
01575 case SPELL_STRING:
01576 {
01577 int left, right, tag;
01578 switch (token->type)
01579 {
01580 case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
01581 case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
01582 case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
01583 case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
01584 case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
01585 default:
01586 cpp_error (pfile, DL_ICE, "unknown string token %s\n",
01587 TOKEN_NAME (token));
01588 return buffer;
01589 }
01590 if (tag) *buffer++ = tag;
01591 *buffer++ = left;
01592 memcpy (buffer, token->val.str.text, token->val.str.len);
01593 buffer += token->val.str.len;
01594 *buffer++ = right;
01595 }
01596 break;
01597
01598 case SPELL_NONE:
01599 cpp_error (pfile, DL_ICE, "unspellable token %s", TOKEN_NAME (token));
01600 break;
01601 }
01602
01603 return buffer;
01604 }
01605
01606
01607
01608 unsigned char *
01609 cpp_token_as_text (pfile, token)
01610 cpp_reader *pfile;
01611 const cpp_token *token;
01612 {
01613 unsigned int len = cpp_token_len (token);
01614 unsigned char *start = _cpp_unaligned_alloc (pfile, len), *end;
01615
01616 end = cpp_spell_token (pfile, token, start);
01617 end[0] = '\0';
01618
01619 return start;
01620 }
01621
01622
01623
01624 const char *
01625 cpp_type2name (type)
01626 enum cpp_ttype type;
01627 {
01628 return (const char *) token_spellings[type].name;
01629 }
01630
01631
01632
01633
01634 void
01635 cpp_output_token (token, fp)
01636 const cpp_token *token;
01637 FILE *fp;
01638 {
01639 switch (TOKEN_SPELL (token))
01640 {
01641 case SPELL_OPERATOR:
01642 {
01643 const unsigned char *spelling;
01644 int c;
01645
01646 if (token->flags & DIGRAPH)
01647 spelling
01648 = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH];
01649 else if (token->flags & NAMED_OP)
01650 goto spell_ident;
01651 else
01652 spelling = TOKEN_NAME (token);
01653
01654 c = *spelling;
01655 do
01656 putc (c, fp);
01657 while ((c = *++spelling) != '\0');
01658 }
01659 break;
01660
01661 case SPELL_CHAR:
01662 putc (token->val.c, fp);
01663 break;
01664
01665 spell_ident:
01666 case SPELL_IDENT:
01667 fwrite (NODE_NAME (token->val.node), 1, NODE_LEN (token->val.node), fp);
01668 break;
01669
01670 case SPELL_NUMBER:
01671 fwrite (token->val.str.text, 1, token->val.str.len, fp);
01672 break;
01673
01674 case SPELL_STRING:
01675 {
01676 int left, right, tag;
01677 switch (token->type)
01678 {
01679 case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
01680 case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
01681 case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
01682 case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
01683 case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
01684 default:
01685 fprintf (stderr, "impossible STRING token %s\n", TOKEN_NAME (token));
01686 return;
01687 }
01688 if (tag) putc (tag, fp);
01689 putc (left, fp);
01690 fwrite (token->val.str.text, 1, token->val.str.len, fp);
01691 putc (right, fp);
01692 }
01693 break;
01694
01695 case SPELL_NONE:
01696
01697 break;
01698 }
01699 }
01700
01701
01702 int
01703 _cpp_equiv_tokens (a, b)
01704 const cpp_token *a, *b;
01705 {
01706 if (a->type == b->type && a->flags == b->flags)
01707 switch (TOKEN_SPELL (a))
01708 {
01709 default:
01710 case SPELL_OPERATOR:
01711 return 1;
01712 case SPELL_CHAR:
01713 return a->val.c == b->val.c;
01714 case SPELL_NONE:
01715 return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no);
01716 case SPELL_IDENT:
01717 return a->val.node == b->val.node;
01718 case SPELL_NUMBER:
01719 case SPELL_STRING:
01720 return (a->val.str.len == b->val.str.len
01721 && !memcmp (a->val.str.text, b->val.str.text,
01722 a->val.str.len));
01723 }
01724
01725 return 0;
01726 }
01727
01728
01729
01730
01731
01732 int
01733 cpp_avoid_paste (pfile, token1, token2)
01734 cpp_reader *pfile;
01735 const cpp_token *token1, *token2;
01736 {
01737 enum cpp_ttype a = token1->type, b = token2->type;
01738 cppchar_t c;
01739
01740 if (token1->flags & NAMED_OP)
01741 a = CPP_NAME;
01742 if (token2->flags & NAMED_OP)
01743 b = CPP_NAME;
01744
01745 c = EOF;
01746 if (token2->flags & DIGRAPH)
01747 c = digraph_spellings[(int) b - (int) CPP_FIRST_DIGRAPH][0];
01748 else if (token_spellings[b].category == SPELL_OPERATOR)
01749 c = token_spellings[b].name[0];
01750
01751
01752 if ((int) a <= (int) CPP_LAST_EQ && c == '=')
01753 return 1;
01754
01755 switch (a)
01756 {
01757 case CPP_GREATER: return c == '>' || c == '?';
01758 case CPP_LESS: return c == '<' || c == '?' || c == '%' || c == ':';
01759 case CPP_PLUS: return c == '+';
01760 case CPP_MINUS: return c == '-' || c == '>';
01761 case CPP_DIV: return c == '/' || c == '*';
01762 case CPP_MOD: return c == ':' || c == '>';
01763 case CPP_AND: return c == '&';
01764 case CPP_OR: return c == '|';
01765 case CPP_COLON: return c == ':' || c == '>';
01766 case CPP_DEREF: return c == '*';
01767 case CPP_DOT: return c == '.' || c == '%' || b == CPP_NUMBER;
01768 case CPP_HASH: return c == '#' || c == '%';
01769 case CPP_NAME: return ((b == CPP_NUMBER
01770 && name_p (pfile, &token2->val.str))
01771 || b == CPP_NAME
01772 || b == CPP_CHAR || b == CPP_STRING);
01773 case CPP_NUMBER: return (b == CPP_NUMBER || b == CPP_NAME
01774 || c == '.' || c == '+' || c == '-');
01775 case CPP_OTHER: return (CPP_OPTION (pfile, objc)
01776 && token1->val.c == '@'
01777 && (b == CPP_NAME || b == CPP_STRING));
01778 default: break;
01779 }
01780
01781 return 0;
01782 }
01783
01784
01785
01786
01787 void
01788 cpp_output_line (pfile, fp)
01789 cpp_reader *pfile;
01790 FILE *fp;
01791 {
01792 const cpp_token *token;
01793
01794 token = cpp_get_token (pfile);
01795 while (token->type != CPP_EOF)
01796 {
01797 cpp_output_token (token, fp);
01798 token = cpp_get_token (pfile);
01799 if (token->flags & PREV_WHITE)
01800 putc (' ', fp);
01801 }
01802
01803 putc ('\n', fp);
01804 }
01805
01806
01807 static unsigned int
01808 hex_digit_value (c)
01809 unsigned int c;
01810 {
01811 if (hex_p (c))
01812 return hex_value (c);
01813 else
01814 abort ();
01815 }
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839 static int
01840 maybe_read_ucs (pfile, pstr, limit, pc)
01841 cpp_reader *pfile;
01842 const unsigned char **pstr;
01843 const unsigned char *limit;
01844 cppchar_t *pc;
01845 {
01846 const unsigned char *p = *pstr;
01847 unsigned int code = 0;
01848 unsigned int c = *pc, length;
01849
01850
01851 if (! (CPP_OPTION (pfile, cplusplus) || CPP_OPTION (pfile, c99)))
01852 return 1;
01853
01854 if (CPP_WTRADITIONAL (pfile))
01855 cpp_error (pfile, DL_WARNING,
01856 "the meaning of '\\%c' is different in traditional C", c);
01857
01858 length = (c == 'u' ? 4: 8);
01859
01860 if ((size_t) (limit - p) < length)
01861 {
01862 cpp_error (pfile, DL_ERROR, "incomplete universal-character-name");
01863
01864 p = limit;
01865 }
01866 else
01867 {
01868 for (; length; length--, p++)
01869 {
01870 c = *p;
01871 if (ISXDIGIT (c))
01872 code = (code << 4) + hex_digit_value (c);
01873 else
01874 {
01875 cpp_error (pfile, DL_ERROR,
01876 "non-hex digit '%c' in universal-character-name", c);
01877
01878 break;
01879 }
01880 }
01881 }
01882
01883 #ifdef TARGET_EBCDIC
01884 cpp_error (pfile, DL_ERROR, "universal-character-name on EBCDIC target");
01885 code = 0x3f;
01886 #else
01887
01888 if (code >= 0xa0
01889 && !(code & 0x80000000)
01890 && !(code >= 0xD800 && code <= 0xDFFF))
01891 ;
01892
01893
01894 else if (code == 0x24 || code == 0x40 || code == 0x60)
01895 ;
01896
01897 else if (length == 0)
01898 cpp_error (pfile, DL_ERROR, "universal-character-name out of range");
01899 #endif
01900
01901 *pstr = p;
01902 *pc = code;
01903 return 0;
01904 }
01905
01906
01907
01908
01909
01910
01911 cppchar_t
01912 cpp_parse_escape (pfile, pstr, limit, wide)
01913 cpp_reader *pfile;
01914 const unsigned char **pstr;
01915 const unsigned char *limit;
01916 int wide;
01917 {
01918 int unknown = 0;
01919 const unsigned char *str = *pstr;
01920 cppchar_t c, mask;
01921 unsigned int width;
01922
01923 if (wide)
01924 width = CPP_OPTION (pfile, wchar_precision);
01925 else
01926 width = CPP_OPTION (pfile, char_precision);
01927 if (width < BITS_PER_CPPCHAR_T)
01928 mask = ((cppchar_t) 1 << width) - 1;
01929 else
01930 mask = ~0;
01931
01932 c = *str++;
01933 switch (c)
01934 {
01935 case '\\': case '\'': case '"': case '?': break;
01936 case 'b': c = TARGET_BS; break;
01937 case 'f': c = TARGET_FF; break;
01938 case 'n': c = TARGET_NEWLINE; break;
01939 case 'r': c = TARGET_CR; break;
01940 case 't': c = TARGET_TAB; break;
01941 case 'v': c = TARGET_VT; break;
01942
01943 case '(': case '{': case '[': case '%':
01944
01945
01946 unknown = CPP_PEDANTIC (pfile);
01947 break;
01948
01949 case 'a':
01950 if (CPP_WTRADITIONAL (pfile))
01951 cpp_error (pfile, DL_WARNING,
01952 "the meaning of '\\a' is different in traditional C");
01953 c = TARGET_BELL;
01954 break;
01955
01956 case 'e': case 'E':
01957 if (CPP_PEDANTIC (pfile))
01958 cpp_error (pfile, DL_PEDWARN,
01959 "non-ISO-standard escape sequence, '\\%c'", (int) c);
01960 c = TARGET_ESC;
01961 break;
01962
01963 case 'u': case 'U':
01964 unknown = maybe_read_ucs (pfile, &str, limit, &c);
01965 break;
01966
01967 case 'x':
01968 if (CPP_WTRADITIONAL (pfile))
01969 cpp_error (pfile, DL_WARNING,
01970 "the meaning of '\\x' is different in traditional C");
01971
01972 {
01973 cppchar_t i = 0, overflow = 0;
01974 int digits_found = 0;
01975
01976 while (str < limit)
01977 {
01978 c = *str;
01979 if (! ISXDIGIT (c))
01980 break;
01981 str++;
01982 overflow |= i ^ (i << 4 >> 4);
01983 i = (i << 4) + hex_digit_value (c);
01984 digits_found = 1;
01985 }
01986
01987 if (!digits_found)
01988 cpp_error (pfile, DL_ERROR,
01989 "\\x used with no following hex digits");
01990
01991 if (overflow | (i != (i & mask)))
01992 {
01993 cpp_error (pfile, DL_PEDWARN,
01994 "hex escape sequence out of range");
01995 i &= mask;
01996 }
01997 c = i;
01998 }
01999 break;
02000
02001 case '0': case '1': case '2': case '3':
02002 case '4': case '5': case '6': case '7':
02003 {
02004 size_t count = 0;
02005 cppchar_t i = c - '0';
02006
02007 while (str < limit && ++count < 3)
02008 {
02009 c = *str;
02010 if (c < '0' || c > '7')
02011 break;
02012 str++;
02013 i = (i << 3) + c - '0';
02014 }
02015
02016 if (i != (i & mask))
02017 {
02018 cpp_error (pfile, DL_PEDWARN,
02019 "octal escape sequence out of range");
02020 i &= mask;
02021 }
02022 c = i;
02023 }
02024 break;
02025
02026 default:
02027 unknown = 1;
02028 break;
02029 }
02030
02031 if (unknown)
02032 {
02033 if (ISGRAPH (c))
02034 cpp_error (pfile, DL_PEDWARN,
02035 "unknown escape sequence '\\%c'", (int) c);
02036 else
02037 cpp_error (pfile, DL_PEDWARN,
02038 "unknown escape sequence: '\\%03o'", (int) c);
02039 }
02040
02041 if (c > mask)
02042 {
02043 cpp_error (pfile, DL_PEDWARN, "escape sequence out of range for its type");
02044 c &= mask;
02045 }
02046
02047 *pstr = str;
02048 return c;
02049 }
02050
02051
02052
02053
02054
02055
02056 cppchar_t
02057 cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
02058 cpp_reader *pfile;
02059 const cpp_token *token;
02060 unsigned int *pchars_seen;
02061 int *unsignedp;
02062 {
02063 const unsigned char *str = token->val.str.text;
02064 const unsigned char *limit = str + token->val.str.len;
02065 unsigned int chars_seen = 0;
02066 size_t width, max_chars;
02067 cppchar_t c, mask, result = 0;
02068 bool unsigned_p;
02069
02070 #ifdef MULTIBYTE_CHARS
02071 (void) local_mbtowc (NULL, NULL, 0);
02072 #endif
02073
02074
02075 if (token->type == CPP_CHAR)
02076 {
02077 width = CPP_OPTION (pfile, char_precision);
02078 max_chars = CPP_OPTION (pfile, int_precision) / width;
02079 unsigned_p = CPP_OPTION (pfile, unsigned_char);
02080 }
02081 else
02082 {
02083 width = CPP_OPTION (pfile, wchar_precision);
02084 max_chars = 1;
02085 unsigned_p = CPP_OPTION (pfile, unsigned_wchar);
02086 }
02087
02088 if (width < BITS_PER_CPPCHAR_T)
02089 mask = ((cppchar_t) 1 << width) - 1;
02090 else
02091 mask = ~0;
02092
02093 while (str < limit)
02094 {
02095 #ifdef MULTIBYTE_CHARS
02096 wchar_t wc;
02097 int char_len;
02098
02099 char_len = local_mbtowc (&wc, str, limit - str);
02100 if (char_len == -1)
02101 {
02102 cpp_error (pfile, DL_WARNING,
02103 "ignoring invalid multibyte character");
02104 c = *str++;
02105 }
02106 else
02107 {
02108 str += char_len;
02109 c = wc;
02110 }
02111 #else
02112 c = *str++;
02113 #endif
02114
02115 if (c == '\\')
02116 c = cpp_parse_escape (pfile, &str, limit, token->type == CPP_WCHAR);
02117
02118 #ifdef MAP_CHARACTER
02119 if (ISPRINT (c))
02120 c = MAP_CHARACTER (c);
02121 #endif
02122
02123 chars_seen++;
02124
02125
02126 c &= mask;
02127 if (width < BITS_PER_CPPCHAR_T)
02128 result = (result << width) | c;
02129 else
02130 result = c;
02131 }
02132
02133 if (chars_seen == 0)
02134 cpp_error (pfile, DL_ERROR, "empty character constant");
02135 else if (chars_seen > 1)
02136 {
02137
02138 unsigned_p = 0;
02139
02140 if (chars_seen > max_chars)
02141 {
02142 chars_seen = max_chars;
02143 cpp_error (pfile, DL_WARNING,
02144 "character constant too long for its type");
02145 }
02146 else if (CPP_OPTION (pfile, warn_multichar))
02147 cpp_error (pfile, DL_WARNING, "multi-character character constant");
02148 }
02149
02150
02151
02152
02153 if (chars_seen > 1)
02154 width *= max_chars;
02155 if (width < BITS_PER_CPPCHAR_T)
02156 {
02157 mask = ((cppchar_t) 1 << width) - 1;
02158 if (unsigned_p || !(result & (1 << (width - 1))))
02159 result &= mask;
02160 else
02161 result |= ~mask;
02162 }
02163
02164 *pchars_seen = chars_seen;
02165 *unsignedp = unsigned_p;
02166 return result;
02167 }
02168
02169
02170
02171
02172
02173
02174
02175 #define MIN_BUFF_SIZE 8000
02176 #define BUFF_SIZE_UPPER_BOUND(MIN_SIZE) (MIN_BUFF_SIZE + (MIN_SIZE) * 3 / 2)
02177 #define EXTENDED_BUFF_SIZE(BUFF, MIN_EXTRA) \
02178 (MIN_EXTRA + ((BUFF)->limit - (BUFF)->cur) * 2)
02179
02180 #if MIN_BUFF_SIZE > BUFF_SIZE_UPPER_BOUND (0)
02181 #error BUFF_SIZE_UPPER_BOUND must be at least as large as MIN_BUFF_SIZE!
02182 #endif
02183
02184
02185
02186 static _cpp_buff *
02187 new_buff (len)
02188 size_t len;
02189 {
02190 _cpp_buff *result;
02191 unsigned char *base;
02192
02193 if (len < MIN_BUFF_SIZE)
02194 len = MIN_BUFF_SIZE;
02195 len = CPP_ALIGN (len);
02196
02197 base = xmalloc (len + sizeof (_cpp_buff));
02198 result = (_cpp_buff *) (base + len);
02199 result->base = base;
02200 result->cur = base;
02201 result->limit = base + len;
02202 result->next = NULL;
02203 return result;
02204 }
02205
02206
02207 void
02208 _cpp_release_buff (pfile, buff)
02209 cpp_reader *pfile;
02210 _cpp_buff *buff;
02211 {
02212 _cpp_buff *end = buff;
02213
02214 while (end->next)
02215 end = end->next;
02216 end->next = pfile->free_buffs;
02217 pfile->free_buffs = buff;
02218 }
02219
02220
02221 _cpp_buff *
02222 _cpp_get_buff (pfile, min_size)
02223 cpp_reader *pfile;
02224 size_t min_size;
02225 {
02226 _cpp_buff *result, **p;
02227
02228 for (p = &pfile->free_buffs;; p = &(*p)->next)
02229 {
02230 size_t size;
02231
02232 if (*p == NULL)
02233 return new_buff (min_size);
02234 result = *p;
02235 size = result->limit - result->base;
02236
02237
02238 if (size >= min_size && size <= BUFF_SIZE_UPPER_BOUND (min_size))
02239 break;
02240 }
02241
02242 *p = result->next;
02243 result->next = NULL;
02244 result->cur = result->base;
02245 return result;
02246 }
02247
02248
02249
02250
02251
02252 _cpp_buff *
02253 _cpp_append_extend_buff (pfile, buff, min_extra)
02254 cpp_reader *pfile;
02255 _cpp_buff *buff;
02256 size_t min_extra;
02257 {
02258 size_t size = EXTENDED_BUFF_SIZE (buff, min_extra);
02259 _cpp_buff *new_buff = _cpp_get_buff (pfile, size);
02260
02261 buff->next = new_buff;
02262 memcpy (new_buff->base, buff->cur, BUFF_ROOM (buff));
02263 return new_buff;
02264 }
02265
02266
02267
02268
02269
02270
02271 void
02272 _cpp_extend_buff (pfile, pbuff, min_extra)
02273 cpp_reader *pfile;
02274 _cpp_buff **pbuff;
02275 size_t min_extra;
02276 {
02277 _cpp_buff *new_buff, *old_buff = *pbuff;
02278 size_t size = EXTENDED_BUFF_SIZE (old_buff, min_extra);
02279
02280 new_buff = _cpp_get_buff (pfile, size);
02281 memcpy (new_buff->base, old_buff->cur, BUFF_ROOM (old_buff));
02282 new_buff->next = old_buff;
02283 *pbuff = new_buff;
02284 }
02285
02286
02287 void
02288 _cpp_free_buff (buff)
02289 _cpp_buff *buff;
02290 {
02291 _cpp_buff *next;
02292
02293 for (; buff; buff = next)
02294 {
02295 next = buff->next;
02296 free (buff->base);
02297 }
02298 }
02299
02300
02301 unsigned char *
02302 _cpp_unaligned_alloc (pfile, len)
02303 cpp_reader *pfile;
02304 size_t len;
02305 {
02306 _cpp_buff *buff = pfile->u_buff;
02307 unsigned char *result = buff->cur;
02308
02309 if (len > (size_t) (buff->limit - result))
02310 {
02311 buff = _cpp_get_buff (pfile, len);
02312 buff->next = pfile->u_buff;
02313 pfile->u_buff = buff;
02314 result = buff->cur;
02315 }
02316
02317 buff->cur = result + len;
02318 return result;
02319 }
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331 unsigned char *
02332 _cpp_aligned_alloc (pfile, len)
02333 cpp_reader *pfile;
02334 size_t len;
02335 {
02336 _cpp_buff *buff = pfile->a_buff;
02337 unsigned char *result = buff->cur;
02338
02339 if (len > (size_t) (buff->limit - result))
02340 {
02341 buff = _cpp_get_buff (pfile, len);
02342 buff->next = pfile->a_buff;
02343 pfile->a_buff = buff;
02344 result = buff->cur;
02345 }
02346
02347 buff->cur = result + len;
02348 return result;
02349 }