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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #ifdef _KEEP_RCS_ID
00103 static char *rcs_id = "$Source: /scratch/mee/2.4-65/kpro64-pending/be/whirl2c/SCCS/s.token_buffer.cxx $ $Revision: 1.2 $";
00104 #endif
00105
00106 #include <stdio.h>
00107 #include <string.h>
00108 #include "defs.h"
00109 #include "srcpos.h"
00110 #include "token_buffer.h"
00111 #include "errors.h"
00112 #include "mempool.h"
00113 #include "wn.h"
00114 #include "ir_reader.h"
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 #define strcpy DO_NOT_USE_STRCPY
00126
00127
00128
00129 #define TB_TYPE_ALLOC_N(type, count)\
00130 TYPE_MEM_POOL_ALLOC_N(type, Malloc_Mem_Pool, count)
00131
00132 #define TB_TYPE_REALLOC_N(type, old_ptr, old_count, new_count)\
00133 TYPE_MEM_POOL_REALLOC_N(type, Malloc_Mem_Pool, old_ptr,\
00134 old_count, new_count)
00135
00136 #define TB_FREE(ptr)\
00137 MEM_POOL_FREE(Malloc_Mem_Pool, ptr)
00138
00139
00140 #define SPACE ' '
00141 #define NEWLINE '\n'
00142 #define COMMA ','
00143 #define SEMICOLON ';'
00144 #define LEFT_PAREN '('
00145 #define RIGHT_PAREN ')'
00146 #define LEFT_BRACKET '['
00147 #define RIGHT_BRACKET ']'
00148 #define LEFT_BRACE '{'
00149 #define RIGHT_BRACE '}'
00150 #define PLUS '+'
00151 #define MINUS '-'
00152 #define MULTIPLY '*'
00153 #define DIVIDE '/'
00154 #define BITAND '&'
00155 #define BITOR '|'
00156 #define MODULUS '%'
00157 #define EQUAL '='
00158 #define QUESTION_MARK '?'
00159 #define COLON ':'
00160 #define LESS_THAN '<'
00161 #define LARGER_THAN '>'
00162 #define NOT '!'
00163 #define BIT_COMPLEMENT '~'
00164 #define FORTRAN_COMMENT_CHAR 'C'
00165
00166
00167 typedef mUINT32 STRING_IDX;
00168 typedef mUINT32 TOKEN_IDX;
00169 #define MAX_STRING_IDX (STRING_IDX)0x7fffffffU
00170 #define MAX_TOKEN_IDX (TOKEN_IDX)0x7fffffffU
00171 #define NO_STRING_IDX (STRING_IDX)0xffffffffU
00172 #define NO_TOKEN_IDX (TOKEN_IDX)0xffffffffU
00173 #define INIT_STRING_BUFFER_SIZE 1024
00174 #define INIT_TOKEN_BUFFER_SIZE 512
00175
00176 typedef enum Token_Kind
00177 {
00178 STRING_TOKEN = 0,
00179 SPECIAL_TOKEN = 1,
00180 SEPARATOR_TOKEN = 2,
00181 DIRECTIVE_TOKEN = 3,
00182 F77_SEQNO_TOKEN = 4,
00183 SRCPOS_MAP_TOKEN = 5,
00184 SRCPOS_DIRECTIVE_TOKEN = 6
00185 } TOKEN_KIND;
00186
00187 typedef struct String_Value
00188 {
00189 STRING_IDX size;
00190 union
00191 {
00192 char ch[sizeof(STRING_IDX)];
00193 STRING_IDX idx;
00194 } string;
00195 } STRING_VALUE;
00196
00197 typedef union Token_Value
00198 {
00199 SRCPOS srcpos;
00200 STRING_VALUE str_val;
00201 } TOKEN_VALUE;
00202
00203 typedef struct Token
00204 {
00205 TOKEN_KIND kind;
00206 TOKEN_IDX next;
00207 TOKEN_VALUE value;
00208 } TOKEN;
00209
00210 #define TOKEN_kind(t) (t)->kind
00211 #define TOKEN_next(t) (t)->next
00212 #define TOKEN_srcpos(t) (t)->value.srcpos
00213 #define TOKEN_char(t) (t)->value.str_val.string.ch[0]
00214 #define TOKEN_short_string(t) (t)->value.str_val.string.ch
00215 #define TOKEN_string_idx(t) (t)->value.str_val.string.idx
00216 #define TOKEN_string_size(t) (t)->value.str_val.size
00217
00218 #define TOKEN_is_short_string(t) (TOKEN_string_size(t) <= sizeof(STRING_IDX))
00219 #define TOKEN_is_string(t) \
00220 (TOKEN_kind(t) == STRING_TOKEN || \
00221 TOKEN_kind(t) == SPECIAL_TOKEN || \
00222 TOKEN_kind(t) == SEPARATOR_TOKEN || \
00223 TOKEN_kind(t) == DIRECTIVE_TOKEN || \
00224 TOKEN_kind(t) == F77_SEQNO_TOKEN)
00225
00226
00227 typedef struct Token_Sequence
00228 {
00229 TOKEN_IDX first;
00230 TOKEN_IDX last;
00231 } TOKEN_SEQUENCE;
00232
00233 struct Token_Buffer
00234 {
00235 char *strings;
00236 TOKEN *tokens;
00237 STRING_IDX chars_allocated;
00238 STRING_IDX chars_used;
00239 TOKEN_IDX tokens_allocated;
00240 TOKEN_IDX tokens_used;
00241 TOKEN_SEQUENCE token_list;
00242 TOKEN_BUFFER next;
00243 };
00244
00245
00246
00247
00248
00249
00250
00251
00252 #define TOKEN_BUFFER_get_char_string(buf, a_token)\
00253 (TOKEN_is_short_string(a_token)? \
00254 TOKEN_short_string(a_token) : \
00255 &buf->strings[TOKEN_string_idx(a_token)])
00256
00257
00258 static TOKEN_BUFFER buffer_free_list = NULL;
00259
00260
00261 #define WRITE_BUFFER_SIZE 256
00262 #define INVALID_SPLIT_PT -1
00263 static char write_buffer[WRITE_BUFFER_SIZE+1];
00264 static INT32 write_buffer_next = 0;
00265 static INT32 last_split_pt = INVALID_SPLIT_PT;
00266
00267
00268 #define MAX_INDENTATION 40
00269 #define MAX_INDENTATION_STEP 10
00270 static UINT32 indentation_increment = 2;
00271 static INT32 current_indentation = 0;
00272 static INT32 requested_indentation = 0;
00273
00274
00275
00276 #define USE_UNLIMITED_LINE_LENGTH (Max_Line_Length == 0)
00277 static UINT32 Max_Line_Length = 0;
00278 static FORMAT_KIND Output_Format = FREE_FORMAT;
00279
00280
00281
00282
00283
00284 static UINT32 Current_Output_Col = 1;
00285 static UINT32 Current_Output_Line = 1;
00286
00287
00288
00289
00290 static UINT32 Max_Srcpos_Map_Filenum = 0;
00291
00292
00293
00294
00295 static UINT32 Default_Max_Line_Length[NUM_FORMAT_KINDS+1] =
00296 {
00297 0,
00298 0,
00299 72
00300 };
00301
00302
00303
00304
00305 #define MAX_F77_DIRECTIVE_PREFIX_SIZE 24
00306 static BOOL Inside_F77_Directive = FALSE;
00307 static UINT32 Max_Line_Length_Outside_F77_Directive;
00308 static char F77_Directive_Continuation[MAX_F77_DIRECTIVE_PREFIX_SIZE+1];
00309
00310
00311
00312 static BOOL Emit_Prompf_Srcpos_Map = FALSE;
00313
00314
00315
00316
00317
00318 #define DBGOUT stderr
00319
00320 void
00321 dbg_tokens(TOKEN_BUFFER buf, BOOL with_token_name)
00322 {
00323 const char *str;
00324 STRING_IDX c;
00325 TOKEN_IDX t;
00326 TOKEN *a_token;
00327 USRCPOS usrcpos;
00328
00329 for (t = buf->token_list.first; t != NO_TOKEN_IDX; t = TOKEN_next(a_token))
00330 {
00331 a_token = &buf->tokens[t];
00332
00333 switch (TOKEN_kind(a_token))
00334 {
00335 case F77_SEQNO_TOKEN:
00336 if (with_token_name)
00337 fputs("F77_SEQNO_TOKEN(", DBGOUT);
00338 str = TOKEN_BUFFER_get_char_string(buf, a_token);
00339 for (c = 0; c < TOKEN_string_size(a_token); c++)
00340 fputc(str[c], DBGOUT);
00341 break;
00342
00343 case STRING_TOKEN:
00344 if (with_token_name)
00345 fputs("STRING_TOKEN(", DBGOUT);
00346 str = TOKEN_BUFFER_get_char_string(buf, a_token);
00347 for (c = 0; c < TOKEN_string_size(a_token); c++)
00348 fputc(str[c], DBGOUT);
00349 break;
00350
00351 case SEPARATOR_TOKEN:
00352 if (with_token_name)
00353 fputs("SEPARATOR_TOKEN(", DBGOUT);
00354 str = TOKEN_BUFFER_get_char_string(buf, a_token);
00355 for (c = 0; c < TOKEN_string_size(a_token); c++)
00356 fputc(str[c], DBGOUT);
00357 break;
00358
00359 case DIRECTIVE_TOKEN:
00360 if (with_token_name)
00361 fputs("DIRECTIVE_TOKEN(", DBGOUT);
00362 str = TOKEN_BUFFER_get_char_string(buf, a_token);
00363 for (c = 0; c < TOKEN_string_size(a_token); c++)
00364 fputc(str[c], DBGOUT);
00365 break;
00366
00367 case SPECIAL_TOKEN:
00368 if (with_token_name)
00369 fputs("SPECIAL_TOKEN(", DBGOUT);
00370 fputc(TOKEN_char(a_token), DBGOUT);
00371 break;
00372
00373 case SRCPOS_MAP_TOKEN:
00374 USRCPOS_srcpos(usrcpos) = TOKEN_srcpos(a_token);
00375 fprintf(DBGOUT,
00376 "SRCPOS_MAP(%d, %d, %d)",
00377 USRCPOS_column(usrcpos),
00378 USRCPOS_linenum(usrcpos),
00379 USRCPOS_filenum(usrcpos));
00380 break;
00381
00382 case SRCPOS_DIRECTIVE_TOKEN:
00383 USRCPOS_srcpos(usrcpos) = TOKEN_srcpos(a_token);
00384 fprintf(DBGOUT,
00385 "SRCPOS_DIRECTIVE(%d, %d, %d)",
00386 USRCPOS_column(usrcpos),
00387 USRCPOS_linenum(usrcpos),
00388 USRCPOS_filenum(usrcpos));
00389 break;
00390
00391 default:
00392 Is_True(FALSE, ("Attempt to write invalid token kind"));
00393 break;
00394 }
00395 if (with_token_name)
00396 fputs(")\n", DBGOUT);
00397 }
00398 if (!with_token_name)
00399 fputs("\n", DBGOUT);
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409 #define CAN_SPLIT_LINE (last_split_pt != INVALID_SPLIT_PT)
00410 #define NEED_TO_SPLIT_LINE \
00411 (!USE_UNLIMITED_LINE_LENGTH && Current_Output_Col > Max_Line_Length)
00412
00413 #ifdef BUILD_WHIRL2F
00414 #define is_binary_or_tertiary_op(c) \
00415 (c==PLUS || \
00416 c==MINUS || \
00417 c==MULTIPLY || \
00418 c==DIVIDE || \
00419 c==BITAND || \
00420 c==BITOR || \
00421 c==EQUAL || \
00422 c==NOT || \
00423 c==QUESTION_MARK || \
00424 c==COLON || \
00425 c==LESS_THAN || \
00426 c==LARGER_THAN)
00427 #else
00428 #define is_binary_or_tertiary_op(c) \
00429 (c==PLUS || \
00430 c==MINUS || \
00431 c==MULTIPLY || \
00432 c==DIVIDE || \
00433 c==BITAND || \
00434 c==BITOR || \
00435 c==MODULUS || \
00436 c==EQUAL || \
00437 c==NOT || \
00438 c==QUESTION_MARK || \
00439 c==COLON || \
00440 c==LESS_THAN || \
00441 c==LARGER_THAN)
00442 #endif
00443
00444 #define is_begin_grouping(c) \
00445 (c==LEFT_PAREN || \
00446 c==LEFT_BRACKET || \
00447 c==LEFT_BRACE)
00448
00449 #define is_end_grouping(c) \
00450 (c==RIGHT_PAREN || \
00451 c==RIGHT_BRACKET || \
00452 c==RIGHT_BRACE)
00453
00454
00455
00456
00457
00458 #define is_unary_op(c1, c2) \
00459 ((is_binary_or_tertiary_op(c1) || \
00460 is_begin_grouping(c1) || \
00461 is_comma_or_semicolon(c1)) && \
00462 is_binary_or_tertiary_op(c2) && \
00463 c1 != c2 && \
00464 c2 != EQUAL && \
00465 !is_end_grouping(c1) && \
00466 !(c1==MINUS && c2==LARGER_THAN))
00467
00468
00469 #define is_comma_or_semicolon(c) (c==COMMA || c==SEMICOLON)
00470
00471
00472 static TOKEN_IDX
00473 get_new_tokens(TOKEN_BUFFER buf, INT number_of_tokens)
00474 {
00475
00476
00477
00478 const TOKEN_IDX return_idx = buf->tokens_used;
00479 TOKEN_IDX max_tokens = buf->tokens_allocated;
00480
00481 buf->tokens_used += number_of_tokens;
00482 Is_True(buf->tokens_used < MAX_TOKEN_IDX, ("Too many tokens!"));
00483 if (buf->tokens_used > max_tokens)
00484 {
00485
00486
00487
00488 if (max_tokens < 0x2000)
00489 do {
00490 max_tokens *= 2;
00491 } while (buf->tokens_used > max_tokens);
00492 else
00493 do {
00494 max_tokens += 0x2000;
00495 } while (buf->tokens_used > max_tokens);
00496
00497 buf->tokens =
00498 TB_TYPE_REALLOC_N(TOKEN,
00499 buf->tokens,
00500 buf->tokens_allocated,
00501 max_tokens);
00502 buf->tokens_allocated = max_tokens;
00503 }
00504 return (return_idx);
00505 }
00506
00507
00508 static STRING_IDX
00509 get_new_string(TOKEN_BUFFER buf, INT16 stringsize)
00510 {
00511
00512
00513
00514 const STRING_IDX return_idx = buf->chars_used;
00515 STRING_IDX max_chars = buf->chars_allocated;
00516
00517 buf->chars_used += stringsize;
00518 Is_True(buf->chars_used < MAX_STRING_IDX, ("Too many output characters!"));
00519 if (buf->chars_used > max_chars)
00520 {
00521
00522
00523
00524 if (max_chars < 0x8000)
00525 do {
00526 max_chars *= 2;
00527 } while (buf->chars_used > max_chars);
00528 else
00529 do {
00530 max_chars += 0x8000;
00531 } while (buf->chars_used > max_chars);
00532
00533 buf->strings =
00534 TB_TYPE_REALLOC_N(char,
00535 buf->strings,
00536 buf->chars_allocated,
00537 max_chars);
00538 buf->chars_allocated = max_chars;
00539 }
00540 return return_idx;
00541 }
00542
00543
00544 static char *
00545 Allocate_Token_String(TOKEN_BUFFER buf, TOKEN *a_token, STRING_IDX str_size)
00546 {
00547 char *str;
00548
00549 TOKEN_string_size(a_token) = str_size;
00550 if (TOKEN_is_short_string(a_token))
00551 {
00552 str = TOKEN_short_string(a_token);
00553 }
00554 else
00555 {
00556 TOKEN_string_idx(a_token) =
00557 get_new_string(buf, TOKEN_string_size(a_token));
00558 str = TOKEN_BUFFER_get_char_string(buf, a_token);
00559 }
00560 return str;
00561 }
00562
00563
00564 static void
00565 free_buffer_list(TOKEN_BUFFER free_list)
00566 {
00567 TOKEN_BUFFER to_be_freed, next = free_list;
00568
00569 while (next != NULL)
00570 {
00571 TB_FREE(next->strings);
00572 TB_FREE(next->tokens);
00573 to_be_freed = next;
00574 next = next->next;
00575 TB_FREE(to_be_freed);
00576 }
00577 }
00578
00579
00580 static TOKEN_IDX
00581 indented_newline_token(TOKEN_BUFFER buffer,
00582 UINT num_lines,
00583 BOOL continuation,
00584 const char *label)
00585 {
00586
00587
00588
00589
00590
00591
00592 char *str;
00593 STRING_IDX char_idx;
00594 INT32 label_size = (label==NULL? 0 : strlen(label));
00595 INT32 prefix_size;
00596 TOKEN_IDX new_token_idx = get_new_tokens(buffer, 1);
00597 TOKEN *a_token = &buffer->tokens[new_token_idx];
00598
00599 Is_True(label_size < 6, ("Too large label at beginning for Fortran line"));
00600
00601
00602 if (Output_Format == FREE_FORMAT)
00603 prefix_size = 0;
00604 else if (Output_Format == F77_TAB_FORMAT)
00605 prefix_size = label_size + (continuation? 2 : 1);
00606 else if (Output_Format == F77_ANSI_FORMAT)
00607 prefix_size = 6;
00608
00609
00610 TOKEN_kind(a_token) = SEPARATOR_TOKEN;
00611 TOKEN_next(a_token) = NO_TOKEN_IDX;
00612 str = Allocate_Token_String(buffer, a_token,
00613 prefix_size + current_indentation + num_lines);
00614
00615
00616
00617
00618 for (char_idx = 0; char_idx < num_lines; char_idx++)
00619 str[char_idx] = NEWLINE;
00620
00621
00622 if (label_size > 0)
00623 {
00624 (void)strncpy(&str[char_idx], &label[0], label_size);
00625 char_idx += label_size;
00626 }
00627
00628
00629
00630
00631 if (Output_Format == F77_TAB_FORMAT)
00632 {
00633 str[char_idx++] = '\t';
00634 if (continuation)
00635 str[char_idx++] = '1';
00636 }
00637 else if (Output_Format == F77_ANSI_FORMAT && continuation)
00638 {
00639 while (char_idx < num_lines + prefix_size - 1)
00640 str[char_idx++] = SPACE;
00641 str[char_idx++] = '>';
00642 }
00643
00644
00645 while (char_idx < num_lines + prefix_size + current_indentation)
00646 str[char_idx++] = SPACE;
00647
00648 return new_token_idx;
00649 }
00650
00651
00652 static TOKEN_IDX
00653 F77_comment_line_token(TOKEN_BUFFER buffer,
00654 UINT num_lines,
00655 const char *comment_prefix,
00656 BOOL indent_last_line)
00657 {
00658
00659
00660
00661
00662
00663
00664
00665 const INT32 comment_prefix_size = strlen(comment_prefix);
00666 char indentation_str[MAX_INDENTATION+50];
00667 INT32 indentation_size;
00668 INT32 num_spaces, lines;
00669 char *str;
00670 TOKEN_IDX new_token_idx = get_new_tokens(buffer, 1);
00671 TOKEN *a_token = &buffer->tokens[new_token_idx];
00672
00673
00674
00675 strncpy(indentation_str, comment_prefix, comment_prefix_size);
00676 indentation_size = comment_prefix_size;
00677 if (indent_last_line)
00678 {
00679
00680
00681
00682 if (Output_Format == F77_TAB_FORMAT)
00683 {
00684 indentation_str[indentation_size++] = '\t';
00685 }
00686 else
00687 {
00688 while (indentation_size < 6)
00689 indentation_str[indentation_size++] = SPACE;
00690 }
00691 for (num_spaces = 0; num_spaces < current_indentation; num_spaces++)
00692 {
00693 indentation_str[indentation_size++] = SPACE;
00694 }
00695 }
00696
00697
00698 TOKEN_kind(a_token) = SEPARATOR_TOKEN;
00699 TOKEN_next(a_token) = NO_TOKEN_IDX;
00700 str = Allocate_Token_String(buffer, a_token,
00701 num_lines +
00702 (num_lines - 1)*comment_prefix_size +
00703 indentation_size);
00704
00705
00706 for (lines = 1; lines < num_lines; lines++)
00707 {
00708 *str++ = NEWLINE;
00709 str = strncpy(str, comment_prefix, comment_prefix_size);
00710 str += comment_prefix_size;
00711 }
00712 *str++ = NEWLINE;
00713
00714
00715 str = strncpy(str, indentation_str, indentation_size);
00716
00717 return new_token_idx;
00718 }
00719
00720
00721 static TOKEN_IDX
00722 F77_directive_line_token(TOKEN_BUFFER buffer,
00723 const char *directive_prefix)
00724 {
00725
00726
00727
00728
00729
00730
00731 const INT32 directive_prefix_size = strlen(directive_prefix);
00732 char *str;
00733 TOKEN_IDX new_token_idx = get_new_tokens(buffer, 1);
00734 TOKEN *a_token = &buffer->tokens[new_token_idx];
00735
00736
00737
00738 TOKEN_kind(a_token) = DIRECTIVE_TOKEN;
00739 TOKEN_next(a_token) = NO_TOKEN_IDX;
00740 str = Allocate_Token_String(buffer, a_token,
00741 1 + directive_prefix_size);
00742
00743
00744
00745 *str++ = NEWLINE;
00746 str = strncpy(str, directive_prefix, directive_prefix_size);
00747
00748 return new_token_idx;
00749 }
00750
00751
00752 static TOKEN_IDX
00753 string_token(TOKEN_BUFFER buffer, const char *string)
00754 {
00755 char *str;
00756 TOKEN_IDX new_token_idx = get_new_tokens(buffer, 1);
00757 TOKEN *a_token = &buffer->tokens[new_token_idx];
00758
00759
00760 TOKEN_kind(a_token) = STRING_TOKEN;
00761 TOKEN_next(a_token) = NO_TOKEN_IDX;
00762 str = Allocate_Token_String(buffer, a_token, strlen(string));
00763
00764
00765 (void)strncpy(str, string, TOKEN_string_size(a_token));
00766
00767 return new_token_idx;
00768 }
00769
00770
00771 static TOKEN_IDX
00772 f77_seqno_token(TOKEN_BUFFER buffer, const char *seqno)
00773 {
00774 TOKEN_IDX idx = string_token(buffer, seqno);
00775 TOKEN_kind(&buffer->tokens[idx]) = F77_SEQNO_TOKEN;
00776 return idx;
00777 }
00778
00779
00780 static TOKEN_IDX
00781 special_char_token(TOKEN_BUFFER buffer, char special)
00782 {
00783 const TOKEN_IDX new_token_idx = get_new_tokens(buffer, 1);
00784 TOKEN *a_token = &buffer->tokens[new_token_idx];
00785
00786
00787 TOKEN_kind(a_token) = SPECIAL_TOKEN;
00788 TOKEN_next(a_token) = NO_TOKEN_IDX;
00789 TOKEN_char(a_token) = special;
00790 TOKEN_string_size(a_token) = 1;
00791
00792 return new_token_idx;
00793 }
00794
00795
00796 static TOKEN_IDX
00797 Srcpos_Map_Token(TOKEN_BUFFER buffer, SRCPOS srcpos)
00798 {
00799 const TOKEN_IDX new_token_idx = get_new_tokens(buffer, 1);
00800 TOKEN *a_token = &buffer->tokens[new_token_idx];
00801
00802
00803 TOKEN_kind(a_token) = SRCPOS_MAP_TOKEN;
00804 TOKEN_next(a_token) = NO_TOKEN_IDX;
00805 TOKEN_srcpos(a_token) = srcpos;
00806
00807 return new_token_idx;
00808 }
00809
00810
00811 static TOKEN_IDX
00812 Srcpos_Directive_Token(TOKEN_BUFFER buffer, SRCPOS srcpos)
00813 {
00814 const TOKEN_IDX new_token_idx = get_new_tokens(buffer, 1);
00815 TOKEN *a_token = &buffer->tokens[new_token_idx];
00816
00817
00818 TOKEN_kind(a_token) = SRCPOS_DIRECTIVE_TOKEN;
00819 TOKEN_next(a_token) = NO_TOKEN_IDX;
00820 TOKEN_srcpos(a_token) = srcpos;
00821
00822 return new_token_idx;
00823 }
00824
00825
00826 static TOKEN_SEQUENCE
00827 copy_token_list(TOKEN_BUFFER to_buffer, TOKEN_BUFFER from_buffer)
00828 {
00829
00830
00831
00832
00833
00834
00835 TOKEN_IDX token_offset, from_idx;
00836 STRING_IDX char_offset, char_idx;
00837 TOKEN *new_token;
00838 TOKEN_SEQUENCE token_list;
00839
00840 if (from_buffer->tokens_used == 0)
00841 {
00842 token_list.first = NO_TOKEN_IDX;
00843 token_list.last = NO_TOKEN_IDX;
00844 }
00845 else
00846 {
00847
00848
00849
00850
00851 token_offset = get_new_tokens(to_buffer, from_buffer->tokens_used);
00852 char_offset = get_new_string(to_buffer, from_buffer->chars_used);
00853 token_list.first = from_buffer->token_list.first + token_offset;
00854 token_list.last = from_buffer->token_list.last + token_offset;
00855
00856
00857
00858 for (char_idx = 0; char_idx < from_buffer->chars_used; char_idx++)
00859 to_buffer->strings[char_offset + char_idx] =
00860 from_buffer->strings[char_idx];
00861
00862
00863
00864
00865 for (from_idx = 0; from_idx < from_buffer->tokens_used; from_idx++)
00866 {
00867 new_token = &to_buffer->tokens[token_offset + from_idx];
00868 *new_token = from_buffer->tokens[from_idx];
00869 TOKEN_next(new_token) += token_offset;
00870
00871
00872 if (TOKEN_is_string(new_token) && !TOKEN_is_short_string(new_token))
00873 TOKEN_string_idx(new_token) += char_offset;
00874 }
00875
00876
00877 to_buffer->tokens[token_list.last].next = NO_TOKEN_IDX;
00878 }
00879 return token_list;
00880 }
00881
00882
00883 static void
00884 append_token_list(TOKEN_BUFFER buffer, TOKEN_SEQUENCE token_list)
00885 {
00886 Is_True(token_list.first != NO_TOKEN_IDX,
00887 ("Cannot append empty token_sequence"));
00888 if (buffer->token_list.first == NO_TOKEN_IDX)
00889 buffer->token_list.first = token_list.first;
00890 else
00891 TOKEN_next(&buffer->tokens[buffer->token_list.last]) = token_list.first;
00892 buffer->token_list.last = token_list.last;
00893 }
00894
00895
00896 static void
00897 prepend_token_list(TOKEN_BUFFER buffer, TOKEN_SEQUENCE token_list)
00898 {
00899 Is_True(token_list.first != NO_TOKEN_IDX,
00900 ("Cannot prepend empty token_sequence"));
00901 if (buffer->token_list.last == NO_TOKEN_IDX)
00902 buffer->token_list.last = token_list.last;
00903 else
00904 TOKEN_next(&buffer->tokens[token_list.last]) = buffer->token_list.first;
00905 buffer->token_list.first = token_list.first;
00906 }
00907
00908
00909 static void
00910 write_into_string_buf(const char *from,
00911 UINT from_size,
00912 char **into,
00913 UINT *into_size)
00914 {
00915
00916
00917
00918
00919 if (from_size >= *into_size)
00920 {
00921 fprintf(stderr,
00922 "ERROR: -flist/-clist string-buffer overflow in"
00923 "write_into_string_buf() !");
00924 from_size = *into_size - 1;
00925 }
00926 if (from_size > 0)
00927 {
00928 strncpy(*into, from, from_size);
00929 *into = *into + from_size;
00930 *into_size -= from_size;
00931 }
00932 }
00933
00934
00935 static void
00936 flush_write_buffer(FILE *ofile, char **buffer, UINT *buflen)
00937 {
00938
00939
00940
00941
00942
00943
00944 UINT32 buffer_idx;
00945 char saved_ch;
00946
00947 if (write_buffer_next > 0)
00948 {
00949
00950
00951
00952
00953
00954
00955 if (last_split_pt > 0 && last_split_pt < write_buffer_next)
00956 {
00957 saved_ch = write_buffer[last_split_pt];
00958 write_buffer[last_split_pt] = '\0';
00959 if (ofile != NULL)
00960 fputs(&write_buffer[0], ofile);
00961 else
00962 write_into_string_buf(
00963 &write_buffer[0], last_split_pt, buffer, buflen);
00964
00965
00966
00967
00968 write_buffer[0] = saved_ch;
00969 for (buffer_idx = 1;
00970 buffer_idx+last_split_pt < write_buffer_next;
00971 buffer_idx++)
00972 {
00973 write_buffer[buffer_idx] = write_buffer[buffer_idx+last_split_pt];
00974 }
00975 last_split_pt = 0;
00976 write_buffer_next = buffer_idx;
00977 }
00978 else
00979 {
00980 write_buffer[write_buffer_next] = '\0';
00981 if (ofile != NULL)
00982 fputs(&write_buffer[0], ofile);
00983 else
00984 write_into_string_buf(
00985 &write_buffer[0], write_buffer_next, buffer, buflen);
00986 if (last_split_pt == write_buffer_next)
00987 last_split_pt = 0;
00988 else
00989 last_split_pt = INVALID_SPLIT_PT;
00990 write_buffer_next = 0;
00991 }
00992 }
00993 }
00994
00995
00996 static void Output_Character(FILE *ofile, char **strbuf, UINT *strlen, char c);
00997
00998 static void
00999 Split_The_Current_Output_Line(FILE *ofile,
01000 char **strbuf,
01001 UINT *strlen)
01002 {
01003 UINT32 idx;
01004 UINT32 num_chars_after_split;
01005 const char *continuation_prefix;
01006 char tmp_buffer[WRITE_BUFFER_SIZE+1];
01007 const BOOL is_inside_directive = Inside_F77_Directive;
01008
01009
01010
01011
01012 for (idx = last_split_pt; idx < write_buffer_next; idx++)
01013 {
01014 tmp_buffer[idx - last_split_pt] = write_buffer[idx];
01015 }
01016 num_chars_after_split = write_buffer_next - last_split_pt;
01017
01018
01019 if (is_inside_directive)
01020 {
01021 continuation_prefix = &F77_Directive_Continuation[0];
01022 Inside_F77_Directive = FALSE;
01023 }
01024 else if (Output_Format == FREE_FORMAT)
01025 continuation_prefix = "\\\n";
01026 else if (Output_Format == F77_TAB_FORMAT)
01027 continuation_prefix = "\n\t1 ";
01028 else
01029 continuation_prefix = "\n > ";
01030
01031
01032
01033
01034
01035 write_buffer_next = last_split_pt;
01036 last_split_pt = INVALID_SPLIT_PT;
01037 Current_Output_Col -= num_chars_after_split;
01038 Inside_F77_Directive = FALSE;
01039 for (idx = 0; continuation_prefix[idx] != '\0'; idx++)
01040 Output_Character(ofile, strbuf, strlen, continuation_prefix[idx]);
01041 for (idx = 0; idx < num_chars_after_split; idx++)
01042 Output_Character(ofile, strbuf, strlen, tmp_buffer[idx]);
01043
01044 Inside_F77_Directive = is_inside_directive;
01045 }
01046
01047
01048 static void
01049 Output_Character(FILE *ofile,
01050 char **strbuf,
01051 UINT *strlen,
01052 char c)
01053 {
01054
01055 if (write_buffer_next+1 >= WRITE_BUFFER_SIZE)
01056 flush_write_buffer(ofile, strbuf, strlen);
01057
01058
01059 write_buffer[write_buffer_next++] = c;
01060
01061
01062 if (c == '\n')
01063 {
01064 Current_Output_Col = 1;
01065 Current_Output_Line++;
01066 last_split_pt = INVALID_SPLIT_PT;
01067 if (Inside_F77_Directive)
01068 {
01069 Inside_F77_Directive = FALSE;
01070 Max_Line_Length = Max_Line_Length_Outside_F77_Directive;
01071 }
01072 }
01073 else
01074 {
01075 Current_Output_Col++;
01076 }
01077
01078 if (NEED_TO_SPLIT_LINE && CAN_SPLIT_LINE)
01079 Split_The_Current_Output_Line(ofile, strbuf, strlen);
01080
01081 }
01082
01083
01084 static void
01085 Output_Srcpos_Map(FILE *mapfile, SRCPOS srcpos)
01086 {
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098 INT32 status;
01099 USRCPOS usrcpos;
01100
01101 if (srcpos != 0)
01102 {
01103 USRCPOS_srcpos(usrcpos) = srcpos;
01104
01105
01106
01107
01108 if (USRCPOS_filenum(usrcpos) > Max_Srcpos_Map_Filenum)
01109 Max_Srcpos_Map_Filenum = USRCPOS_filenum(usrcpos);
01110
01111 if (Emit_Prompf_Srcpos_Map)
01112 status = fprintf(mapfile,
01113 " [%u %u]-->[%u %u %u]\n",
01114 Current_Output_Line,
01115 Current_Output_Col,
01116 USRCPOS_filenum(usrcpos),
01117 USRCPOS_linenum(usrcpos),
01118 USRCPOS_column(usrcpos));
01119 else
01120 status = fprintf(mapfile,
01121 " ((%u %u) (%u %u %u))\n",
01122 Current_Output_Line,
01123 Current_Output_Col,
01124 USRCPOS_filenum(usrcpos),
01125 USRCPOS_linenum(usrcpos),
01126 USRCPOS_column(usrcpos));
01127
01128 Is_True(status >= 0, ("Output error to srcpos mapping file"));
01129 }
01130 }
01131
01132
01133 static void
01134 Output_Srcpos_Directive(FILE *ofile,
01135 char **strbuf,
01136 UINT *strlen,
01137 SRCPOS srcpos)
01138 {
01139
01140
01141
01142
01143
01144
01145
01146
01147 char Srcpos_Directive[1024];
01148 const char *fname;
01149 const char *dirname;
01150 STRING_IDX ch_idx;
01151 USRCPOS usrcpos;
01152
01153 if (srcpos != 0)
01154 {
01155 IR_Srcpos_Filename(srcpos, &fname, &dirname);
01156 USRCPOS_srcpos(usrcpos) = srcpos;
01157 if (fname != NULL && dirname != NULL)
01158 {
01159 sprintf(Srcpos_Directive,
01160 "\n#line %d \"%s/%s\"",
01161 USRCPOS_linenum(usrcpos), dirname, fname);
01162 }
01163 else if (fname != NULL)
01164 {
01165 sprintf(Srcpos_Directive,
01166 "\n#line %d \"%s\"", USRCPOS_linenum(usrcpos), fname);
01167 }
01168 else
01169 {
01170 sprintf(Srcpos_Directive, "\n#line %d", USRCPOS_linenum(usrcpos));
01171 }
01172
01173
01174
01175 for (ch_idx = 0; Srcpos_Directive[ch_idx] != '\0'; ch_idx++)
01176 Output_Character(ofile, strbuf, strlen, Srcpos_Directive[ch_idx]);
01177 }
01178 }
01179
01180
01181 static void
01182 write_token(FILE *ofile,
01183 char **strbuf,
01184 UINT *strlen,
01185 TOKEN_BUFFER buffer,
01186 TOKEN_IDX this_token)
01187 {
01188 const char *str;
01189 STRING_IDX ch_idx;
01190 TOKEN *a_token = &buffer->tokens[this_token];
01191
01192 Is_True(this_token != NO_TOKEN_IDX, ("Cannot write non-existent token"));
01193
01194 switch (TOKEN_kind(a_token))
01195 {
01196 case F77_SEQNO_TOKEN:
01197
01198
01199
01200 for (ch_idx = Current_Output_Col; ch_idx < 73; ch_idx++)
01201 Output_Character(ofile, strbuf, strlen, SPACE);
01202
01203 str = TOKEN_BUFFER_get_char_string(buffer, a_token);
01204 for (ch_idx = 0; ch_idx < TOKEN_string_size(a_token); ch_idx++)
01205 Output_Character(ofile, strbuf, strlen, str[ch_idx]);
01206 break;
01207
01208 case STRING_TOKEN:
01209 str = TOKEN_BUFFER_get_char_string(buffer, a_token);
01210 for (ch_idx = 0; ch_idx < TOKEN_string_size(a_token); ch_idx++)
01211 Output_Character(ofile, strbuf, strlen, str[ch_idx]);
01212 last_split_pt = write_buffer_next;
01213 break;
01214
01215 case SEPARATOR_TOKEN:
01216 str = TOKEN_BUFFER_get_char_string(buffer, a_token);
01217 for (ch_idx = 0; ch_idx < TOKEN_string_size(a_token); ch_idx++)
01218 Output_Character(ofile, strbuf, strlen, str[ch_idx]);
01219 break;
01220
01221 case DIRECTIVE_TOKEN:
01222
01223
01224 str = TOKEN_BUFFER_get_char_string(buffer, a_token);
01225 for (ch_idx = 0; ch_idx < TOKEN_string_size(a_token); ch_idx++)
01226 Output_Character(ofile, strbuf, strlen, str[ch_idx]);
01227
01228
01229
01230
01231 Is_True(TOKEN_string_size(a_token) < MAX_F77_DIRECTIVE_PREFIX_SIZE-2,
01232 ("Too large directive prefix (max = %d)",
01233 MAX_F77_DIRECTIVE_PREFIX_SIZE-2));
01234
01235 Inside_F77_Directive = TRUE;
01236 Max_Line_Length_Outside_F77_Directive = Max_Line_Length;
01237 Max_Line_Length = 72;
01238 strncpy(&F77_Directive_Continuation[0], &str[0],
01239 TOKEN_string_size(a_token));
01240 F77_Directive_Continuation[TOKEN_string_size(a_token)] = '&';
01241 F77_Directive_Continuation[TOKEN_string_size(a_token)+1] = ' ';
01242 F77_Directive_Continuation[TOKEN_string_size(a_token)+2] = '\0';
01243 break;
01244
01245
01246 case SPECIAL_TOKEN:
01247 Output_Character(ofile, strbuf, strlen, TOKEN_char(a_token));
01248 last_split_pt = write_buffer_next;
01249 break;
01250
01251 case SRCPOS_MAP_TOKEN:
01252 Is_True(ofile != NULL, ("Cannot source position mapping to file"));
01253 Output_Srcpos_Map(ofile, TOKEN_srcpos(a_token));
01254 break;
01255
01256 case SRCPOS_DIRECTIVE_TOKEN:
01257 Output_Srcpos_Directive(ofile, strbuf, strlen, TOKEN_srcpos(a_token));
01258 break;
01259
01260 default:
01261 Is_True(FALSE, ("Attempt to write non-existent token"));
01262 break;
01263 }
01264 }
01265
01266
01267 static void
01268 write_separator(FILE *ofile,
01269 char **strbuf,
01270 UINT *strlen,
01271 TOKEN_BUFFER buffer,
01272 TOKEN_IDX idx1,
01273 TOKEN_IDX idx2)
01274 {
01275 BOOL separate;
01276 static UINT16 previous_token_kind = SEPARATOR_TOKEN;
01277 static char previous_token_ch = '\0';
01278
01279 if (idx1 == NO_TOKEN_IDX || idx2 == NO_TOKEN_IDX)
01280 {
01281 previous_token_kind = SEPARATOR_TOKEN;
01282 previous_token_ch = '\0';
01283 separate = FALSE;
01284 }
01285 else
01286 {
01287 TOKEN *a_token1 = &buffer->tokens[idx1];
01288 TOKEN *a_token2 = &buffer->tokens[idx2];
01289 const UINT16 kind1 = TOKEN_kind(a_token1);
01290 const UINT16 kind2 = TOKEN_kind(a_token2);
01291 char ch1 = (kind1 == SPECIAL_TOKEN? TOKEN_char(a_token1) : 'a');
01292 char ch2 = (kind2 == SPECIAL_TOKEN? TOKEN_char(a_token2) : 'a');
01293
01294 if (kind1 == SEPARATOR_TOKEN ||
01295 kind1 == DIRECTIVE_TOKEN ||
01296 kind1 == SRCPOS_DIRECTIVE_TOKEN ||
01297 kind1 == SRCPOS_MAP_TOKEN ||
01298 kind2 == SEPARATOR_TOKEN ||
01299 kind2 == DIRECTIVE_TOKEN ||
01300 kind2 == SRCPOS_DIRECTIVE_TOKEN ||
01301 kind2 == SRCPOS_MAP_TOKEN)
01302 separate = FALSE;
01303 else if (kind1 == STRING_TOKEN && kind2 == STRING_TOKEN)
01304 separate = TRUE;
01305 else if (kind1 == STRING_TOKEN && kind2 == SPECIAL_TOKEN)
01306 separate = (is_binary_or_tertiary_op(ch2) || ch2 == LEFT_BRACE);
01307 else if (kind1 == SPECIAL_TOKEN && kind2 == STRING_TOKEN)
01308 separate = ((is_binary_or_tertiary_op(ch1) &&
01309 !(previous_token_kind == SPECIAL_TOKEN &&
01310 is_unary_op(previous_token_ch, ch1))) ||
01311 is_end_grouping(ch1) ||
01312 is_comma_or_semicolon(ch1));
01313 else if (kind1 == SPECIAL_TOKEN && kind2 == SPECIAL_TOKEN)
01314 separate = (is_comma_or_semicolon(ch1) ||
01315 (is_binary_or_tertiary_op(ch1) &&
01316 is_begin_grouping(ch2) &&
01317 !is_unary_op(previous_token_ch, ch1)) ||
01318 (is_end_grouping(ch1) &&
01319 is_binary_or_tertiary_op(ch2)) ||
01320 (!is_begin_grouping(ch1) &&
01321 is_unary_op(ch1, ch2)));
01322 else
01323 Is_True(FALSE, ("Illegal token to separate"));
01324
01325 previous_token_kind = kind1;
01326 previous_token_ch = ch1;
01327 }
01328 if (separate)
01329 Output_Character(ofile, strbuf, strlen, SPACE);
01330 }
01331
01332 static void
01333 write_F77_separator(FILE *ofile,
01334 char **strbuf,
01335 UINT *strlen,
01336 TOKEN_BUFFER buffer,
01337 TOKEN_IDX idx1,
01338 TOKEN_IDX idx2)
01339 {
01340
01341
01342
01343 write_separator(ofile, strbuf, strlen, buffer, idx1, idx2);
01344 }
01345
01346
01347 static TOKEN_IDX
01348 Skip_Srcpos_Map(FILE *srcpos_map_file, TOKEN_BUFFER buf, TOKEN_IDX token_idx)
01349 {
01350 TOKEN_IDX return_idx;
01351
01352 if (token_idx == NO_TOKEN_IDX ||
01353 TOKEN_kind(&buf->tokens[token_idx]) != SRCPOS_MAP_TOKEN)
01354 {
01355 return_idx = token_idx;
01356 }
01357 else
01358 {
01359 write_token(srcpos_map_file, NULL, 0, buf, token_idx);
01360 return_idx = TOKEN_next(&buf->tokens[token_idx]);
01361 }
01362 return return_idx;
01363 }
01364
01365
01366 static TOKEN_IDX
01367 Str_Skip_Srcpos_Map(TOKEN_BUFFER buf, TOKEN_IDX token_idx)
01368 {
01369 TOKEN_IDX return_idx;
01370
01371 if (token_idx == NO_TOKEN_IDX ||
01372 TOKEN_kind(&buf->tokens[token_idx]) != SRCPOS_MAP_TOKEN)
01373 {
01374 return_idx = token_idx;
01375 }
01376 else
01377 {
01378 return_idx = TOKEN_next(&buf->tokens[token_idx]);
01379 }
01380 return return_idx;
01381 }
01382
01383
01384 static void
01385 Write_Srcpos_File_Map_Table(FILE *srcpos_map_file)
01386 {
01387 UINT32 filenum;
01388 const char *fname;
01389 const char *dirname;
01390 USRCPOS usrcpos;
01391 INT32 status;
01392
01393 if (Emit_Prompf_Srcpos_Map)
01394 fprintf(srcpos_map_file, "SRCFILE_MAP_BEGIN\n");
01395 else
01396 fprintf(srcpos_map_file, "(SRCPOS-FILEMAP\n");
01397 for (filenum = 1; filenum <= Max_Srcpos_Map_Filenum; filenum++)
01398 {
01399 USRCPOS_filenum(usrcpos) = filenum;
01400 IR_Srcpos_Filename(USRCPOS_srcpos(usrcpos), &fname, &dirname);
01401 if (fname != NULL && dirname != NULL)
01402 {
01403 status = fprintf(srcpos_map_file,
01404 " %c%u \"%s/%s\"%c\n",
01405 Emit_Prompf_Srcpos_Map ? '[' : '(',
01406 filenum, dirname, fname,
01407 Emit_Prompf_Srcpos_Map ? ']' : ')');
01408 Is_True(status >= 0, ("Output error to srcpos mapping file"));
01409 }
01410 else if (fname != NULL)
01411 {
01412 status = fprintf(srcpos_map_file,
01413 " %c%u \"%s\"%c\n",
01414 Emit_Prompf_Srcpos_Map ? '[' : '(',
01415 filenum, fname,
01416 Emit_Prompf_Srcpos_Map ? ']' : ')');
01417 Is_True(status >= 0, ("Output error to srcpos mapping file"));
01418 }
01419 }
01420 if (Emit_Prompf_Srcpos_Map)
01421 fprintf(srcpos_map_file, "SRCFILE_MAP_END\n");
01422 else
01423 fprintf(srcpos_map_file, ")\n");
01424 }
01425
01426
01427
01428
01429
01430 void
01431 Initialize_Token_Buffer(FORMAT_KIND output_format, BOOL prompf_srcmap_format)
01432 {
01433 Output_Format = output_format;
01434 Max_Line_Length = Default_Max_Line_Length[output_format];
01435
01436 Emit_Prompf_Srcpos_Map = prompf_srcmap_format;
01437
01438 write_buffer_next = 0;
01439 last_split_pt = INVALID_SPLIT_PT;
01440
01441 Current_Output_Col = 1;
01442 Current_Output_Line = 1;
01443 Max_Srcpos_Map_Filenum = 0;
01444 }
01445
01446
01447 void
01448 Terminate_Token_Buffer(FILE *srcpos_map_file)
01449 {
01450
01451 free_buffer_list(buffer_free_list);
01452
01453
01454 if (Max_Srcpos_Map_Filenum > 0)
01455 Write_Srcpos_File_Map_Table(srcpos_map_file);
01456
01457 }
01458
01459
01460 void
01461 Set_Maximum_Linelength(UINT32 max_linelength)
01462 {
01463 if (max_linelength == 0)
01464 Max_Line_Length = Default_Max_Line_Length[Output_Format];
01465 else
01466 Max_Line_Length = max_linelength;
01467 }
01468
01469
01470 BOOL
01471 HAS_Maximum_Linelength(void)
01472 {
01473 return Max_Line_Length==0;
01474 }
01475
01476
01477 UINT32
01478 Get_Maximum_Linelength(void)
01479 {
01480 return Max_Line_Length;
01481 }
01482
01483
01484 void
01485 Free_Token_Buffer_Memory(void)
01486 {
01487 free_buffer_list(buffer_free_list);
01488 }
01489
01490
01491 TOKEN_BUFFER
01492 New_Token_Buffer(void)
01493 {
01494 TOKEN_BUFFER new_buffer;
01495
01496 if (buffer_free_list != NULL)
01497 {
01498 new_buffer = buffer_free_list;
01499 buffer_free_list = new_buffer->next;
01500 }
01501 else
01502 {
01503 new_buffer =
01504 TB_TYPE_ALLOC_N(struct Token_Buffer, 1);
01505 new_buffer->chars_allocated = INIT_STRING_BUFFER_SIZE;
01506 new_buffer->strings =
01507 TB_TYPE_ALLOC_N(char, new_buffer->chars_allocated);
01508 new_buffer->tokens_allocated = INIT_TOKEN_BUFFER_SIZE;
01509 new_buffer->tokens =
01510 TB_TYPE_ALLOC_N(TOKEN, new_buffer->tokens_allocated);
01511 }
01512 new_buffer->chars_used = 0;
01513 new_buffer->tokens_used = 0;
01514 new_buffer->token_list.first = NO_TOKEN_IDX;
01515 new_buffer->token_list.last = NO_TOKEN_IDX;
01516 new_buffer->next = NULL;
01517
01518 return new_buffer;
01519 }
01520
01521
01522 void
01523 Reclaim_Token_Buffer(TOKEN_BUFFER *tokens)
01524 {
01525 (*tokens)->next = buffer_free_list;
01526 buffer_free_list = *tokens;
01527 *tokens = NULL;
01528 }
01529
01530
01531 BOOL
01532 Is_Empty_Token_Buffer(TOKEN_BUFFER tokens)
01533 {
01534 Is_True(tokens != NULL, ("Invalid TOKEN_BUFFER in Is_Empty_Token_Buffer()"));
01535 return (tokens->tokens_used == 0);
01536 }
01537
01538
01539 BOOL
01540 Identical_Token_Lists(TOKEN_BUFFER tokens1,
01541 TOKEN_BUFFER tokens2)
01542 {
01543 BOOL identical = (tokens1 == NULL && tokens2 == NULL);
01544 TOKEN_IDX token_idx;
01545 TOKEN *a_token1;
01546 TOKEN *a_token2;
01547 const char *str1, *str2;
01548
01549 if (!identical)
01550 {
01551 identical = (tokens1 != NULL && tokens2 != NULL &&
01552 tokens1->tokens_used == tokens2->tokens_used);
01553
01554 for (token_idx = 0;
01555 identical && (token_idx < tokens1->tokens_used);
01556 token_idx++)
01557 {
01558 a_token1 = &tokens1->tokens[token_idx];
01559 a_token2 = &tokens2->tokens[token_idx];
01560 identical = TOKEN_kind(a_token1) == TOKEN_kind(a_token2);
01561 if (identical)
01562 {
01563 switch (TOKEN_kind(a_token1))
01564 {
01565 case F77_SEQNO_TOKEN:
01566 case STRING_TOKEN:
01567 case SEPARATOR_TOKEN:
01568 case DIRECTIVE_TOKEN:
01569 str2 = TOKEN_BUFFER_get_char_string(tokens1, a_token1);
01570 str1 = TOKEN_BUFFER_get_char_string(tokens2, a_token2);
01571 identical =
01572 ((TOKEN_string_size(a_token1) ==
01573 TOKEN_string_size(a_token2)) &&
01574 (strncmp(str1, str2, TOKEN_string_size(a_token1)) == 0));
01575 break;
01576
01577 case SPECIAL_TOKEN:
01578 identical = TOKEN_char(a_token1) == TOKEN_char(a_token2);
01579 break;
01580
01581 case SRCPOS_MAP_TOKEN:
01582 case SRCPOS_DIRECTIVE_TOKEN:
01583 identical = TOKEN_srcpos(a_token1) == TOKEN_srcpos(a_token2);
01584 break;
01585
01586 default:
01587 Is_True(FALSE, ("Attempt to access invalid token kind"));
01588 break;
01589 }
01590 }
01591 }
01592 }
01593
01594 return identical;
01595 }
01596
01597
01598 UINT
01599 Current_Indentation(void)
01600 {
01601 return requested_indentation;
01602 }
01603
01604
01605 void
01606 Set_Current_Indentation(UINT indent)
01607 {
01608 if (indent > MAX_INDENTATION)
01609 {
01610 requested_indentation = (INT32)indent;
01611 current_indentation = MAX_INDENTATION;
01612 }
01613 else
01614 requested_indentation = current_indentation = (INT32)indent;
01615 }
01616
01617
01618 void
01619 Set_Indentation_Step(UINT num_spaces)
01620 {
01621 if (num_spaces > MAX_INDENTATION_STEP)
01622 indentation_increment = MAX_INDENTATION_STEP;
01623 else
01624 indentation_increment = num_spaces;
01625 }
01626
01627
01628 void
01629 Increment_Indentation(void)
01630 {
01631 requested_indentation += indentation_increment;
01632 if (requested_indentation > MAX_INDENTATION)
01633 current_indentation = MAX_INDENTATION;
01634 else
01635 current_indentation = requested_indentation;
01636 }
01637
01638
01639 void
01640 Decrement_Indentation(void)
01641 {
01642 requested_indentation -= indentation_increment;
01643 if (requested_indentation < current_indentation)
01644 {
01645 if (requested_indentation < 0)
01646 requested_indentation = current_indentation = 0;
01647 else
01648 current_indentation = requested_indentation;
01649 }
01650 }
01651
01652
01653 void
01654 Zero_Indentation(void)
01655 {
01656 requested_indentation = current_indentation = 0;
01657 }
01658
01659
01660 void
01661 Append_Indented_Newline(TOKEN_BUFFER tokens, UINT num_lines)
01662 {
01663 TOKEN_SEQUENCE token_list;
01664
01665 Is_True(tokens != NULL,
01666 ("Invalid TOKEN_BUFFER in Append_Indented_Newline()"));
01667 token_list.first = indented_newline_token(tokens, num_lines, FALSE, NULL);
01668 token_list.last = token_list.first;
01669 append_token_list(tokens, token_list);
01670 }
01671
01672
01673 void
01674 Append_Token_String(TOKEN_BUFFER tokens, const char *string)
01675 {
01676 TOKEN_SEQUENCE token_list;
01677
01678 Is_True(tokens != NULL,
01679 ("Invalid TOKEN_BUFFER in Append_Token_String()"));
01680 if (string != NULL && string[0] != '\0')
01681 {
01682 token_list.first = string_token(tokens, string);
01683 token_list.last = token_list.first;
01684 append_token_list(tokens, token_list);
01685 }
01686 }
01687
01688
01689 void
01690 Append_Token_Special(TOKEN_BUFFER tokens, char special)
01691 {
01692 TOKEN_SEQUENCE token_list;
01693
01694 Is_True(tokens != NULL,
01695 ("Invalid TOKEN_BUFFER in Append_Token_Special()"));
01696 token_list.first = special_char_token(tokens, special);
01697 token_list.last = token_list.first;
01698 append_token_list(tokens, token_list);
01699 }
01700
01701
01702 void
01703 Append_And_Copy_Token_List(TOKEN_BUFFER result_tokens,
01704 TOKEN_BUFFER copy_tokens)
01705 {
01706 TOKEN_SEQUENCE token_list;
01707
01708 Is_True(result_tokens != NULL,
01709 ("Invalid TOKEN_BUFFER in Append_And_Copy_Token_List()"));
01710 token_list = copy_token_list(result_tokens, copy_tokens);
01711 if (token_list.first != NO_TOKEN_IDX)
01712 append_token_list(result_tokens, token_list);
01713 }
01714
01715
01716 void
01717 Append_And_Reclaim_Token_List(TOKEN_BUFFER result_tokens,
01718 TOKEN_BUFFER *reclaim_tokens)
01719 {
01720 Append_And_Copy_Token_List(result_tokens, *reclaim_tokens);
01721 Reclaim_Token_Buffer(reclaim_tokens);
01722 }
01723
01724
01725 void
01726 Prepend_Indented_Newline(TOKEN_BUFFER tokens, UINT num_lines)
01727 {
01728 TOKEN_SEQUENCE token_list;
01729
01730 Is_True(tokens != NULL,
01731 ("Invalid TOKEN_BUFFER in Prepend_Indented_Newline()"));
01732 token_list.first = indented_newline_token(tokens, num_lines, FALSE, NULL);
01733 token_list.last = token_list.first;
01734 prepend_token_list(tokens, token_list);
01735 }
01736
01737
01738 void
01739 Prepend_Token_String(TOKEN_BUFFER tokens, const char *string)
01740 {
01741 TOKEN_SEQUENCE token_list;
01742
01743 Is_True(tokens != NULL,
01744 ("Invalid TOKEN_BUFFER in Prepend_Token_String()"));
01745 if (string != NULL && string[0] != '\0')
01746 {
01747 token_list.first = string_token(tokens, string);
01748 token_list.last = token_list.first;
01749 prepend_token_list(tokens, token_list);
01750 }
01751 }
01752
01753
01754 void
01755 Prepend_Token_Special(TOKEN_BUFFER tokens, char special)
01756 {
01757 TOKEN_SEQUENCE token_list;
01758
01759 Is_True(tokens != NULL,
01760 ("Invalid TOKEN_BUFFER in Prepend_Token_Special()"));
01761 token_list.first = special_char_token(tokens, special);
01762 token_list.last = token_list.first;
01763 prepend_token_list(tokens, token_list);
01764 }
01765
01766
01767 void
01768 Prepend_And_Copy_Token_List(TOKEN_BUFFER result_tokens,
01769 TOKEN_BUFFER copy_tokens)
01770 {
01771 TOKEN_SEQUENCE token_list;
01772
01773 Is_True(result_tokens != NULL,
01774 ("Invalid TOKEN_BUFFER in Prepend_And_Copy_Token_List()"));
01775 token_list = copy_token_list(result_tokens, copy_tokens);
01776 if (token_list.first != NO_TOKEN_IDX)
01777 prepend_token_list(result_tokens, token_list);
01778 }
01779
01780 void
01781 Prepend_And_Reclaim_Token_List(TOKEN_BUFFER result_tokens,
01782 TOKEN_BUFFER *reclaim_tokens)
01783 {
01784 Prepend_And_Copy_Token_List(result_tokens, *reclaim_tokens);
01785 Reclaim_Token_Buffer(reclaim_tokens);
01786 }
01787
01788
01789 void
01790 Append_F77_Indented_Newline(TOKEN_BUFFER tokens,
01791 UINT num_lines,
01792 const char *label)
01793 {
01794 TOKEN_SEQUENCE token_list;
01795
01796 Is_True(tokens != NULL &&
01797 (Output_Format == F77_TAB_FORMAT ||
01798 Output_Format == F77_ANSI_FORMAT),
01799 ("Invalid TOKEN_BUFFER in Append_F77_Indented_Newline()"));
01800 token_list.first = indented_newline_token(tokens, num_lines, FALSE, label);
01801 token_list.last = token_list.first;
01802 append_token_list(tokens, token_list);
01803 }
01804
01805
01806 void
01807 Prepend_F77_Indented_Newline(TOKEN_BUFFER tokens,
01808 UINT num_lines,
01809 const char *label)
01810 {
01811 TOKEN_SEQUENCE token_list;
01812
01813 Is_True(tokens != NULL &&
01814 (Output_Format == F77_TAB_FORMAT ||
01815 Output_Format == F77_ANSI_FORMAT),
01816 ("Invalid TOKEN_BUFFER in Prepend_F77_Indented_Newline()"));
01817 token_list.first = indented_newline_token(tokens, num_lines, FALSE, label);
01818 token_list.last = token_list.first;
01819 prepend_token_list(tokens, token_list);
01820 }
01821
01822
01823 void
01824 Append_F77_Indented_Continuation(TOKEN_BUFFER tokens)
01825 {
01826 TOKEN_SEQUENCE token_list;
01827
01828 Is_True(tokens != NULL &&
01829 (Output_Format == F77_TAB_FORMAT ||
01830 Output_Format == F77_ANSI_FORMAT),
01831 ("Invalid TOKEN_BUFFER in Append_F77_Indented_Newline()"));
01832 token_list.first = indented_newline_token(tokens, 1, TRUE, NULL);
01833 token_list.last = token_list.first;
01834 append_token_list(tokens, token_list);
01835 }
01836
01837
01838 void
01839 Prepend_F77_Indented_Continuation(TOKEN_BUFFER tokens)
01840 {
01841 TOKEN_SEQUENCE token_list;
01842
01843 Is_True(tokens != NULL &&
01844 (Output_Format == F77_TAB_FORMAT ||
01845 Output_Format == F77_ANSI_FORMAT),
01846 ("Invalid TOKEN_BUFFER in Prepend_F77_Indented_Continuation()"));
01847 token_list.first = indented_newline_token(tokens, 1, TRUE, NULL);
01848 token_list.last = token_list.first;
01849 prepend_token_list(tokens, token_list);
01850 }
01851
01852
01853 void
01854 Append_F77_Comment_Newline(TOKEN_BUFFER tokens,
01855 UINT num_lines,
01856 BOOL indent_last_line)
01857 {
01858 TOKEN_SEQUENCE token_list;
01859
01860 Is_True(tokens != NULL &&
01861 (Output_Format == F77_TAB_FORMAT ||
01862 Output_Format == F77_ANSI_FORMAT),
01863 ("Invalid TOKEN_BUFFER in Append_F77_Commented_Newline()"));
01864 token_list.first =
01865 F77_comment_line_token(tokens, num_lines, "C", indent_last_line);
01866 token_list.last = token_list.first;
01867 append_token_list(tokens, token_list);
01868 }
01869
01870
01871 void
01872 Prepend_F77_Comment_Newline(TOKEN_BUFFER tokens,
01873 UINT num_lines,
01874 BOOL indent_last_line)
01875 {
01876 TOKEN_SEQUENCE token_list;
01877
01878 Is_True(tokens != NULL &&
01879 (Output_Format == F77_TAB_FORMAT ||
01880 Output_Format == F77_ANSI_FORMAT),
01881 ("Invalid TOKEN_BUFFER in Prepend_F77_Commented_Newline()"));
01882 token_list.first =
01883 F77_comment_line_token(tokens, num_lines, "C", indent_last_line);
01884 token_list.last = token_list.first;
01885 prepend_token_list(tokens, token_list);
01886 }
01887
01888
01889 void
01890 Append_F77_Directive_Newline(TOKEN_BUFFER tokens,
01891 const char *directive_prefix)
01892 {
01893 TOKEN_SEQUENCE token_list;
01894
01895 Is_True(tokens != NULL &&
01896 (Output_Format == F77_TAB_FORMAT ||
01897 Output_Format == F77_ANSI_FORMAT),
01898 ("Invalid TOKEN_BUFFER in Append_F77_Directive_Newline()"));
01899 token_list.first = F77_directive_line_token(tokens, directive_prefix);
01900 token_list.last = token_list.first;
01901 append_token_list(tokens, token_list);
01902 }
01903
01904
01905 void
01906 Prepend_F77_Directive_Newline(TOKEN_BUFFER tokens,
01907 const char *directive_prefix)
01908 {
01909 TOKEN_SEQUENCE token_list;
01910
01911 Is_True(tokens != NULL &&
01912 (Output_Format == F77_TAB_FORMAT ||
01913 Output_Format == F77_ANSI_FORMAT),
01914 ("Invalid TOKEN_BUFFER in Prepend_F77_Directive_Newline()"));
01915 token_list.first = F77_directive_line_token(tokens, directive_prefix);
01916 token_list.last = token_list.first;
01917 prepend_token_list(tokens, token_list);
01918 }
01919
01920
01921 void
01922 Append_F77_Sequence_No(TOKEN_BUFFER tokens,
01923 const char *seq_no)
01924 {
01925 TOKEN_SEQUENCE token_list;
01926
01927 Is_True(tokens != NULL && Output_Format == F77_TAB_FORMAT,
01928 ("Invalid TOKEN_BUFFER in Append_F77_Sequence_No()"));
01929 if (seq_no != NULL && seq_no[0] != '\0')
01930 {
01931 token_list.first = f77_seqno_token(tokens, seq_no);
01932 token_list.last = token_list.first;
01933 append_token_list(tokens, token_list);
01934 }
01935 }
01936
01937
01938 void
01939 Prepend_F77_Sequence_No(TOKEN_BUFFER tokens,
01940 const char *seq_no)
01941 {
01942 TOKEN_SEQUENCE token_list;
01943
01944 Is_True(tokens != NULL && Output_Format == F77_TAB_FORMAT,
01945 ("Invalid TOKEN_BUFFER in Append_F77_Sequence_No()"));
01946 if (seq_no != NULL && seq_no[0] != '\0')
01947 {
01948 token_list.first = f77_seqno_token(tokens, seq_no);
01949 token_list.last = token_list.first;
01950 prepend_token_list(tokens, token_list);
01951 }
01952 }
01953
01954
01955 void
01956 Append_Srcpos_Map(TOKEN_BUFFER tokens, SRCPOS srcpos)
01957 {
01958 TOKEN_SEQUENCE token_list;
01959
01960 Is_True(tokens != NULL,
01961 ("Invalid TOKEN_BUFFER in Append_Srcpos_Map()"));
01962 token_list.first = Srcpos_Map_Token(tokens, srcpos);
01963 token_list.last = token_list.first;
01964 append_token_list(tokens, token_list);
01965 }
01966
01967
01968 void
01969 Append_Srcpos_Directive(TOKEN_BUFFER tokens, SRCPOS srcpos)
01970 {
01971 TOKEN_SEQUENCE token_list;
01972
01973 Is_True(tokens != NULL,
01974 ("Invalid TOKEN_BUFFER in Append_Srcpos_Directive()"));
01975 token_list.first = Srcpos_Directive_Token(tokens, srcpos);
01976 token_list.last = token_list.first;
01977 append_token_list(tokens, token_list);
01978 }
01979
01980
01981 void
01982 Prepend_Srcpos_Map(TOKEN_BUFFER tokens, SRCPOS srcpos)
01983 {
01984 TOKEN_SEQUENCE token_list;
01985
01986 Is_True(tokens != NULL,
01987 ("Invalid TOKEN_BUFFER in Prepend_Srcpos_Map()"));
01988 token_list.first = Srcpos_Map_Token(tokens, srcpos);
01989 token_list.last = token_list.first;
01990 prepend_token_list(tokens, token_list);
01991 }
01992
01993
01994 void
01995 Prepend_Srcpos_Directive(TOKEN_BUFFER tokens, SRCPOS srcpos)
01996 {
01997 TOKEN_SEQUENCE token_list;
01998
01999 Is_True(tokens != NULL,
02000 ("Invalid TOKEN_BUFFER in Prepend_Srcpos_Directive()"));
02001 token_list.first = Srcpos_Directive_Token(tokens, srcpos);
02002 token_list.last = token_list.first;
02003 prepend_token_list(tokens, token_list);
02004 }
02005
02006
02007 void
02008 Write_And_Reclaim_Tokens(FILE *ofile,
02009 FILE *srcpos_map_file,
02010 TOKEN_BUFFER *tokens)
02011 {
02012 TOKEN_IDX this_token, next_token;
02013 UINT32 saved_output_col, saved_output_line;
02014
02015 Is_True(tokens != NULL,
02016 ("Invalid TOKEN_BUFFER in Write_And_Reclaim_Tokens()"));
02017
02018 if (srcpos_map_file == NULL)
02019 {
02020
02021
02022
02023 saved_output_line = Current_Output_Line;
02024 saved_output_col = Current_Output_Col;
02025 }
02026
02027
02028
02029
02030 this_token = Skip_Srcpos_Map(srcpos_map_file,
02031 *tokens,
02032 (*tokens)->token_list.first);
02033 while (this_token != NO_TOKEN_IDX)
02034 {
02035 write_token(ofile, NULL, 0, *tokens, this_token);
02036 next_token = Skip_Srcpos_Map(srcpos_map_file,
02037 *tokens,
02038 TOKEN_next(&(*tokens)->tokens[this_token]));
02039 if (Output_Format == FREE_FORMAT)
02040 write_separator(ofile, NULL, 0, *tokens, this_token, next_token);
02041 else
02042 write_F77_separator(ofile, NULL, 0, *tokens, this_token, next_token);
02043 this_token = next_token;
02044 }
02045 Reclaim_Token_Buffer(tokens);
02046
02047
02048
02049
02050 flush_write_buffer(ofile, NULL, 0);
02051
02052 if (srcpos_map_file == NULL)
02053 {
02054
02055
02056 Current_Output_Line = saved_output_line;
02057 Current_Output_Col = saved_output_col;
02058 }
02059 }
02060
02061
02062 void
02063 Str_Write_And_Reclaim_Tokens(char *strbuf,
02064 UINT32 buflen,
02065 TOKEN_BUFFER *tokens)
02066 {
02067 TOKEN_IDX this_token, next_token;
02068 UINT32 saved_output_col, saved_output_line;
02069
02070 Is_True(tokens != NULL,
02071 ("Invalid TOKEN_BUFFER in Str_Write_And_Reclaim_Tokens()"));
02072
02073
02074
02075
02076 saved_output_line = Current_Output_Line;
02077 saved_output_col = Current_Output_Col;
02078
02079
02080 this_token = Str_Skip_Srcpos_Map(*tokens, (*tokens)->token_list.first);
02081 while (this_token != NO_TOKEN_IDX)
02082 {
02083 write_token(NULL, &strbuf, &buflen, *tokens, this_token);
02084 next_token =
02085 Str_Skip_Srcpos_Map(
02086 *tokens, TOKEN_next(&(*tokens)->tokens[this_token]));
02087
02088 if (Output_Format == FREE_FORMAT)
02089 write_separator(
02090 NULL, &strbuf, &buflen, *tokens, this_token, next_token);
02091 else
02092 write_F77_separator(
02093 NULL, &strbuf, &buflen, *tokens, this_token, next_token);
02094
02095 this_token = next_token;
02096 }
02097 Reclaim_Token_Buffer(tokens);
02098
02099
02100
02101 flush_write_buffer(NULL, &strbuf, &buflen);
02102 Is_True(buflen > 0, ("String buffer overflow!"));
02103 *strbuf = '\0';
02104
02105
02106
02107 Current_Output_Line = saved_output_line;
02108 Current_Output_Col = saved_output_col;
02109 }
02110
02111
02112 void
02113 Write_String(FILE *ofile, FILE *srcpos_map_file, const char *str)
02114 {
02115 INT32 str_idx;
02116
02117 if (srcpos_map_file != NULL)
02118 {
02119 for (str_idx = 0; str[str_idx] != '\0'; str_idx++)
02120 if (str[str_idx] == '\n')
02121 Current_Output_Line++;
02122 Current_Output_Col += str_idx;
02123 }
02124 fputs(str, ofile);
02125 }