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