1 1.1.1.4 mrg /* Copyright (C) 2002-2024 Free Software Foundation, Inc. 2 1.1 mrg Contributed by Andy Vaught 3 1.1 mrg F2003 I/O support contributed by Jerry DeLisle 4 1.1 mrg 5 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran). 6 1.1 mrg 7 1.1 mrg Libgfortran is free software; you can redistribute it and/or modify 8 1.1 mrg it under the terms of the GNU General Public License as published by 9 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 10 1.1 mrg any later version. 11 1.1 mrg 12 1.1 mrg Libgfortran is distributed in the hope that it will be useful, 13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 18 1.1 mrg permissions described in the GCC Runtime Library Exception, version 19 1.1 mrg 3.1, as published by the Free Software Foundation. 20 1.1 mrg 21 1.1 mrg You should have received a copy of the GNU General Public License and 22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 1.1 mrg <http://www.gnu.org/licenses/>. */ 25 1.1 mrg 26 1.1 mrg 27 1.1 mrg /* format.c-- parse a FORMAT string into a binary format suitable for 28 1.1 mrg interpretation during I/O statements. */ 29 1.1 mrg 30 1.1 mrg #include "io.h" 31 1.1 mrg #include "format.h" 32 1.1 mrg #include <string.h> 33 1.1 mrg 34 1.1 mrg 35 1.1.1.4 mrg static const fnode colon_node = { FMT_COLON, FMT_NONE, 0, NULL, NULL, {{ 0, 0, 0 }}, 0, 36 1.1 mrg NULL }; 37 1.1 mrg 38 1.1 mrg /* Error messages. */ 39 1.1 mrg 40 1.1.1.2 mrg static const char posint_required[] = "Positive integer required in format", 41 1.1 mrg period_required[] = "Period required in format", 42 1.1 mrg nonneg_required[] = "Nonnegative width required in format", 43 1.1 mrg unexpected_element[] = "Unexpected element '%c' in format\n", 44 1.1 mrg unexpected_end[] = "Unexpected end of format string", 45 1.1 mrg bad_string[] = "Unterminated character constant in format", 46 1.1 mrg bad_hollerith[] = "Hollerith constant extends past the end of the format", 47 1.1 mrg reversion_error[] = "Exhausted data descriptors in format", 48 1.1 mrg zero_width[] = "Zero width in format descriptor"; 49 1.1 mrg 50 1.1 mrg /* The following routines support caching format data from parsed format strings 51 1.1 mrg into a hash table. This avoids repeatedly parsing duplicate format strings 52 1.1 mrg or format strings in I/O statements that are repeated in loops. */ 53 1.1 mrg 54 1.1 mrg 55 1.1 mrg /* Traverse the table and free all data. */ 56 1.1 mrg 57 1.1 mrg void 58 1.1 mrg free_format_hash_table (gfc_unit *u) 59 1.1 mrg { 60 1.1 mrg size_t i; 61 1.1 mrg 62 1.1 mrg /* free_format_data handles any NULL pointers. */ 63 1.1 mrg for (i = 0; i < FORMAT_HASH_SIZE; i++) 64 1.1 mrg { 65 1.1 mrg if (u->format_hash_table[i].hashed_fmt != NULL) 66 1.1 mrg { 67 1.1 mrg free_format_data (u->format_hash_table[i].hashed_fmt); 68 1.1 mrg free (u->format_hash_table[i].key); 69 1.1 mrg } 70 1.1 mrg u->format_hash_table[i].key = NULL; 71 1.1 mrg u->format_hash_table[i].key_len = 0; 72 1.1 mrg u->format_hash_table[i].hashed_fmt = NULL; 73 1.1 mrg } 74 1.1 mrg } 75 1.1 mrg 76 1.1 mrg /* Traverse the format_data structure and reset the fnode counters. */ 77 1.1 mrg 78 1.1 mrg static void 79 1.1 mrg reset_node (fnode *fn) 80 1.1 mrg { 81 1.1 mrg fnode *f; 82 1.1 mrg 83 1.1 mrg fn->count = 0; 84 1.1 mrg fn->current = NULL; 85 1.1 mrg 86 1.1 mrg if (fn->format != FMT_LPAREN) 87 1.1 mrg return; 88 1.1 mrg 89 1.1 mrg for (f = fn->u.child; f; f = f->next) 90 1.1 mrg { 91 1.1 mrg if (f->format == FMT_RPAREN) 92 1.1 mrg break; 93 1.1 mrg reset_node (f); 94 1.1 mrg } 95 1.1 mrg } 96 1.1 mrg 97 1.1 mrg static void 98 1.1 mrg reset_fnode_counters (st_parameter_dt *dtp) 99 1.1 mrg { 100 1.1 mrg fnode *f; 101 1.1 mrg format_data *fmt; 102 1.1 mrg 103 1.1 mrg fmt = dtp->u.p.fmt; 104 1.1 mrg 105 1.1 mrg /* Clear this pointer at the head so things start at the right place. */ 106 1.1 mrg fmt->array.array[0].current = NULL; 107 1.1 mrg 108 1.1 mrg for (f = fmt->array.array[0].u.child; f; f = f->next) 109 1.1 mrg reset_node (f); 110 1.1 mrg } 111 1.1 mrg 112 1.1 mrg 113 1.1 mrg /* A simple hashing function to generate an index into the hash table. */ 114 1.1 mrg 115 1.1 mrg static uint32_t 116 1.1 mrg format_hash (st_parameter_dt *dtp) 117 1.1 mrg { 118 1.1 mrg char *key; 119 1.1 mrg gfc_charlen_type key_len; 120 1.1 mrg uint32_t hash = 0; 121 1.1 mrg gfc_charlen_type i; 122 1.1 mrg 123 1.1 mrg /* Hash the format string. Super simple, but what the heck! */ 124 1.1 mrg key = dtp->format; 125 1.1 mrg key_len = dtp->format_len; 126 1.1 mrg for (i = 0; i < key_len; i++) 127 1.1 mrg hash ^= key[i]; 128 1.1 mrg hash &= (FORMAT_HASH_SIZE - 1); 129 1.1 mrg return hash; 130 1.1 mrg } 131 1.1 mrg 132 1.1 mrg 133 1.1 mrg static void 134 1.1 mrg save_parsed_format (st_parameter_dt *dtp) 135 1.1 mrg { 136 1.1 mrg uint32_t hash; 137 1.1 mrg gfc_unit *u; 138 1.1 mrg 139 1.1 mrg hash = format_hash (dtp); 140 1.1 mrg u = dtp->u.p.current_unit; 141 1.1 mrg 142 1.1 mrg /* Index into the hash table. We are simply replacing whatever is there 143 1.1 mrg relying on probability. */ 144 1.1 mrg if (u->format_hash_table[hash].hashed_fmt != NULL) 145 1.1 mrg free_format_data (u->format_hash_table[hash].hashed_fmt); 146 1.1 mrg u->format_hash_table[hash].hashed_fmt = NULL; 147 1.1 mrg 148 1.1 mrg free (u->format_hash_table[hash].key); 149 1.1 mrg u->format_hash_table[hash].key = dtp->format; 150 1.1 mrg 151 1.1 mrg u->format_hash_table[hash].key_len = dtp->format_len; 152 1.1 mrg u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt; 153 1.1 mrg } 154 1.1 mrg 155 1.1 mrg 156 1.1 mrg static format_data * 157 1.1 mrg find_parsed_format (st_parameter_dt *dtp) 158 1.1 mrg { 159 1.1 mrg uint32_t hash; 160 1.1 mrg gfc_unit *u; 161 1.1 mrg 162 1.1 mrg hash = format_hash (dtp); 163 1.1 mrg u = dtp->u.p.current_unit; 164 1.1 mrg 165 1.1 mrg if (u->format_hash_table[hash].key != NULL) 166 1.1 mrg { 167 1.1 mrg /* See if it matches. */ 168 1.1 mrg if (u->format_hash_table[hash].key_len == dtp->format_len) 169 1.1 mrg { 170 1.1 mrg /* So far so good. */ 171 1.1 mrg if (strncmp (u->format_hash_table[hash].key, 172 1.1 mrg dtp->format, dtp->format_len) == 0) 173 1.1 mrg return u->format_hash_table[hash].hashed_fmt; 174 1.1 mrg } 175 1.1 mrg } 176 1.1 mrg return NULL; 177 1.1 mrg } 178 1.1 mrg 179 1.1 mrg 180 1.1 mrg /* next_char()-- Return the next character in the format string. 181 1.1 mrg Returns -1 when the string is done. If the literal flag is set, 182 1.1 mrg spaces are significant, otherwise they are not. */ 183 1.1 mrg 184 1.1 mrg static int 185 1.1 mrg next_char (format_data *fmt, int literal) 186 1.1 mrg { 187 1.1 mrg int c; 188 1.1 mrg 189 1.1 mrg do 190 1.1 mrg { 191 1.1 mrg if (fmt->format_string_len == 0) 192 1.1 mrg return -1; 193 1.1 mrg 194 1.1 mrg fmt->format_string_len--; 195 1.1.1.3 mrg c = safe_toupper (*fmt->format_string++); 196 1.1 mrg fmt->error_element = c; 197 1.1 mrg } 198 1.1 mrg while ((c == ' ' || c == '\t') && !literal); 199 1.1 mrg 200 1.1 mrg return c; 201 1.1 mrg } 202 1.1 mrg 203 1.1 mrg 204 1.1 mrg /* unget_char()-- Back up one character position. */ 205 1.1 mrg 206 1.1 mrg #define unget_char(fmt) \ 207 1.1 mrg { fmt->format_string--; fmt->format_string_len++; } 208 1.1 mrg 209 1.1 mrg 210 1.1 mrg /* get_fnode()-- Allocate a new format node, inserting it into the 211 1.1 mrg current singly linked list. These are initially allocated from the 212 1.1 mrg static buffer. */ 213 1.1 mrg 214 1.1 mrg static fnode * 215 1.1 mrg get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t) 216 1.1 mrg { 217 1.1 mrg fnode *f; 218 1.1 mrg 219 1.1 mrg if (fmt->avail == &fmt->last->array[FARRAY_SIZE]) 220 1.1 mrg { 221 1.1 mrg fmt->last->next = xmalloc (sizeof (fnode_array)); 222 1.1 mrg fmt->last = fmt->last->next; 223 1.1 mrg fmt->last->next = NULL; 224 1.1 mrg fmt->avail = &fmt->last->array[0]; 225 1.1 mrg } 226 1.1 mrg f = fmt->avail++; 227 1.1 mrg memset (f, '\0', sizeof (fnode)); 228 1.1.1.4 mrg f->pushed = FMT_NONE; 229 1.1 mrg 230 1.1 mrg if (*head == NULL) 231 1.1 mrg *head = *tail = f; 232 1.1 mrg else 233 1.1 mrg { 234 1.1 mrg (*tail)->next = f; 235 1.1 mrg *tail = f; 236 1.1 mrg } 237 1.1 mrg 238 1.1 mrg f->format = t; 239 1.1 mrg f->repeat = -1; 240 1.1 mrg f->source = fmt->format_string; 241 1.1 mrg return f; 242 1.1 mrg } 243 1.1 mrg 244 1.1 mrg 245 1.1 mrg /* free_format()-- Free allocated format string. */ 246 1.1 mrg void 247 1.1 mrg free_format (st_parameter_dt *dtp) 248 1.1 mrg { 249 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_FORMAT) && dtp->format) 250 1.1 mrg { 251 1.1 mrg free (dtp->format); 252 1.1 mrg dtp->format = NULL; 253 1.1 mrg } 254 1.1 mrg } 255 1.1 mrg 256 1.1 mrg 257 1.1 mrg /* free_format_data()-- Free all allocated format data. */ 258 1.1 mrg 259 1.1 mrg void 260 1.1 mrg free_format_data (format_data *fmt) 261 1.1 mrg { 262 1.1 mrg fnode_array *fa, *fa_next; 263 1.1 mrg fnode *fnp; 264 1.1 mrg 265 1.1 mrg if (fmt == NULL) 266 1.1 mrg return; 267 1.1 mrg 268 1.1 mrg /* Free vlist descriptors in the fnode_array if one was allocated. */ 269 1.1 mrg for (fnp = fmt->array.array; fnp < &fmt->array.array[FARRAY_SIZE] && 270 1.1 mrg fnp->format != FMT_NONE; fnp++) 271 1.1 mrg if (fnp->format == FMT_DT) 272 1.1 mrg { 273 1.1.1.4 mrg free (GFC_DESCRIPTOR_DATA(fnp->u.udf.vlist)); 274 1.1 mrg free (fnp->u.udf.vlist); 275 1.1 mrg } 276 1.1 mrg 277 1.1 mrg for (fa = fmt->array.next; fa; fa = fa_next) 278 1.1 mrg { 279 1.1 mrg fa_next = fa->next; 280 1.1 mrg free (fa); 281 1.1 mrg } 282 1.1 mrg 283 1.1 mrg free (fmt); 284 1.1 mrg fmt = NULL; 285 1.1 mrg } 286 1.1 mrg 287 1.1 mrg 288 1.1 mrg /* format_lex()-- Simple lexical analyzer for getting the next token 289 1.1 mrg in a FORMAT string. We support a one-level token pushback in the 290 1.1 mrg fmt->saved_token variable. */ 291 1.1 mrg 292 1.1 mrg static format_token 293 1.1 mrg format_lex (format_data *fmt) 294 1.1 mrg { 295 1.1 mrg format_token token; 296 1.1 mrg int negative_flag; 297 1.1 mrg int c; 298 1.1 mrg char delim; 299 1.1 mrg 300 1.1 mrg if (fmt->saved_token != FMT_NONE) 301 1.1 mrg { 302 1.1 mrg token = fmt->saved_token; 303 1.1 mrg fmt->saved_token = FMT_NONE; 304 1.1 mrg return token; 305 1.1 mrg } 306 1.1 mrg 307 1.1 mrg negative_flag = 0; 308 1.1 mrg c = next_char (fmt, 0); 309 1.1 mrg 310 1.1 mrg switch (c) 311 1.1 mrg { 312 1.1 mrg case '*': 313 1.1 mrg token = FMT_STAR; 314 1.1 mrg break; 315 1.1 mrg 316 1.1 mrg case '(': 317 1.1 mrg token = FMT_LPAREN; 318 1.1 mrg break; 319 1.1 mrg 320 1.1 mrg case ')': 321 1.1 mrg token = FMT_RPAREN; 322 1.1 mrg break; 323 1.1 mrg 324 1.1 mrg case '-': 325 1.1 mrg negative_flag = 1; 326 1.1 mrg /* Fall Through */ 327 1.1 mrg 328 1.1 mrg case '+': 329 1.1 mrg c = next_char (fmt, 0); 330 1.1.1.3 mrg if (!safe_isdigit (c)) 331 1.1 mrg { 332 1.1 mrg token = FMT_UNKNOWN; 333 1.1 mrg break; 334 1.1 mrg } 335 1.1 mrg 336 1.1 mrg fmt->value = c - '0'; 337 1.1 mrg 338 1.1 mrg for (;;) 339 1.1 mrg { 340 1.1 mrg c = next_char (fmt, 0); 341 1.1.1.3 mrg if (!safe_isdigit (c)) 342 1.1 mrg break; 343 1.1 mrg 344 1.1 mrg fmt->value = 10 * fmt->value + c - '0'; 345 1.1 mrg } 346 1.1 mrg 347 1.1 mrg unget_char (fmt); 348 1.1 mrg 349 1.1 mrg if (negative_flag) 350 1.1 mrg fmt->value = -fmt->value; 351 1.1 mrg token = FMT_SIGNED_INT; 352 1.1 mrg break; 353 1.1 mrg 354 1.1 mrg case '0': 355 1.1 mrg case '1': 356 1.1 mrg case '2': 357 1.1 mrg case '3': 358 1.1 mrg case '4': 359 1.1 mrg case '5': 360 1.1 mrg case '6': 361 1.1 mrg case '7': 362 1.1 mrg case '8': 363 1.1 mrg case '9': 364 1.1 mrg fmt->value = c - '0'; 365 1.1 mrg 366 1.1 mrg for (;;) 367 1.1 mrg { 368 1.1 mrg c = next_char (fmt, 0); 369 1.1.1.3 mrg if (!safe_isdigit (c)) 370 1.1 mrg break; 371 1.1 mrg 372 1.1 mrg fmt->value = 10 * fmt->value + c - '0'; 373 1.1 mrg } 374 1.1 mrg 375 1.1 mrg unget_char (fmt); 376 1.1 mrg token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT; 377 1.1 mrg break; 378 1.1 mrg 379 1.1 mrg case '.': 380 1.1 mrg token = FMT_PERIOD; 381 1.1 mrg break; 382 1.1 mrg 383 1.1 mrg case ',': 384 1.1 mrg token = FMT_COMMA; 385 1.1 mrg break; 386 1.1 mrg 387 1.1 mrg case ':': 388 1.1 mrg token = FMT_COLON; 389 1.1 mrg break; 390 1.1 mrg 391 1.1 mrg case '/': 392 1.1 mrg token = FMT_SLASH; 393 1.1 mrg break; 394 1.1 mrg 395 1.1 mrg case '$': 396 1.1 mrg token = FMT_DOLLAR; 397 1.1 mrg break; 398 1.1 mrg 399 1.1 mrg case 'T': 400 1.1 mrg switch (next_char (fmt, 0)) 401 1.1 mrg { 402 1.1 mrg case 'L': 403 1.1 mrg token = FMT_TL; 404 1.1 mrg break; 405 1.1 mrg case 'R': 406 1.1 mrg token = FMT_TR; 407 1.1 mrg break; 408 1.1 mrg default: 409 1.1 mrg token = FMT_T; 410 1.1 mrg unget_char (fmt); 411 1.1 mrg break; 412 1.1 mrg } 413 1.1 mrg 414 1.1 mrg break; 415 1.1 mrg 416 1.1 mrg case 'X': 417 1.1 mrg token = FMT_X; 418 1.1 mrg break; 419 1.1 mrg 420 1.1 mrg case 'S': 421 1.1 mrg switch (next_char (fmt, 0)) 422 1.1 mrg { 423 1.1 mrg case 'S': 424 1.1 mrg token = FMT_SS; 425 1.1 mrg break; 426 1.1 mrg case 'P': 427 1.1 mrg token = FMT_SP; 428 1.1 mrg break; 429 1.1 mrg default: 430 1.1 mrg token = FMT_S; 431 1.1 mrg unget_char (fmt); 432 1.1 mrg break; 433 1.1 mrg } 434 1.1 mrg 435 1.1 mrg break; 436 1.1 mrg 437 1.1 mrg case 'B': 438 1.1 mrg switch (next_char (fmt, 0)) 439 1.1 mrg { 440 1.1 mrg case 'N': 441 1.1 mrg token = FMT_BN; 442 1.1 mrg break; 443 1.1 mrg case 'Z': 444 1.1 mrg token = FMT_BZ; 445 1.1 mrg break; 446 1.1 mrg default: 447 1.1 mrg token = FMT_B; 448 1.1 mrg unget_char (fmt); 449 1.1 mrg break; 450 1.1 mrg } 451 1.1 mrg 452 1.1 mrg break; 453 1.1 mrg 454 1.1 mrg case '\'': 455 1.1 mrg case '"': 456 1.1 mrg delim = c; 457 1.1 mrg 458 1.1 mrg fmt->string = fmt->format_string; 459 1.1 mrg fmt->value = 0; /* This is the length of the string */ 460 1.1 mrg 461 1.1 mrg for (;;) 462 1.1 mrg { 463 1.1 mrg c = next_char (fmt, 1); 464 1.1 mrg if (c == -1) 465 1.1 mrg { 466 1.1 mrg token = FMT_BADSTRING; 467 1.1 mrg fmt->error = bad_string; 468 1.1 mrg break; 469 1.1 mrg } 470 1.1 mrg 471 1.1 mrg if (c == delim) 472 1.1 mrg { 473 1.1 mrg c = next_char (fmt, 1); 474 1.1 mrg 475 1.1 mrg if (c == -1) 476 1.1 mrg { 477 1.1 mrg token = FMT_BADSTRING; 478 1.1 mrg fmt->error = bad_string; 479 1.1 mrg break; 480 1.1 mrg } 481 1.1 mrg 482 1.1 mrg if (c != delim) 483 1.1 mrg { 484 1.1 mrg unget_char (fmt); 485 1.1 mrg token = FMT_STRING; 486 1.1 mrg break; 487 1.1 mrg } 488 1.1 mrg } 489 1.1 mrg 490 1.1 mrg fmt->value++; 491 1.1 mrg } 492 1.1 mrg 493 1.1 mrg break; 494 1.1 mrg 495 1.1 mrg case 'P': 496 1.1 mrg token = FMT_P; 497 1.1 mrg break; 498 1.1 mrg 499 1.1 mrg case 'I': 500 1.1 mrg token = FMT_I; 501 1.1 mrg break; 502 1.1 mrg 503 1.1 mrg case 'O': 504 1.1 mrg token = FMT_O; 505 1.1 mrg break; 506 1.1 mrg 507 1.1 mrg case 'Z': 508 1.1 mrg token = FMT_Z; 509 1.1 mrg break; 510 1.1 mrg 511 1.1 mrg case 'F': 512 1.1 mrg token = FMT_F; 513 1.1 mrg break; 514 1.1 mrg 515 1.1 mrg case 'E': 516 1.1 mrg switch (next_char (fmt, 0)) 517 1.1 mrg { 518 1.1 mrg case 'N': 519 1.1 mrg token = FMT_EN; 520 1.1 mrg break; 521 1.1 mrg case 'S': 522 1.1 mrg token = FMT_ES; 523 1.1 mrg break; 524 1.1 mrg default: 525 1.1 mrg token = FMT_E; 526 1.1 mrg unget_char (fmt); 527 1.1 mrg break; 528 1.1 mrg } 529 1.1 mrg break; 530 1.1 mrg 531 1.1 mrg case 'G': 532 1.1 mrg token = FMT_G; 533 1.1 mrg break; 534 1.1 mrg 535 1.1 mrg case 'H': 536 1.1 mrg token = FMT_H; 537 1.1 mrg break; 538 1.1 mrg 539 1.1 mrg case 'L': 540 1.1 mrg token = FMT_L; 541 1.1 mrg break; 542 1.1 mrg 543 1.1 mrg case 'A': 544 1.1 mrg token = FMT_A; 545 1.1 mrg break; 546 1.1 mrg 547 1.1 mrg case 'D': 548 1.1 mrg switch (next_char (fmt, 0)) 549 1.1 mrg { 550 1.1 mrg case 'P': 551 1.1 mrg token = FMT_DP; 552 1.1 mrg break; 553 1.1 mrg case 'C': 554 1.1 mrg token = FMT_DC; 555 1.1 mrg break; 556 1.1 mrg case 'T': 557 1.1 mrg token = FMT_DT; 558 1.1 mrg break; 559 1.1 mrg default: 560 1.1 mrg token = FMT_D; 561 1.1 mrg unget_char (fmt); 562 1.1 mrg break; 563 1.1 mrg } 564 1.1 mrg break; 565 1.1 mrg 566 1.1 mrg case 'R': 567 1.1 mrg switch (next_char (fmt, 0)) 568 1.1 mrg { 569 1.1 mrg case 'C': 570 1.1 mrg token = FMT_RC; 571 1.1 mrg break; 572 1.1 mrg case 'D': 573 1.1 mrg token = FMT_RD; 574 1.1 mrg break; 575 1.1 mrg case 'N': 576 1.1 mrg token = FMT_RN; 577 1.1 mrg break; 578 1.1 mrg case 'P': 579 1.1 mrg token = FMT_RP; 580 1.1 mrg break; 581 1.1 mrg case 'U': 582 1.1 mrg token = FMT_RU; 583 1.1 mrg break; 584 1.1 mrg case 'Z': 585 1.1 mrg token = FMT_RZ; 586 1.1 mrg break; 587 1.1 mrg default: 588 1.1 mrg unget_char (fmt); 589 1.1 mrg token = FMT_UNKNOWN; 590 1.1 mrg break; 591 1.1 mrg } 592 1.1 mrg break; 593 1.1 mrg 594 1.1 mrg case -1: 595 1.1 mrg token = FMT_END; 596 1.1 mrg break; 597 1.1 mrg 598 1.1 mrg default: 599 1.1 mrg token = FMT_UNKNOWN; 600 1.1 mrg break; 601 1.1 mrg } 602 1.1 mrg 603 1.1 mrg return token; 604 1.1 mrg } 605 1.1 mrg 606 1.1 mrg 607 1.1 mrg /* parse_format_list()-- Parse a format list. Assumes that a left 608 1.1 mrg paren has already been seen. Returns a list representing the 609 1.1 mrg parenthesis node which contains the rest of the list. */ 610 1.1 mrg 611 1.1 mrg static fnode * 612 1.1 mrg parse_format_list (st_parameter_dt *dtp, bool *seen_dd) 613 1.1 mrg { 614 1.1 mrg fnode *head, *tail; 615 1.1 mrg format_token t, u, t2; 616 1.1 mrg int repeat; 617 1.1 mrg format_data *fmt = dtp->u.p.fmt; 618 1.1 mrg bool seen_data_desc = false; 619 1.1.1.3 mrg int standard; 620 1.1 mrg 621 1.1 mrg head = tail = NULL; 622 1.1 mrg 623 1.1 mrg /* Get the next format item */ 624 1.1 mrg format_item: 625 1.1 mrg t = format_lex (fmt); 626 1.1 mrg format_item_1: 627 1.1 mrg switch (t) 628 1.1 mrg { 629 1.1 mrg case FMT_STAR: 630 1.1 mrg t = format_lex (fmt); 631 1.1 mrg if (t != FMT_LPAREN) 632 1.1 mrg { 633 1.1 mrg fmt->error = "Left parenthesis required after '*'"; 634 1.1 mrg goto finished; 635 1.1 mrg } 636 1.1 mrg get_fnode (fmt, &head, &tail, FMT_LPAREN); 637 1.1 mrg tail->repeat = -2; /* Signifies unlimited format. */ 638 1.1 mrg tail->u.child = parse_format_list (dtp, &seen_data_desc); 639 1.1 mrg *seen_dd = seen_data_desc; 640 1.1 mrg if (fmt->error != NULL) 641 1.1 mrg goto finished; 642 1.1 mrg if (!seen_data_desc) 643 1.1 mrg { 644 1.1 mrg fmt->error = "'*' requires at least one associated data descriptor"; 645 1.1 mrg goto finished; 646 1.1 mrg } 647 1.1 mrg goto between_desc; 648 1.1 mrg 649 1.1 mrg case FMT_POSINT: 650 1.1 mrg repeat = fmt->value; 651 1.1 mrg 652 1.1 mrg t = format_lex (fmt); 653 1.1 mrg switch (t) 654 1.1 mrg { 655 1.1 mrg case FMT_LPAREN: 656 1.1 mrg get_fnode (fmt, &head, &tail, FMT_LPAREN); 657 1.1 mrg tail->repeat = repeat; 658 1.1 mrg tail->u.child = parse_format_list (dtp, &seen_data_desc); 659 1.1 mrg *seen_dd = seen_data_desc; 660 1.1 mrg if (fmt->error != NULL) 661 1.1 mrg goto finished; 662 1.1 mrg 663 1.1 mrg goto between_desc; 664 1.1 mrg 665 1.1 mrg case FMT_SLASH: 666 1.1 mrg get_fnode (fmt, &head, &tail, FMT_SLASH); 667 1.1 mrg tail->repeat = repeat; 668 1.1 mrg goto optional_comma; 669 1.1 mrg 670 1.1 mrg case FMT_X: 671 1.1 mrg get_fnode (fmt, &head, &tail, FMT_X); 672 1.1 mrg tail->repeat = 1; 673 1.1 mrg tail->u.k = fmt->value; 674 1.1 mrg goto between_desc; 675 1.1 mrg 676 1.1 mrg case FMT_P: 677 1.1 mrg goto p_descriptor; 678 1.1 mrg 679 1.1 mrg default: 680 1.1 mrg goto data_desc; 681 1.1 mrg } 682 1.1 mrg 683 1.1 mrg case FMT_LPAREN: 684 1.1 mrg get_fnode (fmt, &head, &tail, FMT_LPAREN); 685 1.1 mrg tail->repeat = 1; 686 1.1 mrg tail->u.child = parse_format_list (dtp, &seen_data_desc); 687 1.1 mrg *seen_dd = seen_data_desc; 688 1.1 mrg if (fmt->error != NULL) 689 1.1 mrg goto finished; 690 1.1 mrg 691 1.1 mrg goto between_desc; 692 1.1 mrg 693 1.1 mrg case FMT_SIGNED_INT: /* Signed integer can only precede a P format. */ 694 1.1 mrg case FMT_ZERO: /* Same for zero. */ 695 1.1 mrg t = format_lex (fmt); 696 1.1 mrg if (t != FMT_P) 697 1.1 mrg { 698 1.1 mrg fmt->error = "Expected P edit descriptor in format"; 699 1.1 mrg goto finished; 700 1.1 mrg } 701 1.1 mrg 702 1.1 mrg p_descriptor: 703 1.1 mrg get_fnode (fmt, &head, &tail, FMT_P); 704 1.1 mrg tail->u.k = fmt->value; 705 1.1 mrg tail->repeat = 1; 706 1.1 mrg 707 1.1 mrg t = format_lex (fmt); 708 1.1 mrg if (t == FMT_F || t == FMT_EN || t == FMT_ES || t == FMT_D 709 1.1 mrg || t == FMT_G || t == FMT_E) 710 1.1 mrg { 711 1.1 mrg repeat = 1; 712 1.1 mrg goto data_desc; 713 1.1 mrg } 714 1.1 mrg 715 1.1 mrg if (t != FMT_COMMA && t != FMT_RPAREN && t != FMT_SLASH 716 1.1 mrg && t != FMT_POSINT) 717 1.1 mrg { 718 1.1 mrg fmt->error = "Comma required after P descriptor"; 719 1.1 mrg goto finished; 720 1.1 mrg } 721 1.1 mrg 722 1.1 mrg fmt->saved_token = t; 723 1.1 mrg goto optional_comma; 724 1.1 mrg 725 1.1 mrg case FMT_P: /* P and X require a prior number */ 726 1.1 mrg fmt->error = "P descriptor requires leading scale factor"; 727 1.1 mrg goto finished; 728 1.1 mrg 729 1.1 mrg case FMT_X: 730 1.1 mrg /* 731 1.1 mrg EXTENSION! 732 1.1 mrg 733 1.1 mrg If we would be pedantic in the library, we would have to reject 734 1.1 mrg an X descriptor without an integer prefix: 735 1.1 mrg 736 1.1 mrg fmt->error = "X descriptor requires leading space count"; 737 1.1 mrg goto finished; 738 1.1 mrg 739 1.1 mrg However, this is an extension supported by many Fortran compilers, 740 1.1 mrg including Cray, HP, AIX, and IRIX. Therefore, we allow it in the 741 1.1 mrg runtime library, and make the front end reject it if the compiler 742 1.1 mrg is in pedantic mode. The interpretation of 'X' is '1X'. 743 1.1 mrg */ 744 1.1 mrg get_fnode (fmt, &head, &tail, FMT_X); 745 1.1 mrg tail->repeat = 1; 746 1.1 mrg tail->u.k = 1; 747 1.1 mrg goto between_desc; 748 1.1 mrg 749 1.1 mrg case FMT_STRING: 750 1.1 mrg get_fnode (fmt, &head, &tail, FMT_STRING); 751 1.1 mrg tail->u.string.p = fmt->string; 752 1.1 mrg tail->u.string.length = fmt->value; 753 1.1 mrg tail->repeat = 1; 754 1.1 mrg goto optional_comma; 755 1.1 mrg 756 1.1 mrg case FMT_RC: 757 1.1 mrg case FMT_RD: 758 1.1 mrg case FMT_RN: 759 1.1 mrg case FMT_RP: 760 1.1 mrg case FMT_RU: 761 1.1 mrg case FMT_RZ: 762 1.1 mrg notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: Round " 763 1.1 mrg "descriptor not allowed"); 764 1.1 mrg get_fnode (fmt, &head, &tail, t); 765 1.1 mrg tail->repeat = 1; 766 1.1 mrg goto between_desc; 767 1.1 mrg 768 1.1 mrg case FMT_DC: 769 1.1 mrg case FMT_DP: 770 1.1 mrg notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: DC or DP " 771 1.1 mrg "descriptor not allowed"); 772 1.1 mrg /* Fall through. */ 773 1.1 mrg case FMT_S: 774 1.1 mrg case FMT_SS: 775 1.1 mrg case FMT_SP: 776 1.1 mrg case FMT_BN: 777 1.1 mrg case FMT_BZ: 778 1.1 mrg get_fnode (fmt, &head, &tail, t); 779 1.1 mrg tail->repeat = 1; 780 1.1 mrg goto between_desc; 781 1.1 mrg 782 1.1 mrg case FMT_COLON: 783 1.1 mrg get_fnode (fmt, &head, &tail, FMT_COLON); 784 1.1 mrg tail->repeat = 1; 785 1.1 mrg goto optional_comma; 786 1.1 mrg 787 1.1 mrg case FMT_SLASH: 788 1.1 mrg get_fnode (fmt, &head, &tail, FMT_SLASH); 789 1.1 mrg tail->repeat = 1; 790 1.1 mrg tail->u.r = 1; 791 1.1 mrg goto optional_comma; 792 1.1 mrg 793 1.1 mrg case FMT_DOLLAR: 794 1.1 mrg get_fnode (fmt, &head, &tail, FMT_DOLLAR); 795 1.1 mrg tail->repeat = 1; 796 1.1 mrg notify_std (&dtp->common, GFC_STD_GNU, "Extension: $ descriptor"); 797 1.1 mrg goto between_desc; 798 1.1 mrg 799 1.1 mrg case FMT_T: 800 1.1 mrg case FMT_TL: 801 1.1 mrg case FMT_TR: 802 1.1 mrg t2 = format_lex (fmt); 803 1.1 mrg if (t2 != FMT_POSINT) 804 1.1 mrg { 805 1.1 mrg fmt->error = posint_required; 806 1.1 mrg goto finished; 807 1.1 mrg } 808 1.1 mrg get_fnode (fmt, &head, &tail, t); 809 1.1 mrg tail->u.n = fmt->value; 810 1.1 mrg tail->repeat = 1; 811 1.1 mrg goto between_desc; 812 1.1 mrg 813 1.1 mrg case FMT_I: 814 1.1 mrg case FMT_B: 815 1.1 mrg case FMT_O: 816 1.1 mrg case FMT_Z: 817 1.1 mrg case FMT_E: 818 1.1 mrg case FMT_EN: 819 1.1 mrg case FMT_ES: 820 1.1 mrg case FMT_D: 821 1.1 mrg case FMT_DT: 822 1.1 mrg case FMT_L: 823 1.1 mrg case FMT_A: 824 1.1 mrg case FMT_F: 825 1.1 mrg case FMT_G: 826 1.1 mrg repeat = 1; 827 1.1 mrg *seen_dd = true; 828 1.1 mrg goto data_desc; 829 1.1 mrg 830 1.1 mrg case FMT_H: 831 1.1 mrg get_fnode (fmt, &head, &tail, FMT_STRING); 832 1.1 mrg if (fmt->format_string_len < 1) 833 1.1 mrg { 834 1.1 mrg fmt->error = bad_hollerith; 835 1.1 mrg goto finished; 836 1.1 mrg } 837 1.1 mrg 838 1.1 mrg tail->u.string.p = fmt->format_string; 839 1.1 mrg tail->u.string.length = 1; 840 1.1 mrg tail->repeat = 1; 841 1.1 mrg 842 1.1 mrg fmt->format_string++; 843 1.1 mrg fmt->format_string_len--; 844 1.1 mrg 845 1.1 mrg goto between_desc; 846 1.1 mrg 847 1.1 mrg case FMT_END: 848 1.1 mrg fmt->error = unexpected_end; 849 1.1 mrg goto finished; 850 1.1 mrg 851 1.1 mrg case FMT_BADSTRING: 852 1.1 mrg goto finished; 853 1.1 mrg 854 1.1 mrg case FMT_RPAREN: 855 1.1 mrg goto finished; 856 1.1 mrg 857 1.1 mrg default: 858 1.1 mrg fmt->error = unexpected_element; 859 1.1 mrg goto finished; 860 1.1 mrg } 861 1.1 mrg 862 1.1 mrg /* In this state, t must currently be a data descriptor. Deal with 863 1.1 mrg things that can/must follow the descriptor */ 864 1.1 mrg data_desc: 865 1.1 mrg 866 1.1 mrg switch (t) 867 1.1 mrg { 868 1.1 mrg case FMT_L: 869 1.1 mrg *seen_dd = true; 870 1.1 mrg t = format_lex (fmt); 871 1.1 mrg if (t != FMT_POSINT) 872 1.1 mrg { 873 1.1 mrg if (t == FMT_ZERO) 874 1.1 mrg { 875 1.1 mrg if (notification_std(GFC_STD_GNU) == NOTIFICATION_ERROR) 876 1.1 mrg { 877 1.1 mrg fmt->error = "Extension: Zero width after L descriptor"; 878 1.1 mrg goto finished; 879 1.1 mrg } 880 1.1 mrg else 881 1.1 mrg notify_std (&dtp->common, GFC_STD_GNU, 882 1.1 mrg "Zero width after L descriptor"); 883 1.1 mrg } 884 1.1 mrg else 885 1.1 mrg { 886 1.1 mrg fmt->saved_token = t; 887 1.1 mrg notify_std (&dtp->common, GFC_STD_GNU, 888 1.1 mrg "Positive width required with L descriptor"); 889 1.1 mrg } 890 1.1 mrg fmt->value = 1; /* Default width */ 891 1.1 mrg } 892 1.1 mrg get_fnode (fmt, &head, &tail, FMT_L); 893 1.1 mrg tail->u.n = fmt->value; 894 1.1 mrg tail->repeat = repeat; 895 1.1 mrg break; 896 1.1 mrg 897 1.1 mrg case FMT_A: 898 1.1 mrg *seen_dd = true; 899 1.1 mrg t = format_lex (fmt); 900 1.1 mrg if (t == FMT_ZERO) 901 1.1 mrg { 902 1.1 mrg fmt->error = zero_width; 903 1.1 mrg goto finished; 904 1.1 mrg } 905 1.1 mrg 906 1.1 mrg if (t != FMT_POSINT) 907 1.1 mrg { 908 1.1 mrg fmt->saved_token = t; 909 1.1 mrg fmt->value = -1; /* Width not present */ 910 1.1 mrg } 911 1.1 mrg 912 1.1 mrg get_fnode (fmt, &head, &tail, FMT_A); 913 1.1 mrg tail->repeat = repeat; 914 1.1 mrg tail->u.n = fmt->value; 915 1.1 mrg break; 916 1.1 mrg 917 1.1 mrg case FMT_D: 918 1.1 mrg case FMT_E: 919 1.1 mrg case FMT_F: 920 1.1 mrg case FMT_G: 921 1.1 mrg case FMT_EN: 922 1.1 mrg case FMT_ES: 923 1.1 mrg *seen_dd = true; 924 1.1 mrg get_fnode (fmt, &head, &tail, t); 925 1.1 mrg tail->repeat = repeat; 926 1.1.1.4 mrg tail->pushed = FMT_NONE; 927 1.1 mrg 928 1.1 mrg u = format_lex (fmt); 929 1.1.1.2 mrg 930 1.1.1.2 mrg /* Processing for zero width formats. */ 931 1.1.1.2 mrg if (u == FMT_ZERO) 932 1.1 mrg { 933 1.1.1.3 mrg if (t == FMT_F) 934 1.1.1.3 mrg standard = GFC_STD_F95; 935 1.1.1.3 mrg else if (t == FMT_G) 936 1.1.1.3 mrg standard = GFC_STD_F2008; 937 1.1.1.3 mrg else 938 1.1.1.3 mrg standard = GFC_STD_F2018; 939 1.1.1.3 mrg 940 1.1.1.3 mrg if (notification_std (standard) == NOTIFICATION_ERROR 941 1.1 mrg || dtp->u.p.mode == READING) 942 1.1 mrg { 943 1.1 mrg fmt->error = zero_width; 944 1.1 mrg goto finished; 945 1.1 mrg } 946 1.1 mrg tail->u.real.w = 0; 947 1.1.1.2 mrg 948 1.1.1.2 mrg /* Look for the dot seperator. */ 949 1.1 mrg u = format_lex (fmt); 950 1.1 mrg if (u != FMT_PERIOD) 951 1.1 mrg { 952 1.1 mrg fmt->saved_token = u; 953 1.1 mrg break; 954 1.1 mrg } 955 1.1 mrg 956 1.1.1.2 mrg /* Look for the precision. */ 957 1.1 mrg u = format_lex (fmt); 958 1.1.1.2 mrg if (u != FMT_ZERO && u != FMT_POSINT) 959 1.1 mrg { 960 1.1.1.2 mrg fmt->error = nonneg_required; 961 1.1 mrg goto finished; 962 1.1 mrg } 963 1.1 mrg tail->u.real.d = fmt->value; 964 1.1.1.2 mrg 965 1.1.1.2 mrg /* Look for optional exponent, not allowed for FMT_D */ 966 1.1.1.2 mrg if (t == FMT_D) 967 1.1.1.2 mrg break; 968 1.1.1.2 mrg u = format_lex (fmt); 969 1.1.1.2 mrg if (u != FMT_E) 970 1.1.1.2 mrg fmt->saved_token = u; 971 1.1.1.2 mrg else 972 1.1.1.2 mrg { 973 1.1.1.2 mrg u = format_lex (fmt); 974 1.1.1.2 mrg if (u != FMT_POSINT) 975 1.1.1.2 mrg { 976 1.1.1.2 mrg if (u == FMT_ZERO) 977 1.1.1.2 mrg { 978 1.1.1.2 mrg notify_std (&dtp->common, GFC_STD_F2018, 979 1.1.1.2 mrg "Positive exponent width required"); 980 1.1.1.2 mrg } 981 1.1.1.2 mrg else 982 1.1.1.2 mrg { 983 1.1.1.2 mrg fmt->error = "Positive exponent width required in " 984 1.1.1.2 mrg "format string at %L"; 985 1.1.1.2 mrg goto finished; 986 1.1.1.2 mrg } 987 1.1.1.2 mrg } 988 1.1.1.2 mrg tail->u.real.e = fmt->value; 989 1.1.1.2 mrg } 990 1.1 mrg break; 991 1.1 mrg } 992 1.1.1.2 mrg 993 1.1.1.2 mrg /* Processing for positive width formats. */ 994 1.1.1.2 mrg if (u == FMT_POSINT) 995 1.1 mrg { 996 1.1.1.2 mrg tail->u.real.w = fmt->value; 997 1.1.1.2 mrg 998 1.1.1.2 mrg /* Look for the dot separator. Because of legacy behaviors 999 1.1.1.2 mrg we do some look ahead for missing things. */ 1000 1.1.1.2 mrg t2 = t; 1001 1.1.1.2 mrg t = format_lex (fmt); 1002 1.1.1.2 mrg if (t != FMT_PERIOD) 1003 1.1 mrg { 1004 1.1.1.2 mrg /* We treat a missing decimal descriptor as 0. Note: This is only 1005 1.1.1.2 mrg allowed if -std=legacy, otherwise an error occurs. */ 1006 1.1.1.2 mrg if (compile_options.warn_std != 0) 1007 1.1.1.2 mrg { 1008 1.1.1.2 mrg fmt->error = period_required; 1009 1.1.1.2 mrg goto finished; 1010 1.1.1.2 mrg } 1011 1.1.1.2 mrg fmt->saved_token = t; 1012 1.1.1.2 mrg tail->u.real.d = 0; 1013 1.1.1.2 mrg tail->u.real.e = -1; 1014 1.1.1.2 mrg break; 1015 1.1 mrg } 1016 1.1 mrg 1017 1.1.1.2 mrg /* If we made it here, we should have the dot so look for the 1018 1.1.1.2 mrg precision. */ 1019 1.1.1.2 mrg t = format_lex (fmt); 1020 1.1.1.2 mrg if (t != FMT_ZERO && t != FMT_POSINT) 1021 1.1 mrg { 1022 1.1.1.2 mrg fmt->error = nonneg_required; 1023 1.1 mrg goto finished; 1024 1.1 mrg } 1025 1.1.1.2 mrg tail->u.real.d = fmt->value; 1026 1.1 mrg tail->u.real.e = -1; 1027 1.1 mrg 1028 1.1.1.2 mrg /* Done with D and F formats. */ 1029 1.1.1.2 mrg if (t2 == FMT_D || t2 == FMT_F) 1030 1.1.1.2 mrg { 1031 1.1.1.2 mrg *seen_dd = true; 1032 1.1.1.2 mrg break; 1033 1.1.1.2 mrg } 1034 1.1 mrg 1035 1.1.1.2 mrg /* Look for optional exponent */ 1036 1.1.1.2 mrg u = format_lex (fmt); 1037 1.1.1.2 mrg if (u != FMT_E) 1038 1.1.1.2 mrg fmt->saved_token = u; 1039 1.1.1.2 mrg else 1040 1.1.1.2 mrg { 1041 1.1.1.2 mrg u = format_lex (fmt); 1042 1.1.1.2 mrg if (u != FMT_POSINT) 1043 1.1.1.2 mrg { 1044 1.1.1.2 mrg if (u == FMT_ZERO) 1045 1.1.1.2 mrg { 1046 1.1.1.2 mrg notify_std (&dtp->common, GFC_STD_F2018, 1047 1.1.1.2 mrg "Positive exponent width required"); 1048 1.1.1.2 mrg } 1049 1.1.1.2 mrg else 1050 1.1.1.2 mrg { 1051 1.1.1.2 mrg fmt->error = "Positive exponent width required in " 1052 1.1.1.2 mrg "format string at %L"; 1053 1.1.1.2 mrg goto finished; 1054 1.1.1.2 mrg } 1055 1.1.1.2 mrg } 1056 1.1.1.2 mrg tail->u.real.e = fmt->value; 1057 1.1.1.2 mrg } 1058 1.1 mrg break; 1059 1.1 mrg } 1060 1.1 mrg 1061 1.1.1.2 mrg /* Old DEC codes may not have width or precision specified. */ 1062 1.1.1.2 mrg if (dtp->u.p.mode == WRITING && (dtp->common.flags & IOPARM_DT_DEC_EXT)) 1063 1.1 mrg { 1064 1.1.1.2 mrg tail->u.real.w = DEFAULT_WIDTH; 1065 1.1.1.2 mrg tail->u.real.d = 0; 1066 1.1.1.2 mrg tail->u.real.e = -1; 1067 1.1.1.2 mrg fmt->saved_token = u; 1068 1.1 mrg } 1069 1.1 mrg break; 1070 1.1.1.2 mrg 1071 1.1 mrg case FMT_DT: 1072 1.1 mrg *seen_dd = true; 1073 1.1 mrg get_fnode (fmt, &head, &tail, t); 1074 1.1 mrg tail->repeat = repeat; 1075 1.1 mrg 1076 1.1 mrg t = format_lex (fmt); 1077 1.1 mrg 1078 1.1 mrg /* Initialize the vlist to a zero size, rank-one array. */ 1079 1.1 mrg tail->u.udf.vlist= xmalloc (sizeof(gfc_array_i4) 1080 1.1 mrg + sizeof (descriptor_dimension)); 1081 1.1 mrg GFC_DESCRIPTOR_DATA(tail->u.udf.vlist) = NULL; 1082 1.1 mrg GFC_DIMENSION_SET(tail->u.udf.vlist->dim[0],1, 0, 0); 1083 1.1 mrg 1084 1.1 mrg if (t == FMT_STRING) 1085 1.1 mrg { 1086 1.1 mrg /* Get pointer to the optional format string. */ 1087 1.1 mrg tail->u.udf.string = fmt->string; 1088 1.1 mrg tail->u.udf.string_len = fmt->value; 1089 1.1 mrg t = format_lex (fmt); 1090 1.1 mrg } 1091 1.1 mrg if (t == FMT_LPAREN) 1092 1.1 mrg { 1093 1.1 mrg /* Temporary buffer to hold the vlist values. */ 1094 1.1 mrg GFC_INTEGER_4 temp[FARRAY_SIZE]; 1095 1.1 mrg int i = 0; 1096 1.1 mrg loop: 1097 1.1 mrg t = format_lex (fmt); 1098 1.1 mrg if (t != FMT_POSINT) 1099 1.1 mrg { 1100 1.1 mrg fmt->error = posint_required; 1101 1.1 mrg goto finished; 1102 1.1 mrg } 1103 1.1 mrg /* Save the positive integer value. */ 1104 1.1 mrg temp[i++] = fmt->value; 1105 1.1 mrg t = format_lex (fmt); 1106 1.1 mrg if (t == FMT_COMMA) 1107 1.1 mrg goto loop; 1108 1.1 mrg if (t == FMT_RPAREN) 1109 1.1 mrg { 1110 1.1 mrg /* We have parsed the complete vlist so initialize the 1111 1.1 mrg array descriptor and save it in the format node. */ 1112 1.1 mrg gfc_full_array_i4 *vp = tail->u.udf.vlist; 1113 1.1 mrg GFC_DESCRIPTOR_DATA(vp) = xmalloc (i * sizeof(GFC_INTEGER_4)); 1114 1.1 mrg GFC_DIMENSION_SET(vp->dim[0],1, i, 1); 1115 1.1 mrg memcpy (GFC_DESCRIPTOR_DATA(vp), temp, i * sizeof(GFC_INTEGER_4)); 1116 1.1 mrg break; 1117 1.1 mrg } 1118 1.1 mrg fmt->error = unexpected_element; 1119 1.1 mrg goto finished; 1120 1.1 mrg } 1121 1.1 mrg fmt->saved_token = t; 1122 1.1 mrg break; 1123 1.1 mrg case FMT_H: 1124 1.1 mrg if (repeat > fmt->format_string_len) 1125 1.1 mrg { 1126 1.1 mrg fmt->error = bad_hollerith; 1127 1.1 mrg goto finished; 1128 1.1 mrg } 1129 1.1 mrg 1130 1.1 mrg get_fnode (fmt, &head, &tail, FMT_STRING); 1131 1.1 mrg tail->u.string.p = fmt->format_string; 1132 1.1 mrg tail->u.string.length = repeat; 1133 1.1 mrg tail->repeat = 1; 1134 1.1 mrg 1135 1.1 mrg fmt->format_string += fmt->value; 1136 1.1 mrg fmt->format_string_len -= repeat; 1137 1.1 mrg 1138 1.1 mrg break; 1139 1.1 mrg 1140 1.1 mrg case FMT_I: 1141 1.1 mrg case FMT_B: 1142 1.1 mrg case FMT_O: 1143 1.1 mrg case FMT_Z: 1144 1.1 mrg *seen_dd = true; 1145 1.1 mrg get_fnode (fmt, &head, &tail, t); 1146 1.1 mrg tail->repeat = repeat; 1147 1.1 mrg 1148 1.1 mrg t = format_lex (fmt); 1149 1.1 mrg 1150 1.1 mrg if (dtp->u.p.mode == READING) 1151 1.1 mrg { 1152 1.1 mrg if (t != FMT_POSINT) 1153 1.1 mrg { 1154 1.1.1.2 mrg if (dtp->common.flags & IOPARM_DT_DEC_EXT) 1155 1.1.1.2 mrg { 1156 1.1.1.2 mrg tail->u.integer.w = DEFAULT_WIDTH; 1157 1.1.1.2 mrg tail->u.integer.m = -1; 1158 1.1.1.2 mrg fmt->saved_token = t; 1159 1.1.1.2 mrg break; 1160 1.1.1.2 mrg } 1161 1.1 mrg fmt->error = posint_required; 1162 1.1 mrg goto finished; 1163 1.1 mrg } 1164 1.1 mrg } 1165 1.1 mrg else 1166 1.1 mrg { 1167 1.1 mrg if (t != FMT_ZERO && t != FMT_POSINT) 1168 1.1 mrg { 1169 1.1.1.2 mrg if (dtp->common.flags & IOPARM_DT_DEC_EXT) 1170 1.1.1.2 mrg { 1171 1.1.1.2 mrg tail->u.integer.w = DEFAULT_WIDTH; 1172 1.1.1.2 mrg tail->u.integer.m = -1; 1173 1.1.1.2 mrg fmt->saved_token = t; 1174 1.1.1.2 mrg break; 1175 1.1.1.2 mrg } 1176 1.1 mrg fmt->error = nonneg_required; 1177 1.1 mrg goto finished; 1178 1.1 mrg } 1179 1.1 mrg } 1180 1.1 mrg 1181 1.1 mrg tail->u.integer.w = fmt->value; 1182 1.1 mrg tail->u.integer.m = -1; 1183 1.1 mrg 1184 1.1 mrg t = format_lex (fmt); 1185 1.1 mrg if (t != FMT_PERIOD) 1186 1.1 mrg { 1187 1.1 mrg fmt->saved_token = t; 1188 1.1 mrg } 1189 1.1 mrg else 1190 1.1 mrg { 1191 1.1 mrg t = format_lex (fmt); 1192 1.1 mrg if (t != FMT_ZERO && t != FMT_POSINT) 1193 1.1 mrg { 1194 1.1 mrg fmt->error = nonneg_required; 1195 1.1 mrg goto finished; 1196 1.1 mrg } 1197 1.1 mrg 1198 1.1 mrg tail->u.integer.m = fmt->value; 1199 1.1 mrg } 1200 1.1 mrg 1201 1.1 mrg if (tail->u.integer.w != 0 && tail->u.integer.m > tail->u.integer.w) 1202 1.1 mrg { 1203 1.1 mrg fmt->error = "Minimum digits exceeds field width"; 1204 1.1 mrg goto finished; 1205 1.1 mrg } 1206 1.1 mrg 1207 1.1 mrg break; 1208 1.1 mrg 1209 1.1 mrg default: 1210 1.1 mrg fmt->error = unexpected_element; 1211 1.1 mrg goto finished; 1212 1.1 mrg } 1213 1.1 mrg 1214 1.1 mrg /* Between a descriptor and what comes next */ 1215 1.1 mrg between_desc: 1216 1.1 mrg t = format_lex (fmt); 1217 1.1 mrg switch (t) 1218 1.1 mrg { 1219 1.1 mrg case FMT_COMMA: 1220 1.1 mrg goto format_item; 1221 1.1 mrg 1222 1.1 mrg case FMT_RPAREN: 1223 1.1 mrg goto finished; 1224 1.1 mrg 1225 1.1 mrg case FMT_SLASH: 1226 1.1 mrg case FMT_COLON: 1227 1.1 mrg get_fnode (fmt, &head, &tail, t); 1228 1.1 mrg tail->repeat = 1; 1229 1.1 mrg goto optional_comma; 1230 1.1 mrg 1231 1.1 mrg case FMT_END: 1232 1.1 mrg fmt->error = unexpected_end; 1233 1.1 mrg goto finished; 1234 1.1 mrg 1235 1.1 mrg default: 1236 1.1 mrg /* Assume a missing comma, this is a GNU extension */ 1237 1.1 mrg goto format_item_1; 1238 1.1 mrg } 1239 1.1 mrg 1240 1.1 mrg /* Optional comma is a weird between state where we've just finished 1241 1.1 mrg reading a colon, slash or P descriptor. */ 1242 1.1 mrg optional_comma: 1243 1.1 mrg t = format_lex (fmt); 1244 1.1 mrg switch (t) 1245 1.1 mrg { 1246 1.1 mrg case FMT_COMMA: 1247 1.1 mrg break; 1248 1.1 mrg 1249 1.1 mrg case FMT_RPAREN: 1250 1.1 mrg goto finished; 1251 1.1 mrg 1252 1.1 mrg default: /* Assume that we have another format item */ 1253 1.1 mrg fmt->saved_token = t; 1254 1.1 mrg break; 1255 1.1 mrg } 1256 1.1 mrg 1257 1.1 mrg goto format_item; 1258 1.1 mrg 1259 1.1 mrg finished: 1260 1.1 mrg 1261 1.1 mrg return head; 1262 1.1 mrg } 1263 1.1 mrg 1264 1.1 mrg 1265 1.1 mrg /* format_error()-- Generate an error message for a format statement. 1266 1.1 mrg If the node that gives the location of the error is NULL, the error 1267 1.1 mrg is assumed to happen at parse time, and the current location of the 1268 1.1 mrg parser is shown. 1269 1.1 mrg 1270 1.1 mrg We generate a message showing where the problem is. We take extra 1271 1.1 mrg care to print only the relevant part of the format if it is longer 1272 1.1 mrg than a standard 80 column display. */ 1273 1.1 mrg 1274 1.1 mrg void 1275 1.1 mrg format_error (st_parameter_dt *dtp, const fnode *f, const char *message) 1276 1.1 mrg { 1277 1.1 mrg int width, i, offset; 1278 1.1 mrg #define BUFLEN 300 1279 1.1 mrg char *p, buffer[BUFLEN]; 1280 1.1 mrg format_data *fmt = dtp->u.p.fmt; 1281 1.1 mrg 1282 1.1 mrg if (f != NULL) 1283 1.1 mrg p = f->source; 1284 1.1 mrg else /* This should not happen. */ 1285 1.1 mrg p = dtp->format; 1286 1.1 mrg 1287 1.1 mrg if (message == unexpected_element) 1288 1.1 mrg snprintf (buffer, BUFLEN, message, fmt->error_element); 1289 1.1 mrg else 1290 1.1 mrg snprintf (buffer, BUFLEN, "%s\n", message); 1291 1.1 mrg 1292 1.1 mrg /* Get the offset into the format string where the error occurred. */ 1293 1.1 mrg offset = dtp->format_len - (fmt->reversion_ok ? 1294 1.1 mrg (int) strlen(p) : fmt->format_string_len); 1295 1.1 mrg 1296 1.1 mrg width = dtp->format_len; 1297 1.1 mrg 1298 1.1 mrg if (width > 80) 1299 1.1 mrg width = 80; 1300 1.1 mrg 1301 1.1 mrg /* Show the format */ 1302 1.1 mrg 1303 1.1 mrg p = strchr (buffer, '\0'); 1304 1.1 mrg 1305 1.1 mrg if (dtp->format) 1306 1.1 mrg memcpy (p, dtp->format, width); 1307 1.1 mrg 1308 1.1 mrg p += width; 1309 1.1 mrg *p++ = '\n'; 1310 1.1 mrg 1311 1.1 mrg /* Show where the problem is */ 1312 1.1 mrg 1313 1.1 mrg for (i = 1; i < offset; i++) 1314 1.1 mrg *p++ = ' '; 1315 1.1 mrg 1316 1.1 mrg *p++ = '^'; 1317 1.1 mrg *p = '\0'; 1318 1.1 mrg 1319 1.1 mrg generate_error (&dtp->common, LIBERROR_FORMAT, buffer); 1320 1.1 mrg } 1321 1.1 mrg 1322 1.1 mrg 1323 1.1 mrg /* revert()-- Do reversion of the format. Control reverts to the left 1324 1.1 mrg parenthesis that matches the rightmost right parenthesis. From our 1325 1.1 mrg tree structure, we are looking for the rightmost parenthesis node 1326 1.1 mrg at the second level, the first level always being a single 1327 1.1 mrg parenthesis node. If this node doesn't exit, we use the top 1328 1.1 mrg level. */ 1329 1.1 mrg 1330 1.1 mrg static void 1331 1.1 mrg revert (st_parameter_dt *dtp) 1332 1.1 mrg { 1333 1.1 mrg fnode *f, *r; 1334 1.1 mrg format_data *fmt = dtp->u.p.fmt; 1335 1.1 mrg 1336 1.1 mrg dtp->u.p.reversion_flag = 1; 1337 1.1 mrg 1338 1.1 mrg r = NULL; 1339 1.1 mrg 1340 1.1 mrg for (f = fmt->array.array[0].u.child; f; f = f->next) 1341 1.1 mrg if (f->format == FMT_LPAREN) 1342 1.1 mrg r = f; 1343 1.1 mrg 1344 1.1 mrg /* If r is NULL because no node was found, the whole tree will be used */ 1345 1.1 mrg 1346 1.1 mrg fmt->array.array[0].current = r; 1347 1.1 mrg fmt->array.array[0].count = 0; 1348 1.1 mrg } 1349 1.1 mrg 1350 1.1 mrg /* parse_format()-- Parse a format string. */ 1351 1.1 mrg 1352 1.1 mrg void 1353 1.1 mrg parse_format (st_parameter_dt *dtp) 1354 1.1 mrg { 1355 1.1 mrg format_data *fmt; 1356 1.1 mrg bool format_cache_ok, seen_data_desc = false; 1357 1.1 mrg 1358 1.1 mrg /* Don't cache for internal units and set an arbitrary limit on the 1359 1.1 mrg size of format strings we will cache. (Avoids memory issues.) 1360 1.1 mrg Also, the format_hash_table resides in the current_unit, so 1361 1.1 mrg child_dtio procedures would overwrite the parent table */ 1362 1.1 mrg format_cache_ok = !is_internal_unit (dtp) 1363 1.1 mrg && (dtp->u.p.current_unit->child_dtio == 0); 1364 1.1 mrg 1365 1.1 mrg /* Lookup format string to see if it has already been parsed. */ 1366 1.1 mrg if (format_cache_ok) 1367 1.1 mrg { 1368 1.1 mrg dtp->u.p.fmt = find_parsed_format (dtp); 1369 1.1 mrg 1370 1.1 mrg if (dtp->u.p.fmt != NULL) 1371 1.1 mrg { 1372 1.1 mrg dtp->u.p.fmt->reversion_ok = 0; 1373 1.1 mrg dtp->u.p.fmt->saved_token = FMT_NONE; 1374 1.1 mrg dtp->u.p.fmt->saved_format = NULL; 1375 1.1 mrg reset_fnode_counters (dtp); 1376 1.1 mrg return; 1377 1.1 mrg } 1378 1.1 mrg } 1379 1.1 mrg 1380 1.1 mrg /* Not found so proceed as follows. */ 1381 1.1 mrg 1382 1.1 mrg char *fmt_string = fc_strdup_notrim (dtp->format, dtp->format_len); 1383 1.1 mrg dtp->format = fmt_string; 1384 1.1 mrg 1385 1.1 mrg dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data)); 1386 1.1 mrg fmt->format_string = dtp->format; 1387 1.1 mrg fmt->format_string_len = dtp->format_len; 1388 1.1 mrg 1389 1.1 mrg fmt->string = NULL; 1390 1.1 mrg fmt->saved_token = FMT_NONE; 1391 1.1 mrg fmt->error = NULL; 1392 1.1 mrg fmt->value = 0; 1393 1.1 mrg 1394 1.1 mrg /* Initialize variables used during traversal of the tree. */ 1395 1.1 mrg 1396 1.1 mrg fmt->reversion_ok = 0; 1397 1.1 mrg fmt->saved_format = NULL; 1398 1.1 mrg 1399 1.1 mrg /* Initialize the fnode_array. */ 1400 1.1 mrg 1401 1.1 mrg memset (&(fmt->array), 0, sizeof(fmt->array)); 1402 1.1 mrg 1403 1.1 mrg /* Allocate the first format node as the root of the tree. */ 1404 1.1 mrg 1405 1.1 mrg fmt->last = &fmt->array; 1406 1.1 mrg fmt->last->next = NULL; 1407 1.1 mrg fmt->avail = &fmt->array.array[0]; 1408 1.1 mrg 1409 1.1 mrg memset (fmt->avail, 0, sizeof (*fmt->avail)); 1410 1.1 mrg fmt->avail->format = FMT_LPAREN; 1411 1.1 mrg fmt->avail->repeat = 1; 1412 1.1 mrg fmt->avail++; 1413 1.1 mrg 1414 1.1 mrg if (format_lex (fmt) == FMT_LPAREN) 1415 1.1 mrg fmt->array.array[0].u.child = parse_format_list (dtp, &seen_data_desc); 1416 1.1 mrg else 1417 1.1 mrg fmt->error = "Missing initial left parenthesis in format"; 1418 1.1 mrg 1419 1.1 mrg if (format_cache_ok) 1420 1.1 mrg save_parsed_format (dtp); 1421 1.1 mrg else 1422 1.1 mrg dtp->u.p.format_not_saved = 1; 1423 1.1 mrg 1424 1.1 mrg if (fmt->error) 1425 1.1 mrg format_error (dtp, NULL, fmt->error); 1426 1.1 mrg } 1427 1.1 mrg 1428 1.1 mrg 1429 1.1 mrg /* next_format0()-- Get the next format node without worrying about 1430 1.1 mrg reversion. Returns NULL when we hit the end of the list. 1431 1.1 mrg Parenthesis nodes are incremented after the list has been 1432 1.1 mrg exhausted, other nodes are incremented before they are returned. */ 1433 1.1 mrg 1434 1.1 mrg static const fnode * 1435 1.1 mrg next_format0 (fnode *f) 1436 1.1 mrg { 1437 1.1 mrg const fnode *r; 1438 1.1 mrg 1439 1.1 mrg if (f == NULL) 1440 1.1 mrg return NULL; 1441 1.1 mrg 1442 1.1 mrg if (f->format != FMT_LPAREN) 1443 1.1 mrg { 1444 1.1 mrg f->count++; 1445 1.1 mrg if (f->count <= f->repeat) 1446 1.1 mrg return f; 1447 1.1 mrg 1448 1.1 mrg f->count = 0; 1449 1.1 mrg return NULL; 1450 1.1 mrg } 1451 1.1 mrg 1452 1.1 mrg /* Deal with a parenthesis node with unlimited format. */ 1453 1.1 mrg 1454 1.1 mrg if (f->repeat == -2) /* -2 signifies unlimited. */ 1455 1.1 mrg for (;;) 1456 1.1 mrg { 1457 1.1 mrg if (f->current == NULL) 1458 1.1 mrg f->current = f->u.child; 1459 1.1 mrg 1460 1.1 mrg for (; f->current != NULL; f->current = f->current->next) 1461 1.1 mrg { 1462 1.1 mrg r = next_format0 (f->current); 1463 1.1 mrg if (r != NULL) 1464 1.1 mrg return r; 1465 1.1 mrg } 1466 1.1 mrg } 1467 1.1 mrg 1468 1.1 mrg /* Deal with a parenthesis node with specific repeat count. */ 1469 1.1 mrg for (; f->count < f->repeat; f->count++) 1470 1.1 mrg { 1471 1.1 mrg if (f->current == NULL) 1472 1.1 mrg f->current = f->u.child; 1473 1.1 mrg 1474 1.1 mrg for (; f->current != NULL; f->current = f->current->next) 1475 1.1 mrg { 1476 1.1 mrg r = next_format0 (f->current); 1477 1.1 mrg if (r != NULL) 1478 1.1 mrg return r; 1479 1.1 mrg } 1480 1.1 mrg } 1481 1.1 mrg 1482 1.1 mrg f->count = 0; 1483 1.1 mrg return NULL; 1484 1.1 mrg } 1485 1.1 mrg 1486 1.1 mrg 1487 1.1 mrg /* next_format()-- Return the next format node. If the format list 1488 1.1 mrg ends up being exhausted, we do reversion. Reversion is only 1489 1.1 mrg allowed if we've seen a data descriptor since the 1490 1.1 mrg initialization or the last reversion. We return NULL if there 1491 1.1 mrg are no more data descriptors to return (which is an error 1492 1.1 mrg condition). */ 1493 1.1 mrg 1494 1.1 mrg const fnode * 1495 1.1 mrg next_format (st_parameter_dt *dtp) 1496 1.1 mrg { 1497 1.1 mrg format_token t; 1498 1.1 mrg const fnode *f; 1499 1.1 mrg format_data *fmt = dtp->u.p.fmt; 1500 1.1 mrg 1501 1.1 mrg if (fmt->saved_format != NULL) 1502 1.1 mrg { /* Deal with a pushed-back format node */ 1503 1.1 mrg f = fmt->saved_format; 1504 1.1 mrg fmt->saved_format = NULL; 1505 1.1 mrg goto done; 1506 1.1 mrg } 1507 1.1 mrg 1508 1.1 mrg f = next_format0 (&fmt->array.array[0]); 1509 1.1 mrg if (f == NULL) 1510 1.1 mrg { 1511 1.1 mrg if (!fmt->reversion_ok) 1512 1.1 mrg return NULL; 1513 1.1 mrg 1514 1.1 mrg fmt->reversion_ok = 0; 1515 1.1 mrg revert (dtp); 1516 1.1 mrg 1517 1.1 mrg f = next_format0 (&fmt->array.array[0]); 1518 1.1 mrg if (f == NULL) 1519 1.1 mrg { 1520 1.1 mrg format_error (dtp, NULL, reversion_error); 1521 1.1 mrg return NULL; 1522 1.1 mrg } 1523 1.1 mrg 1524 1.1 mrg /* Push the first reverted token and return a colon node in case 1525 1.1 mrg there are no more data items. */ 1526 1.1 mrg 1527 1.1 mrg fmt->saved_format = f; 1528 1.1 mrg return &colon_node; 1529 1.1 mrg } 1530 1.1 mrg 1531 1.1 mrg /* If this is a data edit descriptor, then reversion has become OK. */ 1532 1.1 mrg done: 1533 1.1 mrg t = f->format; 1534 1.1 mrg 1535 1.1 mrg if (!fmt->reversion_ok && 1536 1.1 mrg (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F || 1537 1.1 mrg t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L || 1538 1.1 mrg t == FMT_A || t == FMT_D || t == FMT_DT)) 1539 1.1 mrg fmt->reversion_ok = 1; 1540 1.1 mrg return f; 1541 1.1 mrg } 1542 1.1 mrg 1543 1.1 mrg 1544 1.1 mrg /* unget_format()-- Push the given format back so that it will be 1545 1.1 mrg returned on the next call to next_format() without affecting 1546 1.1 mrg counts. This is necessary when we've encountered a data 1547 1.1 mrg descriptor, but don't know what the data item is yet. The format 1548 1.1 mrg node is pushed back, and we return control to the main program, 1549 1.1 mrg which calls the library back with the data item (or not). */ 1550 1.1 mrg 1551 1.1 mrg void 1552 1.1 mrg unget_format (st_parameter_dt *dtp, const fnode *f) 1553 1.1 mrg { 1554 1.1 mrg dtp->u.p.fmt->saved_format = f; 1555 1.1 mrg } 1556 1.1 mrg 1557