Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 07-Oct-94 - Original Version 00042 * 00043 * Description: 00044 * 00045 * This package implements the most basic form of token buffer, 00046 * where we only distinguish between separators, special character 00047 * string tokens, and source position directives. 00048 * 00049 * The purpose of a token_buffer is two-fold: It writes token 00050 * sequences to an output-file, which is opened as a side-effect 00051 * of initializing this module. Secondly it provides facilities 00052 * for buffering an ordered sequence of tokens. 00053 * 00054 * We maintain a free-list (buffer_free_list) for reusing buffers. 00055 * There are really three kinds of buffers: 00056 * 00057 * TOKEN_BUFFER: Contains information about a buffer and has its 00058 * own private string and token buffer area. This 00059 * is the "abstract data type" exported by this 00060 * package. 00061 * 00062 * tokens: A memory pool allocated for a given TOKEN_BUFFER, 00063 * which contains all its tokens. The token sequence 00064 * will index into this memory pool of tokens. 00065 * 00066 * strings: A memory pool allocated for a given TOKEN_BUFFER, 00067 * which contains all its character strings. Each 00068 * token will index into this pool of characters. 00069 * 00070 * The buffers and memory pools are never freed up from memory, 00071 * unless an explicit request is recieved to do so, and they are 00072 * instead kept on a free_list. 00073 * 00074 * The exported routines are described in token_buffer.h, and are 00075 * implemented in terms of various static utility routines and 00076 * variables local to this module "body". The definitions are 00077 * in the following order: 00078 * 00079 * 1) Macro definitions, data types, and local state. 00080 * 00081 * 2) Local utility routines. 00082 * 00083 * 3) Implementation of each of the exported routines. 00084 * 00085 * WARNING: 00086 * 00087 * This module has been implemented very carefully without any 00088 * interspersed assertion checking, so extreme care should be 00089 * exercised in any modification to this module. It is essential 00090 * that the implementation of the token-buffer mechanism be as 00091 * efficient as is possible. 00092 * 00093 * ==================================================================== 00094 * ==================================================================== 00095 */ 00096 00097 #ifdef _KEEP_RCS_ID 00098 #endif /* _KEEP_RCS_ID */ 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 /*------------------ macros, types, and local state -------------------*/ 00113 /*---------------------------------------------------------------------*/ 00114 00115 /* Disallow any use of strcpy, since it potentially dangerous. We operate 00116 * with strings that are not NULL-character terminated in the tokens, and 00117 * as such space is not allocated for such NULL-characters and a strcpy 00118 * may write a NULL character beyond the end of an allocated buffer. 00119 */ 00120 #define strcpy DO_NOT_USE_STRCPY 00121 00122 /* Macros for allocating, reallocating and freeing up memory. 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 /* The buffer structure and its index types */ 00137 typedef mUINT32 STRING_IDX; 00138 typedef mUINT32 TOKEN_IDX; 00139 #define MAX_STRING_IDX (STRING_IDX)0x7fffffffU /* max string buffer size */ 00140 #define MAX_TOKEN_IDX (TOKEN_IDX)0x7fffffffU /* max token buffer size */ 00141 #define NO_STRING_IDX (STRING_IDX)0xffffffffU /* Invalid string buffer index*/ 00142 #define NO_TOKEN_IDX (TOKEN_IDX)0xffffffffU /* Invalid token buffer index*/ 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; /* String size */ 00160 union 00161 { 00162 char ch[sizeof(STRING_IDX)]; /* SPECIAL_TOKEN and short strings */ 00163 STRING_IDX idx; /* ... any longer char strings */ 00164 } string; 00165 } STRING_VALUE; 00166 00167 typedef union Token_Value 00168 { 00169 SRCPOS srcpos; /* SRCPOS value (64 bits) */ 00170 STRING_VALUE str_val; /* string values (64 bits) */ 00171 } TOKEN_VALUE; 00172 00173 typedef struct Token 00174 { 00175 TOKEN_KIND kind; /* (32 bits) */ 00176 TOKEN_IDX next; /* The next token in a token-sequence (32 bits) */ 00177 TOKEN_VALUE value; /* The characters for the token (64 bits) */ 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; /* First token in the token-sequence */ 00200 TOKEN_IDX last; /* Last token in the token-sequence */ 00201 } TOKEN_SEQUENCE; 00202 00203 struct Token_Buffer 00204 { 00205 char *strings; 00206 TOKEN *tokens; 00207 STRING_IDX chars_allocated; /* Number of characters allocated */ 00208 STRING_IDX chars_used; /* Number of characters used */ 00209 TOKEN_IDX tokens_allocated; /* Number of tokens allocated */ 00210 TOKEN_IDX tokens_used; /* Number of tokens used */ 00211 TOKEN_SEQUENCE token_list; /* The token-sequence */ 00212 TOKEN_BUFFER next; /* Maintains free-list of buffers */ 00213 }; 00214 00215 /* Given that the token is of a kind that has an associated char-string, 00216 * this macro will return the address to this string (currently, only 00217 * SRCPOS tokens do not have a char-string, while SPECIAL_CHAR tokens 00218 * are represented as a string with one char and can alternatively be 00219 * accessed with the TOKEN_char(a_token) macro call). There is no 00220 * assertion checking on this access to the string. 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 /* Local state variables */ 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; /* Need to access the previous idx as -1 */ 00235 static INT32 last_split_pt = INVALID_SPLIT_PT; /* To split too long lines */ 00236 00237 00238 #define MAX_INDENTATION 40 00239 #define MAX_INDENTATION_STEP 10 00240 static UINT32 indentation_increment = 2; /* Ident by 2 spaces at a time */ 00241 static INT32 current_indentation = 0; /* Never to exceed MAX_INDENTATION */ 00242 static INT32 requested_indentation = 0; /* May exceed MAX_INDENTATION */ 00243 00244 00245 /* How do we format the output characters? */ 00246 #define USE_UNLIMITED_LINE_LENGTH (Max_Line_Length == 0) 00247 static UINT32 Max_Line_Length = 0; /* Unlimited line-length */ 00248 static FORMAT_KIND Output_Format = FREE_FORMAT; 00249 00250 00251 /* What is the current position in the output file, taking into 00252 * account the line currently being buffered for output. 00253 */ 00254 static UINT32 Current_Output_Col = 1; 00255 static UINT32 Current_Output_Line = 1; 00256 00257 00258 /* What is the maxumum file-number encountered in any SRCPOS_MAP token. 00259 */ 00260 static UINT32 Max_Srcpos_Map_Filenum = 0; 00261 00262 /* What is the default maximum line lengths for the various formatting 00263 * kinds that we support. 00264 */ 00265 static UINT32 Default_Max_Line_Length[NUM_FORMAT_KINDS+1] = 00266 { 00267 0, /* FREE_FORMAT: no limit */ 00268 0, /* F77_TAB_FORMAT: no limit */ 00269 72 /* F77_ANSI_FORMAT: limited to 72 characters */ 00270 }; 00271 00272 /* Fortran directives are somewhat special in that they enforce a 72 00273 * character limit on line-lengths. 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 /* Use a special syntax for the ProMPF analysis file. 00281 */ 00282 static BOOL Emit_Prompf_Srcpos_Map = FALSE; 00283 00284 00285 /*--------------- routines for debugging a token buffer ---------------*/ 00286 /*---------------------------------------------------------------------*/ 00287 00288 #define DBGOUT stderr /* debugging output file */ 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 } /* dbg_tokens */ 00371 00372 00373 /*------------------ general purpose hidden routines ------------------*/ 00374 /*---------------------------------------------------------------------*/ 00375 00376 /* Determine whether we have exceeded the line-length limit and have 00377 * a place to insert a split-point. 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 /* Determine whether or not c2 is a unary operator, assuming the 00398 * previous character c1 is also a special character. 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)) /* Field selection */ 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 /* Allocates number_of_tokens, with successive indices 00418 * starting at the returned idx. 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 /* Need to reallocate tokens; double size if the number of tokens 00428 * is less than 8K, otherwise increment the number of tokens by 8K. 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, /* type */ 00441 buf->tokens, /* old ptr */ 00442 buf->tokens_allocated, /* old count */ 00443 max_tokens); /* new count */ 00444 buf->tokens_allocated = max_tokens; 00445 } 00446 return (return_idx); 00447 } /* get_new_tokens */ 00448 00449 00450 static STRING_IDX 00451 get_new_string(TOKEN_BUFFER buf, INT16 stringsize) 00452 { 00453 /* Allocates number_of_char, with successive indices 00454 * starting at the returned idx. 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 /* Need to reallocate string-buffer; double size if the buffer is 00464 * less than 32K in size, otherwise increment size by 32K. 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, /* type */ 00477 buf->strings, /* old ptr */ 00478 buf->chars_allocated, /* old count */ 00479 max_chars); /* new count */ 00480 buf->chars_allocated = max_chars; 00481 } 00482 return return_idx; 00483 } /* get_new_string */ 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 } /* Allocate_Token_String */ 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 } /* free_buffer_list */ 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 /* Emit num_lines '\n' characters, followed by the Fortran 00529 * formatting offset and label, followed by the continuation 00530 * mark and the indentation amount. Note that the indentation 00531 * for labels of more than 5 characters in F77_TAB_FORMAT will 00532 * be larger than expected (however, this should be very rare). 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 /* Allocate a string for this SEPERATOR token */ 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 /* Initiate the token */ 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 /* Add the newline ('\n') characters to the string and 00558 * advance char_idx one past the last newline character. 00559 */ 00560 for (char_idx = 0; char_idx < num_lines; char_idx++) 00561 str[char_idx] = NEWLINE; 00562 00563 /* Add the Fortran specific label (char_idx==num_lines) */ 00564 if (label_size > 0) 00565 { 00566 (void)strncpy(&str[char_idx], &label[0], label_size); 00567 char_idx += label_size; 00568 } 00569 00570 /* Add the fortran specific layout prefix and continuation marks 00571 * (char_idx==new_string_idx+num_lines+label_size) 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 /* Add the indentation (char_idx==new_string_idx+num_lines+prefix_size) */ 00587 while (char_idx < num_lines + prefix_size + current_indentation) 00588 str[char_idx++] = SPACE; 00589 00590 return new_token_idx; 00591 } /* indented_newline_token */ 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 /* Emit num_lines '\n' characters, each followed by the 00601 * comment_prefix in column one. Use the current Indent the last 00602 * line when "indent==TRUE". Must be in one of the Fortran 00603 * formatting modes. With no indentation of the last line, we do 00604 * not even insert the tab character or standard fomatting space 00605 * characters. 00606 */ 00607 const INT32 comment_prefix_size = strlen(comment_prefix); 00608 char indentation_str[MAX_INDENTATION+50]; /* E.g. "C$\t " */ 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 /* Get the string used to indent the last line (preceding actual comment). 00616 */ 00617 strncpy(indentation_str, comment_prefix, comment_prefix_size); 00618 indentation_size = comment_prefix_size; 00619 if (indent_last_line) 00620 { 00621 /* Assume the comment_prefix is smaller than the F77 tab or space 00622 * prefix. 00623 */ 00624 if (Output_Format == F77_TAB_FORMAT) 00625 { 00626 indentation_str[indentation_size++] = '\t'; 00627 } 00628 else /* Output_Format == F77_ANSI_FORMAT */ 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 } /* if indent last line */ 00638 00639 /* Allocate a string for this SEPERATOR token and initiate it */ 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 + /* '\n' */ 00644 (num_lines - 1)*comment_prefix_size + 00645 indentation_size); 00646 00647 /* Add the newline ("\n<comment_prefix>") characters to the string */ 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 /* Add the last line indentation */ 00657 str = strncpy(str, indentation_str, indentation_size); 00658 00659 return new_token_idx; 00660 } /* F77_comment_line_token */ 00661 00662 00663 static TOKEN_IDX 00664 F77_directive_line_token(TOKEN_BUFFER buffer, 00665 const char *directive_prefix) 00666 { 00667 /* Emit a Fortran directive, which must be specially tokenized since 00668 * it must NEVER exceed a line-length of 72 characters (there is no 00669 * tab formatting mode for directives). The directive will be preceeded 00670 * by a newline character. Note that all subsequent tokens, up till 00671 * the next explicit NEWLINE character, apply to this token. 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 /* Allocate a string for this DIRECTIVE token and initiate it. 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/*'\n'*/ + directive_prefix_size); 00684 00685 /* Insert the new ("\n<diretcive_prefix>") characters into the token. 00686 */ 00687 *str++ = NEWLINE; 00688 str = strncpy(str, directive_prefix, directive_prefix_size); 00689 00690 return new_token_idx; 00691 } /* F77_directive_line_token */ 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 /* Initiate the token */ 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 /* Initiate the string for this token */ 00707 (void)strncpy(str, string, TOKEN_string_size(a_token)); 00708 00709 return new_token_idx; 00710 } /* string_token */ 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 } /* f77_seqno_token */ 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 /* Initiate the token */ 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 /* Initiate the token */ 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 } /* Srcpos_Map_Token */ 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 /* Initiate the token */ 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 } /* Srcpos_Directive_Token */ 00766 00767 00768 static TOKEN_SEQUENCE 00769 copy_token_list(TOKEN_BUFFER to_buffer, TOKEN_BUFFER from_buffer) 00770 { 00771 /* Copy the tokens from from_buffer into to_buffer, and 00772 * return a pointer to the first and last tokens of the 00773 * resultant token list without appending or prepending 00774 * it to the existing tokens in the to_buffer. The next 00775 * pointers for the token_sequence will all be correct. 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 /* We take advantage of the fact that token_lists and characters 00790 * will be allocated in consecutive regions of memory, and we 00791 * therefore allocate all we need immediately. 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 /* Copy the string into the target buffer. 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 /* Copy the tokens into the new token list, and update the string 00805 * indices and next indices accordingly. 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]; /* copy token */ 00811 TOKEN_next(new_token) += token_offset; /* correct next idx */ 00812 00813 /* correct string idx, if relevant */ 00814 if (TOKEN_is_string(new_token) && !TOKEN_is_short_string(new_token)) 00815 TOKEN_string_idx(new_token) += char_offset; 00816 } 00817 00818 /* Correct the next index for the last token in the copied sequence */ 00819 to_buffer->tokens[token_list.last].next = NO_TOKEN_IDX; 00820 } 00821 return token_list; 00822 } /* copy_token_list */ 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 } /* append_token_list */ 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 } /* prepend_token_list */ 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 /* Write "from_size" characters into "into" and update 00858 * the "into" buffer and the "into_size" to refer to the 00859 * remaining part of the buffer. 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 } /* write_into_string_buf */ 00875 00876 00877 static void 00878 flush_write_buffer(FILE *ofile, char **buffer, UINT *buflen) 00879 { 00880 /* NOTE: THIS SHOULD BE THE ONLY PLACE WHERE TOKENS ARE WRITTEN 00881 * TO FILE! 00882 * 00883 * Write buffer contents to file, but not beyond the 00884 * last_split_pt. 00885 */ 00886 UINT32 buffer_idx; 00887 char saved_ch; 00888 00889 if (write_buffer_next > 0) 00890 { 00891 /* If there is a splitpoint somewhere in the buffer, but not at 00892 * the very beginning of the buffer and not at the very end of 00893 * the buffer, then emit characters up till that point and 00894 * restore the remaining characters into the buffer; 00895 * otherwise, write out the whole buffer. 00896 */ 00897 if (last_split_pt > 0 && last_split_pt < write_buffer_next) 00898 { 00899 saved_ch = write_buffer[last_split_pt]; /* save splitpoint */ 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 /* Restore the characters following and including the last_split_pt 00908 * into the buffer. 00909 */ 00910 write_buffer[0] = saved_ch; /* restore splitpoint */ 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 } /* flush_write_buffer */ 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, /* NULL when strbuf!=NULL */ 00942 char **strbuf, /* NULL when ofile!=NULL */ 00943 UINT *strlen) /* Relevant for strbuf!=NULL */ 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 /* Copy the characters following the split-point into a temporary 00952 * buffer, and set buffer_idx. 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 /* Determine the continuation prefix for this line-split */ 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"; /* backslash followed by newline */ 00968 else if (Output_Format == F77_TAB_FORMAT) 00969 continuation_prefix = "\n\t1 "; /* newline followed by tab and '1' */ 00970 else /* if (Output_Format == F77_ANSI_FORMAT) */ 00971 continuation_prefix = "\n > "; /* newline followed by 5 spaces */ 00972 00973 /* Reset the buffer to only account for characters up to the 00974 * current split-point, then add back in the remaining characters 00975 * after having added in the split-point itself. 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 } /* Split_The_Current_Output_Line */ 00988 00989 00990 static void 00991 Output_Character(FILE *ofile, /* NULL when strbuf!=NULL */ 00992 char **strbuf, /* NULL when ofile!=NULL */ 00993 UINT *strlen, /* Only relevant when strbuf!=NULL */ 00994 char c) 00995 { 00996 /* Write the buffer to file once it is full */ 00997 if (write_buffer_next+1 >= WRITE_BUFFER_SIZE) 00998 flush_write_buffer(ofile, strbuf, strlen); 00999 01000 /* Add this character to file */ 01001 write_buffer[write_buffer_next++] = c; 01002 01003 /* Keep track of the current positioning in the output file */ 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 } /* Output_Character */ 01024 01025 01026 static void 01027 Output_Srcpos_Map(FILE *mapfile, SRCPOS srcpos) 01028 { 01029 /* Output the current source position, relative to the 01030 * Current_Output_Line and the Current_Output_Col in 01031 * a Lisp like predicate form. If this token is 01032 * used in conjunction with a SRCPOS_DIRECTIVE token, 01033 * it should typically follow the indented newline token 01034 * that follows the SRCPOS_DIRECTIVE token to get the 01035 * Current_Output_Line and Current_Output_Col right. 01036 * NOTE that this token is assumed output to a file 01037 * different from the regular output-file, and hence 01038 * we do not use the Output_Character() function. 01039 */ 01040 INT32 status; 01041 USRCPOS usrcpos; 01042 01043 if (srcpos != 0) 01044 { 01045 USRCPOS_srcpos(usrcpos) = srcpos; 01046 01047 /* Get the maximum file-number, such we later can write out the 01048 * whole file-table. 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 } /* Output_Srcpos_Map */ 01073 01074 01075 static void 01076 Output_Srcpos_Directive(FILE *ofile, 01077 char **strbuf, 01078 UINT *strlen, 01079 SRCPOS srcpos) 01080 { 01081 /* Output the current source position in the form 01082 * of a "#line" preprocessing directive. Since this 01083 * directive applies to everything that follows, it 01084 * implicitly causes a newline to precede it. The 01085 * implicit newline should be known to users of this 01086 * module and means this token should precede the 01087 * indented newline that typically precedes a stmt. 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 /* Write the directive to file. 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 } /* Output_Srcpos_Directive */ 01121 01122 01123 static void 01124 write_token(FILE *ofile, /* NULL if strbuf!=NULL */ 01125 char **strbuf, /* NULL if ofile!=NULL */ 01126 UINT *strlen, /* Only relevant when strbuf!=NULL */ 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 /* Fill up the current line to column 73, where the sequence number 01140 * will begin, before entering the sequence number. 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 /* Output the diretive prefix. 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 /* Note the fact that subsequent tokens apply to a Fortran directive 01171 * and that lines should be limited to 72 characters. 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 } /* write_token */ 01207 01208 01209 static void 01210 write_separator(FILE *ofile, /* NULL when strbuf!=NULL */ 01211 char **strbuf, /* NULL when ofile!=NULL */ 01212 UINT *strlen, /* Only relevant for strbuf!=NULL */ 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 } /* write_separator */ 01273 01274 static void 01275 write_F77_separator(FILE *ofile, /* NULL when strbuf!=NULL */ 01276 char **strbuf, /* NULL when ofile!=NULL */ 01277 UINT *strlen, /* Relevant for strbuf!=NULL */ 01278 TOKEN_BUFFER buffer, 01279 TOKEN_IDX idx1, 01280 TOKEN_IDX idx2) 01281 { 01282 /* This can be targeted to Fortran requirements whenever necessary. 01283 * For now, simply call the FREE_FORMAT separator. 01284 */ 01285 write_separator(ofile, strbuf, strlen, buffer, idx1, idx2); 01286 } /* write_F77_separator */ 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 /* TOKEN_kind == SRCPOS_MAP_TOKEN */ 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 } /* Skip_Srcpos_Map */ 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 /* TOKEN_kind == SRCPOS_MAP_TOKEN */ 01319 { 01320 return_idx = TOKEN_next(&buf->tokens[token_idx]); 01321 } 01322 return return_idx; 01323 } /* Str_Skip_Srcpos_Map */ 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 } /* for */ 01362 if (Emit_Prompf_Srcpos_Map) 01363 fprintf(srcpos_map_file, "SRCFILE_MAP_END\n"); 01364 else 01365 fprintf(srcpos_map_file, ")\n"); 01366 } /* Write_Srcpos_File_Map_Table */ 01367 01368 01369 /*------------------------- exported routines -------------------------*/ 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 } /* Initialize_Token_Buffer */ 01387 01388 01389 void 01390 Terminate_Token_Buffer(FILE *srcpos_map_file) 01391 { 01392 /* Free up all malloced space! */ 01393 free_buffer_list(buffer_free_list); 01394 01395 /* Emit the file-number to file-name mapping table */ 01396 if (Max_Srcpos_Map_Filenum > 0) 01397 Write_Srcpos_File_Map_Table(srcpos_map_file); 01398 01399 } /* Terminate_Token_Buffer */ 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 } /* Set_Maximum_Linelength */ 01410 01411 01412 BOOL 01413 HAS_Maximum_Linelength(void) 01414 { 01415 return Max_Line_Length==0; 01416 } /* Get_Maximum_Linelength */ 01417 01418 01419 UINT32 01420 Get_Maximum_Linelength(void) 01421 { 01422 return Max_Line_Length; 01423 } /* Get_Maximum_Linelength */ 01424 01425 01426 void 01427 Free_Token_Buffer_Memory(void) 01428 { 01429 free_buffer_list(buffer_free_list); 01430 } /* free_token_buffer_memory */ 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 } /* New_Token_Buffer */ 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 } /* Reclaim_Token_Buffer */ 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 } /* Is_Empty_Token_Buffer */ 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 } /*switch*/ 01532 } /*if*/ 01533 } /*for*/ 01534 } /*if*/ 01535 01536 return identical; 01537 } /* Identical_Token_Lists */ 01538 01539 01540 UINT 01541 Current_Indentation(void) 01542 { 01543 return requested_indentation; 01544 } /* Current_Indentation */ 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 } /* Set_Current_Indentation */ 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 } /* Set_Indentation_Step */ 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 } /* Increment_Indentation */ 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 } /* Decrement_Indentation */ 01593 01594 01595 void 01596 Zero_Indentation(void) 01597 { 01598 requested_indentation = current_indentation = 0; 01599 } /* Zero_Indentation */ 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 } /* Append_F77_Indented_Newline */ 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 } /* Prepend_F77_Indented_Newline */ 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 } /* Append_F77_Indented_Continuation */ 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 } /* Prepend_F77_Indented_Newline */ 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 } /* Append_F77_Comment_Newline */ 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 } /* Prepend_F77_Comment_Newline */ 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 } /* Append_F77_Directive_Newline */ 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 } /* Prepend_F77_Directive_Newline */ 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 } /* Append_F77_Sequence_No */ 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 } /* Prepend_F77_Sequence_No */ 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 } /* Append_Srcpos_Map */ 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 } /* Append_Srcpos_Directive */ 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 } /* Prepend_Srcpos_Map */ 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 } /* Prepend_Srcpos_Directive */ 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 /* Save the current source and column numbers and restore them 01963 * at the end. These tokens do not apply to any srcpos map. 01964 */ 01965 saved_output_line = Current_Output_Line; 01966 saved_output_col = Current_Output_Col; 01967 } 01968 01969 /* Write tokens to the ofile, and all SRCPOS_MAP_TOKENs to 01970 * the srcpos_map_file. 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 /* Write out remaining characters, since the same buffer is used 01990 * to write to different files! 01991 */ 01992 flush_write_buffer(ofile, NULL, 0); 01993 01994 if (srcpos_map_file == NULL) 01995 { 01996 /* Restore the current source and column numbers . 01997 */ 01998 Current_Output_Line = saved_output_line; 01999 Current_Output_Col = saved_output_col; 02000 } 02001 } /* Write_And_Reclaim_Tokens */ 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 /* Save the current source and column numbers and restore them 02016 * at the end. These tokens do not apply to any srcpos map. 02017 */ 02018 saved_output_line = Current_Output_Line; 02019 saved_output_col = Current_Output_Col; 02020 02021 /* Write tokens to the string, but skip all SRCPOS_MAP_TOKENs */ 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 /* Write out remaining characters and terminate the string. 02042 */ 02043 flush_write_buffer(NULL, &strbuf, &buflen); 02044 Is_True(buflen > 0, ("String buffer overflow!")); 02045 *strbuf = '\0'; /* Terminate the output string */ 02046 02047 /* Restore the current source and column numbers . 02048 */ 02049 Current_Output_Line = saved_output_line; 02050 Current_Output_Col = saved_output_col; 02051 } /* Str_Write_And_Reclaim_Tokens */ 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 } /* Write_String */