00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef _OLD_ERROR_NUMBERS
00039 #pragma ident "@(#) libf/fio/fmtparse.c 92.3 06/18/99 19:52:04"
00040 #endif
00041 #include "lio.h"
00042 #include <ctype.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <cray/format.h>
00046 #include <cray/nassert.h>
00047 #include <cray/portdefs.h>
00048
00049 typedef struct {
00050 char fmt_ch;
00051 char *fmt_ptr;
00052 short caller;
00053 short depth;
00054 short maxdepth;
00055 short fatal_err;
00056 long desc_col;
00057 long fmt_pos;
00058 long fmt_len;
00059 fmt_type *parsed;
00060 fmt_type *pptr;
00061 fmt_type *revert;
00062 msg_type *stat;
00063 _Error_function *iss_msg;
00064 } parse_block;
00065
00066
00067
00068 static void
00069 fmterr ( parse_block *pfmt,
00070 short msg_num,
00071 short code,
00072 long column);
00073
00074 static short
00075 process_paren_group ( parse_block *pfmt,
00076 fmt_type *ploc);
00077
00078
00079
00080 static int64 non_repeatable[2] = {
00081 0x00000000297EFFE0,
00082 0x0000180800001800
00083 };
00084
00085
00086
00087
00088
00089
00090
00091
00092 #define GET(P) { \
00093 do { \
00094 if (++P->fmt_pos > P->fmt_len) { \
00095 P->fmt_ch = '\0'; \
00096 P->fmt_pos--; \
00097 break; \
00098 } \
00099 P->fmt_ch = *(++P->fmt_ptr); \
00100 } while (P->fmt_ch == ' ' || P->fmt_ch == '\t'); \
00101 }
00102
00103 #define GETNUM(P, M) { \
00104 do { \
00105 M = (M + M + (M << 3)) + ((int64) P->fmt_ch - ZERO);\
00106 GET(P); \
00107 } while (IS_DIGIT(P->fmt_ch)); \
00108 }
00109
00110
00111
00112 #ifndef E_WITH_D_NON_ANSI
00113 #define E_WITH_D_NON_ANSI DW_IS_NON_ANSI
00114 #endif
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 fmt_type *
00152 _fmt_parse(
00153 _Error_function **msg_rtn,
00154 char *format_str,
00155 long routine_caller,
00156 long *fmt_str_len,
00157 msg_type *lib_err_msg
00158 )
00159 {
00160 register short length;
00161 parse_block *pfmt, p;
00162
00163
00164
00165 assert (format_str != NULL);
00166 assert (routine_caller >= 0 && routine_caller <= MAX_CALL_FLAG);
00167 assert (fmt_str_len != NULL);
00168 assert (*fmt_str_len > 0);
00169 assert (routine_caller == LIB_CALL ? lib_err_msg != NULL : 1);
00170 assert (routine_caller != LIB_CALL ? msg_rtn != NULL : 1);
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 pfmt = &p;
00182
00183 pfmt->fmt_pos = 0;
00184 pfmt->depth = 0;
00185 pfmt->maxdepth = 0;
00186 pfmt->fatal_err = FALSE;
00187 pfmt->iss_msg = (msg_rtn == NULL ? NULL : *msg_rtn);
00188 pfmt->stat = lib_err_msg;
00189 pfmt->fmt_ptr = format_str - 1;
00190 pfmt->fmt_len = *fmt_str_len;
00191 pfmt->caller = routine_caller;
00192
00193 GET(pfmt);
00194
00195 pfmt->desc_col = pfmt->fmt_pos;
00196
00197 if (pfmt->fmt_ch == '(') {
00198 GET(pfmt);
00199 }
00200 else {
00201 fmterr(pfmt, EXPECTING_LEFT_PAREN, FALL, 0);
00202
00203
00204
00205 if (pfmt->caller == LIB_CALL)
00206 return( (fmt_type *) NULL);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 pfmt->parsed = (fmt_type *) calloc(pfmt->fmt_len + 2,
00220 sizeof(fmt_type));
00221
00222 if (pfmt->parsed == NULL) {
00223
00224 fmterr(pfmt, UNABLE_TO_MALLOC_MEMORY, FALL, 0);
00225
00226
00227
00228 return( (fmt_type *) NULL);
00229 }
00230
00231 pfmt->pptr = pfmt->parsed + 1;
00232 pfmt->revert = pfmt->pptr;
00233
00234
00235
00236 (void) process_paren_group(pfmt, pfmt->pptr);
00237
00238 if (pfmt->fatal_err) {
00239 free( (char *) pfmt->parsed);
00240 pfmt->parsed = NULL;
00241 length = 0;
00242 }
00243 else {
00244 length = pfmt->pptr - pfmt->parsed;
00245 pfmt->parsed->offset = PARSER_LEVEL;
00246 pfmt->parsed->rep_count = pfmt->maxdepth + 1;
00247
00248 if (pfmt->fmt_ch != '\0')
00249 fmterr(pfmt, TRAILING_CHARS, FALL, 0);
00250
00251 if (pfmt->caller == LIB_CALL)
00252 pfmt->parsed = (fmt_type *) realloc (
00253 (char *) pfmt->parsed,
00254 length * FMT_ENTRY_BYTE_SIZE );
00255 }
00256
00257 *fmt_str_len = length * FMT_ENTRY_WORD_SIZE;
00258
00259 return(pfmt->parsed);
00260
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 static void
00291 fmterr(
00292 parse_block *pfmt,
00293 short msg_num,
00294 short code,
00295 long column
00296 )
00297 {
00298 register short callflg;
00299
00300 callflg = 0;
00301
00302 if (msg_num >= FIRST_FATAL_MESSAGE)
00303 pfmt->fatal_err = TRUE;
00304
00305 if (column == 0)
00306 column = pfmt->fmt_pos;
00307
00308 switch (pfmt->caller) {
00309
00310 case LIB_CALL:
00311
00312
00313
00314 if (msg_num >= FIRST_FATAL_MESSAGE) {
00315 pfmt->stat->msg_number = msg_num;
00316 pfmt->stat->msg_column = column;
00317 pfmt->stat->desc_column = pfmt->desc_col;
00318 }
00319 break;
00320
00321 case COMPILER_CALL_NO_ANSI:
00322
00323
00324
00325 callflg = (msg_num < FIRST_NON_ANSI_MESSAGE ||
00326 msg_num >= FIRST_FATAL_MESSAGE);
00327 break;
00328
00329 case COMPILER_CALL_ANSI:
00330
00331
00332
00333 callflg = 1;
00334 break;
00335
00336 case COMPILER_CALL_ANSI_77:
00337
00338
00339
00340 callflg = (code & F77);
00341 break;
00342
00343 case COMPILER_CALL_ANSI_90:
00344
00345
00346
00347 callflg = (code & F90);
00348 break;
00349
00350 case COMPILER_CALL_ANSI_95:
00351
00352
00353
00354 callflg = (code & F95);
00355 break;
00356 }
00357
00358 if (callflg != 0)
00359 (*pfmt->iss_msg) (msg_num, column, pfmt->desc_col);
00360
00361 return;
00362
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 static void
00386 recover(
00387 parse_block *pfmt
00388 )
00389 {
00390 register short found_char;
00391
00392 found_char = FALSE;
00393
00394 if (pfmt->caller != LIB_CALL)
00395 do {
00396 switch (pfmt->fmt_ch) {
00397 case ',':
00398 case ')':
00399 case '(':
00400 case '"':
00401 case '*':
00402 case '\'':
00403 case '\0':
00404 found_char = TRUE;
00405 break;
00406
00407 default:
00408 GET(pfmt);
00409 break;
00410 }
00411 } while (!found_char);
00412
00413 return;
00414
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 static short
00437 nonzero_integer(
00438 parse_block *pfmt,
00439 long *size
00440 )
00441 {
00442 register short return_val;
00443 register int64 value;
00444 register long col;
00445
00446 if (IS_DIGIT(pfmt->fmt_ch)) {
00447
00448 col = pfmt->fmt_pos;
00449 return_val = TRUE;
00450 value = *size;
00451
00452 GETNUM(pfmt, value);
00453
00454 if (value == 0) {
00455 fmterr(pfmt, FIELD_WIDTH_ZERO, FALL, col);
00456 value = 1;
00457 }
00458 else
00459 if (value > MAX_FIELD_WIDTH) {
00460 fmterr(pfmt, FIELD_TOO_LARGE, FALL, col);
00461 value = MAX_FIELD_WIDTH;
00462 }
00463 }
00464 else {
00465 fmterr(pfmt, EXPECTING_INTEGER, FALL, 0);
00466 return_val = FALSE;
00467 value = 1;
00468 }
00469
00470 *size = value;
00471
00472 return(return_val);
00473
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 static void
00502 process_arl(
00503 parse_block *pfmt,
00504 unsigned short op_code
00505 )
00506 {
00507 register long col;
00508 register int64 size;
00509
00510 size = 0;
00511
00512 GET(pfmt);
00513
00514 if (IS_DIGIT(pfmt->fmt_ch)) {
00515
00516 col = pfmt->fmt_pos;
00517
00518 GETNUM(pfmt, size);
00519
00520 if (size == 0) {
00521 #ifdef _OLD_ERROR_NUMBERS
00522 fmterr(pfmt, FIELD_WIDTH_ZERO, FALL, col);
00523 size = 1;
00524 #else
00525 fmterr(pfmt, ZERO_WIDTH_NON_ANSI, FALL, col);
00526 #endif
00527 }
00528 else
00529 if (size > MAX_FIELD_WIDTH) {
00530 fmterr(pfmt, FIELD_TOO_LARGE, FALL, col);
00531 size = MAX_FIELD_WIDTH;
00532 }
00533 }
00534 else
00535 if (op_code != A_ED) {
00536 #ifdef _OLD_ERROR_NUMBERS
00537 fmterr(pfmt, EXPECTING_INTEGER, FALL, 0);
00538 recover(pfmt);
00539 #else
00540 fmterr(pfmt, MISSING_WIDTH_NON_ANSI, FALL, pfmt->fmt_pos);
00541 #endif
00542 }
00543
00544 pfmt->pptr->op_code = op_code;
00545 pfmt->pptr->field_width = size;
00546 pfmt->pptr = pfmt->pptr + 1;
00547
00548 return;
00549
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 static void
00589 process_defg(
00590 parse_block *pfmt,
00591 unsigned short op_code
00592 )
00593 {
00594 register short dset;
00595 register long col;
00596 register int64 esize;
00597 register int64 dsize;
00598 register int64 wsize;
00599
00600 dset = 1;
00601 dsize = 0;
00602 esize = 0;
00603 wsize = 0;
00604
00605 GET(pfmt);
00606
00607 if (IS_DIGIT(pfmt->fmt_ch)) {
00608
00609 col = pfmt->fmt_pos;
00610
00611 GETNUM(pfmt, wsize);
00612
00613 if (wsize == 0) {
00614 #ifdef _OLD_ERROR_NUMBERS
00615 fmterr(pfmt, FIELD_WIDTH_ZERO, FALL, col);
00616 wsize = 1;
00617 #else
00618 register short code;
00619
00620 code = (op_code == F_ED) ? (F77 | F90) : FALL;
00621
00622 fmterr(pfmt, ZERO_WIDTH_NON_ANSI, code, col);
00623 #endif
00624 }
00625 else
00626 if (wsize > MAX_FIELD_WIDTH) {
00627 fmterr(pfmt, FIELD_TOO_LARGE, FALL, col);
00628 wsize = MAX_FIELD_WIDTH;
00629 }
00630
00631 if (pfmt->fmt_ch == '.') {
00632
00633 GET(pfmt);
00634
00635 if (IS_DIGIT(pfmt->fmt_ch)) {
00636
00637 col = pfmt->fmt_pos;
00638 dset = 0;
00639 dsize = 0;
00640
00641 GETNUM(pfmt, dsize);
00642
00643 if (dsize > MAX_DECIMAL_FIELD) {
00644 fmterr(pfmt, FIELD_TOO_LARGE, FALL, col);
00645 dsize = MAX_DECIMAL_FIELD;
00646 }
00647
00648 if (toupper(pfmt->fmt_ch) == 'E' &&
00649 op_code != F_ED) {
00650 register long col_e;
00651
00652 col_e = pfmt->fmt_pos;
00653
00654 GET(pfmt);
00655
00656 if (IS_DIGIT(pfmt->fmt_ch)) {
00657
00658 col = pfmt->fmt_pos;
00659
00660 GETNUM(pfmt, esize);
00661
00662 if (esize == 0) {
00663 fmterr(pfmt,
00664 FIELD_WIDTH_ZERO,
00665 FALL,
00666 col);
00667 esize = 1;
00668 }
00669 else
00670 if (esize > MAX_EXPONENT) {
00671 fmterr(pfmt,
00672 FIELD_TOO_LARGE,
00673 FALL, col);
00674 esize = MAX_EXPONENT;
00675 }
00676
00677 if (op_code == D_ED)
00678 fmterr(pfmt, E_WITH_D_NON_ANSI,
00679 FALL, col_e);
00680 }
00681 else {
00682 fmterr(pfmt, EXPECTING_INTEGER,
00683 FALL, 0);
00684 recover(pfmt);
00685 }
00686 }
00687 }
00688 else {
00689 fmterr(pfmt, EXPECTING_INTEGER, FALL, 0);
00690 recover(pfmt);
00691 }
00692 }
00693 else {
00694 fmterr(pfmt, EXPECTING_PERIOD, FALL, 0);
00695 recover(pfmt);
00696 }
00697 }
00698 else {
00699 #ifdef _OLD_ERROR_NUMBERS
00700 fmterr(pfmt, EXPECTING_INTEGER, FALL, 0);
00701 recover(pfmt);
00702 #else
00703 fmterr(pfmt, MISSING_WIDTH_NON_ANSI, FALL, pfmt->fmt_pos);
00704 #endif
00705 }
00706
00707 pfmt->pptr->op_code = op_code;
00708 pfmt->pptr->exponent = esize;
00709 pfmt->pptr->field_width = wsize;
00710 pfmt->pptr->digits_field = dsize;
00711 pfmt->pptr->default_digits = dset;
00712 pfmt->pptr = pfmt->pptr + 1;
00713
00714 return;
00715
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749 static void
00750 process_bioz(
00751 parse_block *pfmt,
00752 unsigned short op_code
00753 )
00754 {
00755 register short dset;
00756 register long col;
00757 register int64 dsize;
00758 register int64 wsize;
00759
00760 dset = 1;
00761 dsize = 1;
00762 wsize = 0;
00763
00764 GET(pfmt);
00765
00766 if (IS_DIGIT(pfmt->fmt_ch)) {
00767
00768 col = pfmt->fmt_pos;
00769
00770 GETNUM(pfmt, wsize);
00771
00772 if (wsize == 0) {
00773 #ifdef _OLD_ERROR_NUMBERS
00774 fmterr(pfmt, FIELD_WIDTH_ZERO, FALL, col);
00775 wsize = 1;
00776 #else
00777 fmterr(pfmt, ZERO_WIDTH_NON_ANSI, (F77 | F90), col);
00778 #endif
00779 } else
00780 if (wsize > MAX_FIELD_WIDTH) {
00781 fmterr(pfmt, FIELD_TOO_LARGE, FALL, col);
00782 wsize = MAX_FIELD_WIDTH;
00783 }
00784
00785 if (pfmt->fmt_ch == '.') {
00786
00787 GET(pfmt);
00788
00789 if (IS_DIGIT(pfmt->fmt_ch)) {
00790
00791 col = pfmt->fmt_pos;
00792 dsize = 0;
00793 dset = 0;
00794
00795 GETNUM(pfmt, dsize);
00796
00797 if (dsize > MAX_DECIMAL_FIELD) {
00798 fmterr(pfmt, FIELD_TOO_LARGE, FALL, col);
00799 dsize = MAX_DECIMAL_FIELD;
00800 }
00801 }
00802 else {
00803 fmterr(pfmt, EXPECTING_INTEGER, FALL, 0);
00804 recover(pfmt);
00805 }
00806 }
00807 }
00808 else {
00809 #ifdef _OLD_ERROR_NUMBERS
00810 fmterr(pfmt, EXPECTING_INTEGER, FALL, 0);
00811 recover(pfmt);
00812 #else
00813 fmterr(pfmt, MISSING_WIDTH_NON_ANSI, FALL, pfmt->fmt_pos);
00814 #endif
00815 }
00816
00817 pfmt->pptr->op_code = op_code;
00818 pfmt->pptr->field_width = wsize;
00819 pfmt->pptr->digits_field = dsize;
00820 pfmt->pptr->default_digits = dset;
00821 pfmt->pptr = pfmt->pptr + 1;
00822
00823 return;
00824
00825 }
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843 static void
00844 process_t(
00845 parse_block *pfmt
00846 )
00847 {
00848 long size;
00849 register char ch;
00850
00851 size = 0;
00852
00853 GET(pfmt);
00854
00855 ch = toupper(pfmt->fmt_ch);
00856
00857 if (ch == 'R') {
00858
00859 GET(pfmt);
00860
00861 if (nonzero_integer(pfmt, &size)) {
00862 pfmt->pptr->op_code = TR_ED;
00863 pfmt->pptr->field_width = size;
00864 pfmt->pptr = pfmt->pptr + 1;
00865 }
00866 }
00867 else
00868 if (ch == 'L') {
00869
00870 GET(pfmt);
00871
00872 if (nonzero_integer(pfmt, &size)) {
00873 pfmt->pptr->op_code = TL_ED;
00874 pfmt->pptr->field_width = size;
00875 pfmt->pptr = pfmt->pptr + 1;
00876 }
00877 }
00878 else
00879 if (nonzero_integer(pfmt, &size)) {
00880 pfmt->pptr->op_code = T_ED;
00881 pfmt->pptr->field_width = size;
00882 pfmt->pptr->rep_count = 1;
00883 pfmt->pptr = pfmt->pptr + 1;
00884 }
00885
00886 return;
00887
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 static void
00912 process_p(
00913 parse_block *pfmt,
00914 long scale_factor
00915 )
00916 {
00917 pfmt->pptr->op_code = P_ED;
00918 pfmt->pptr->offset = pfmt->fmt_pos;
00919 pfmt->pptr->rep_count = scale_factor;
00920 pfmt->pptr = pfmt->pptr + 1;
00921
00922 GET(pfmt);
00923
00924 switch (pfmt->fmt_ch) {
00925 case ',':
00926 case 'D':
00927 case 'E':
00928 case 'F':
00929 case 'G':
00930 case 'd':
00931 case 'e':
00932 case 'f':
00933 case 'g':
00934 case ')':
00935 case ':':
00936 case '/':
00937 case '\0':
00938 break;
00939
00940 default:
00941 fmterr(pfmt, ANSI_COMMA_REQ, FALL, 0);
00942 break;
00943 }
00944
00945 return;
00946
00947 }
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 static void
00966 process_char_string(
00967 parse_block *pfmt
00968 )
00969 {
00970 char *str_ptr;
00971 register long size;
00972
00973 size = 0;
00974 str_ptr = (char *) (pfmt->pptr + 1);
00975
00976 for ( ; ; ) {
00977
00978 if (++pfmt->fmt_pos > pfmt->fmt_len) {
00979 pfmt->fmt_pos = pfmt->fmt_pos - 1;
00980 pfmt->fmt_ch = '\0';
00981 fmterr(pfmt, NONTERMINATED_LITERAL, FALL, 0);
00982 break;
00983 }
00984
00985 if (*(++pfmt->fmt_ptr) == pfmt->fmt_ch) {
00986
00987 if (pfmt->fmt_pos == pfmt->fmt_len) {
00988 pfmt->fmt_ch = '\0';
00989 break;
00990 }
00991
00992 if (*(pfmt->fmt_ptr+1) != pfmt->fmt_ch) {
00993 GET(pfmt);
00994 break;
00995 }
00996 else {
00997 pfmt->fmt_pos = pfmt->fmt_pos + 1;
00998 pfmt->fmt_ptr = pfmt->fmt_ptr + 1;
00999 }
01000 }
01001
01002 *str_ptr++ = *pfmt->fmt_ptr;
01003 size = size + 1;
01004 }
01005
01006 pfmt->pptr->op_code = STRING_ED;
01007 pfmt->pptr->field_width = size;
01008 pfmt->pptr = pfmt->pptr +
01009 ((size + FMT_ENTRY_BYTE_SIZE - 1) / FMT_ENTRY_BYTE_SIZE) + 1;
01010
01011 return;
01012
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 static short
01035 process_minus(
01036 parse_block *pfmt
01037 )
01038 {
01039 register short return_val;
01040 register long col_m;
01041 register long col_n;
01042
01043 return_val = TRUE;
01044 col_m = pfmt->fmt_pos;
01045
01046 GET(pfmt);
01047
01048 col_n = pfmt->fmt_pos;
01049
01050 if (IS_DIGIT(pfmt->fmt_ch)) {
01051 register int64 size;
01052 register char ch;
01053
01054 size = 0;
01055
01056 GETNUM(pfmt, size);
01057
01058 ch = toupper(pfmt->fmt_ch);
01059
01060 if (ch == 'P') {
01061
01062 pfmt->desc_col = pfmt->fmt_pos;
01063 return_val = FALSE;
01064
01065 if (size > MAX_REP_COUNT) {
01066 fmterr(pfmt, FIELD_TOO_LARGE, FALL, col_n);
01067 size = MAX_REP_COUNT;
01068 }
01069
01070 process_p(pfmt, (long) -size);
01071 }
01072 else
01073 if (ch == 'X') {
01074
01075 pfmt->desc_col = pfmt->fmt_pos;
01076
01077 fmterr(pfmt, MINUS_X_NON_ANSI, FALL, col_m);
01078
01079 if (size == 0) {
01080 fmterr(pfmt, FIELD_WIDTH_ZERO, FALL,
01081 col_n);
01082 size = 1;
01083 }
01084 else
01085 if (size > MAX_FIELD_WIDTH) {
01086 fmterr(pfmt, FIELD_TOO_LARGE,
01087 FALL, col_n);
01088 size = MAX_FIELD_WIDTH;
01089 }
01090
01091 pfmt->pptr->op_code = TL_ED;
01092 pfmt->pptr->offset = pfmt->fmt_pos;
01093 pfmt->pptr->field_width = size;
01094 pfmt->pptr = pfmt->pptr + 1;
01095
01096 GET(pfmt);
01097 }
01098 else {
01099 fmterr(pfmt, EXPECTING_P_OR_X, FALL, col_n);
01100 recover(pfmt);
01101 }
01102 }
01103 else {
01104 fmterr(pfmt, EXPECTING_INTEGER, FALL, col_n);
01105 recover(pfmt);
01106 }
01107
01108 return(return_val);
01109
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 static short
01155 process_paren_group(
01156 parse_block *pfmt,
01157 fmt_type *ploc
01158 )
01159 {
01160 register short comma_req_flag;
01161 register short data_ed;
01162 register short found_rep_count;
01163 register short outer_paren;
01164 register short num_eds;
01165 register short op_code;
01166 register short temp;
01167 register long num_start;
01168 register long old_pos;
01169 register int64 repeat_count;
01170 register char ch;
01171 char *old_ptr;
01172
01173 num_eds = 0;
01174 data_ed = FALSE;
01175 outer_paren = (pfmt->pptr == ploc);
01176
01177 do {
01178
01179 num_start = pfmt->fmt_pos;
01180 pfmt->desc_col = pfmt->fmt_pos;
01181 comma_req_flag = TRUE;
01182 num_eds = num_eds + 1;
01183
01184 if (IS_DIGIT(pfmt->fmt_ch)) {
01185 register short j, k;
01186
01187 repeat_count = 0;
01188 found_rep_count = TRUE;
01189
01190 GETNUM(pfmt, repeat_count);
01191
01192 pfmt->desc_col = pfmt->fmt_pos;
01193
01194
01195
01196 j = (((short) pfmt->fmt_ch) >> 6) & 1;
01197 k = ((short) pfmt->fmt_ch) & 077;
01198
01199 if ((non_repeatable[j] << k) < 0)
01200 fmterr(pfmt, INVALID_REP_COUNT, FALL, num_start);
01201 else {
01202
01203 ch = toupper(pfmt->fmt_ch);
01204
01205 if (repeat_count == 0 && ch != 'P') {
01206
01207 if (ch == 'H')
01208 fmterr(pfmt,
01209 ZERO_OR_NO_HOLLERITH_CNT,
01210 FALL, num_start);
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 else
01222 if (ch != 'B')
01223 fmterr(pfmt,
01224 ZERO_REP_COUNT,
01225 FALL, num_start);
01226 }
01227
01228
01229
01230
01231
01232
01233
01234
01235 if (repeat_count > MAX_REP_COUNT)
01236 if (ch != 'X' && ch != 'H' && ch != '/') {
01237 fmterr(pfmt, FIELD_TOO_LARGE,
01238 FALL, num_start);
01239 repeat_count = MAX_REP_COUNT;
01240 }
01241 }
01242 }
01243 else {
01244 repeat_count = 1;
01245 found_rep_count = FALSE;
01246 }
01247
01248 pfmt->pptr->offset = pfmt->fmt_pos;
01249 pfmt->pptr->rep_count = repeat_count;
01250
01251 switch (toupper(pfmt->fmt_ch)) {
01252
01253 case '(':
01254
01255 num_eds = num_eds - 1;
01256 pfmt->pptr->op_code = REPEAT_OP;
01257 pfmt->pptr = pfmt->pptr + 1;
01258 pfmt->depth = pfmt->depth + 1;
01259
01260
01261
01262
01263
01264
01265 if (pfmt->depth == 1)
01266 data_ed = FALSE;
01267
01268 GET(pfmt);
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280 temp = process_paren_group(pfmt,
01281 pfmt->pptr - 1);
01282
01283
01284
01285
01286
01287
01288 if (temp < 0) {
01289 data_ed = TRUE;
01290 temp = -temp;
01291 }
01292
01293 num_eds = num_eds + temp;
01294 break;
01295
01296 case 'A':
01297 data_ed = TRUE;
01298 process_arl(pfmt, A_ED);
01299 break;
01300
01301 case 'D':
01302 data_ed = TRUE;
01303 process_defg(pfmt, D_ED);
01304 break;
01305
01306 case 'F':
01307 data_ed = TRUE;
01308 process_defg(pfmt, F_ED);
01309 break;
01310
01311 case 'I':
01312 data_ed = TRUE;
01313 process_bioz(pfmt, I_ED);
01314 break;
01315
01316 case 'X':
01317
01318 if (!found_rep_count)
01319 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR,
01320 FALL, 0);
01321 else
01322 if (repeat_count > MAX_FIELD_WIDTH) {
01323 fmterr(pfmt, FIELD_TOO_LARGE,
01324 FALL, num_start);
01325 repeat_count = MAX_FIELD_WIDTH;
01326 }
01327
01328 pfmt->pptr->op_code = TR_ED;
01329 pfmt->pptr->field_width = repeat_count;
01330 pfmt->pptr->rep_count = 1;
01331 pfmt->pptr = pfmt->pptr + 1;
01332
01333 GET(pfmt);
01334 break;
01335
01336 case 'H':
01337 fmterr(pfmt, H_IS_OBSOLETE_IN_F90, F90, 0);
01338 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR, F95, 0);
01339
01340 if (found_rep_count) {
01341 register int left;
01342
01343 if (repeat_count > MAX_FIELD_WIDTH) {
01344 fmterr(pfmt, FIELD_TOO_LARGE,
01345 FALL, num_start);
01346 repeat_count = MAX_FIELD_WIDTH;
01347 }
01348
01349 left = pfmt->fmt_len - pfmt->fmt_pos;
01350
01351 if (repeat_count > left)
01352 repeat_count = (int64) left;
01353
01354 pfmt->pptr->op_code = STRING_ED;
01355 pfmt->pptr->field_width = repeat_count;
01356 pfmt->pptr->rep_count = 1;
01357 pfmt->pptr = pfmt->pptr + 1;
01358
01359 (void) strncpy((char *) pfmt->pptr,
01360 pfmt->fmt_ptr + 1, (int) repeat_count);
01361
01362 pfmt->pptr = pfmt->pptr + 1 +
01363 ((repeat_count - 1) / FMT_ENTRY_BYTE_SIZE);
01364 pfmt->fmt_ptr = pfmt->fmt_ptr + repeat_count;
01365 pfmt->fmt_pos = pfmt->fmt_pos + repeat_count;
01366
01367 GET(pfmt);
01368
01369 if (pfmt->fmt_ch == '\0')
01370 fmterr(pfmt, NONTERMINATED_LITERAL,
01371 FALL, 0);
01372 }
01373 else {
01374 fmterr(pfmt, ZERO_OR_NO_HOLLERITH_CNT,
01375 FALL, num_start);
01376 recover(pfmt);
01377 }
01378 break;
01379
01380 case '*':
01381 case '"':
01382 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR, FALL, 0);
01383
01384
01385
01386 case '\'':
01387 process_char_string(pfmt);
01388 break;
01389
01390 case 'G':
01391 data_ed = TRUE;
01392 process_defg(pfmt, G_ED);
01393 break;
01394
01395 case 'E':
01396
01397 data_ed = TRUE;
01398 op_code = E_ED;
01399 old_pos = pfmt->fmt_pos;
01400 old_ptr = pfmt->fmt_ptr;
01401
01402 GET(pfmt);
01403
01404 ch = toupper(pfmt->fmt_ch);
01405
01406 if (ch == 'N' || ch == 'S') {
01407
01408 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR,
01409 F77, old_pos);
01410
01411 op_code = (ch == 'N') ? EN_ED : ES_ED;
01412
01413 }
01414 else {
01415 pfmt->fmt_pos = old_pos;
01416 pfmt->fmt_ptr = old_ptr;
01417 }
01418
01419 process_defg(pfmt, op_code);
01420 break;
01421
01422 case 'B':
01423
01424
01425 old_pos = pfmt->fmt_pos;
01426 old_ptr = pfmt->fmt_ptr;
01427
01428 GET(pfmt);
01429
01430 ch = toupper(pfmt->fmt_ch);
01431
01432 if (ch == 'N' || ch == 'Z') {
01433
01434 if (found_rep_count)
01435 fmterr(pfmt, INVALID_REP_COUNT,
01436 FALL, num_start);
01437
01438 pfmt->pptr->op_code = (ch == 'N') ?
01439 BN_ED : BZ_ED;
01440 pfmt->pptr = pfmt->pptr + 1;
01441
01442 GET(pfmt);
01443 }
01444 else {
01445 if (repeat_count == 0)
01446 fmterr(pfmt, ZERO_REP_COUNT,
01447 FALL, num_start);
01448
01449
01450
01451 pfmt->fmt_pos = old_pos;
01452 pfmt->fmt_ptr = old_ptr;
01453
01454 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR,
01455 F77, 0);
01456
01457 data_ed = TRUE;
01458 process_bioz(pfmt, B_ED);
01459 break;
01460 }
01461 break;
01462
01463 case 'R':
01464 data_ed = TRUE;
01465 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR, FALL, 0);
01466 process_arl(pfmt, R_ED);
01467 break;
01468
01469 case 'L':
01470 data_ed = TRUE;
01471 process_arl(pfmt, L_ED);
01472 break;
01473
01474 case 'P':
01475 if (!found_rep_count)
01476 fmterr(pfmt, EXPECTING_INTEGER, FALL,
01477 0);
01478
01479 process_p(pfmt, (long) repeat_count);
01480 comma_req_flag = FALSE;
01481 break;
01482
01483 case 'O':
01484 data_ed = TRUE;
01485 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR, F77, 0);
01486 process_bioz(pfmt, O_ED);
01487 break;
01488
01489 case 'Z':
01490 data_ed = TRUE;
01491 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR, F77, 0);
01492 process_bioz(pfmt, Z_ED);
01493 break;
01494
01495 case '/':
01496 if (found_rep_count) {
01497
01498 if (repeat_count > MAX_FIELD_WIDTH) {
01499 fmterr(pfmt, FIELD_TOO_LARGE,
01500 FALL, num_start);
01501 repeat_count = MAX_FIELD_WIDTH;
01502 }
01503
01504 fmterr(pfmt, REP_SLASH_NON_ANSI,
01505 F77, num_start);
01506 }
01507
01508 pfmt->pptr->op_code = SLASH_ED;
01509 pfmt->pptr->field_width = repeat_count;
01510 pfmt->pptr->rep_count = 1;
01511 pfmt->pptr = pfmt->pptr + 1;
01512
01513 comma_req_flag = FALSE;
01514
01515 GET(pfmt);
01516 break;
01517
01518 case '+':
01519 GET(pfmt);
01520
01521 if (IS_DIGIT(pfmt->fmt_ch)) {
01522 register int64 size;
01523
01524 size = 0;
01525 num_start = pfmt->fmt_pos;
01526
01527 GETNUM(pfmt, size);
01528
01529 if (toupper(pfmt->fmt_ch) == 'P') {
01530
01531 pfmt->desc_col = pfmt->fmt_pos;
01532
01533 if (size > MAX_REP_COUNT) {
01534 fmterr(pfmt, FIELD_TOO_LARGE,
01535 FALL, num_start);
01536 size = MAX_REP_COUNT;
01537 }
01538
01539 process_p(pfmt, (long) size);
01540
01541 comma_req_flag = FALSE;
01542 break;
01543 }
01544
01545 fmterr(pfmt, EXPECTING_P_OR_X, FALL, 0);
01546 }
01547 else
01548 fmterr(pfmt, EXPECTING_INTEGER, FALL, 0);
01549
01550 recover(pfmt);
01551 break;
01552
01553 case '-':
01554
01555 comma_req_flag = process_minus(pfmt);
01556 break;
01557
01558 case ':':
01559 pfmt->pptr->op_code = COLON_ED;
01560 pfmt->pptr = pfmt->pptr + 1;
01561
01562 GET(pfmt);
01563
01564 comma_req_flag = FALSE;
01565 break;
01566
01567 case 'Q':
01568 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR, FALL, 0);
01569
01570 pfmt->pptr->op_code = Q_ED;
01571 pfmt->pptr = pfmt->pptr + 1;
01572
01573 GET(pfmt);
01574
01575 comma_req_flag = FALSE;
01576 data_ed = TRUE;
01577 break;
01578
01579 case '$':
01580 case '\\':
01581 fmterr(pfmt, NON_ANSI_EDIT_DESCRIPTOR, FALL, 0);
01582
01583 pfmt->pptr->op_code = DOLLAR_ED;
01584 pfmt->pptr = pfmt->pptr + 1;
01585
01586 GET(pfmt);
01587
01588 comma_req_flag = FALSE;
01589 break;
01590
01591 case 'S':
01592 GET(pfmt);
01593
01594 ch = toupper(pfmt->fmt_ch);
01595
01596 if (ch == 'S' || ch == 'P') {
01597 op_code = (ch == 'S') ? SS_ED : SP_ED;
01598 GET(pfmt);
01599 }
01600 else
01601 op_code = S_ED;
01602
01603 pfmt->pptr->op_code = op_code;
01604 pfmt->pptr = pfmt->pptr + 1;
01605 break;
01606
01607 case 'T':
01608 process_t(pfmt);
01609 break;
01610
01611 #ifndef _OLD_ERROR_NUMBERS
01612 case ',':
01613 fmterr(pfmt, NON_ANSI_NULL_DESCRIPTOR, FALL, 0);
01614 GET(pfmt);
01615
01616 comma_req_flag = FALSE;
01617 break;
01618 #endif
01619
01620 case ')':
01621 num_eds = num_eds - 1;
01622
01623 if (num_eds == 0 && !outer_paren)
01624 fmterr(pfmt, ANSI_EMPTY_PAREN_MSG,
01625 FALL, 0);
01626 break;
01627
01628 case '\0':
01629 fmterr(pfmt, EXPECTING_RIGHT_PAREN, FALL, 0);
01630 return(0);
01631
01632 default:
01633 fmterr(pfmt, UNKNOWN_EDIT_DESCRIPTOR, FALL, 0);
01634 recover(pfmt);
01635 break;
01636
01637 }
01638
01639 if (pfmt->fmt_ch == ',') {
01640 register long col;
01641
01642 col = pfmt->fmt_pos;
01643
01644 GET(pfmt);
01645
01646 if (pfmt->fmt_ch == ')') {
01647 pfmt->desc_col = col;
01648 fmterr(pfmt, COMMA_NON_ANSI, FALL, col);
01649 }
01650 }
01651 else
01652 if (comma_req_flag)
01653 switch (pfmt->fmt_ch) {
01654
01655 case ')':
01656 case ':':
01657 case '/':
01658 case '\0':
01659 break;
01660
01661 default:
01662 fmterr(pfmt, ANSI_COMMA_REQ,
01663 FALL, 0);
01664 break;
01665 }
01666
01667 if (pfmt->fatal_err && pfmt->caller == LIB_CALL)
01668 return(0);
01669
01670 } while (pfmt->fmt_ch != ')');
01671
01672 if (outer_paren) {
01673 pfmt->pptr->op_code = REVERT_OP;
01674 pfmt->pptr->rep_count = pfmt->revert - pfmt->pptr;
01675 pfmt->pptr->offset = pfmt->fmt_pos;
01676 pfmt->pptr->rgcdedf = data_ed;
01677 pfmt->pptr = pfmt->pptr + 1;
01678 }
01679 else {
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723 if (pfmt->depth == 1)
01724 pfmt->revert = ploc;
01725
01726 if (ploc + 1 == pfmt->pptr && ploc->op_code == REPEAT_OP) {
01727
01728
01729
01730 pfmt->pptr = pfmt->pptr - 1;
01731
01732 (void) memset((void *) pfmt->pptr, 0, 2 * sizeof(fmt_type));
01733
01734 }
01735 else {
01736
01737 if ((num_eds == 1 ||
01738 (ploc->op_code == REPEAT_OP &&
01739 ploc->rep_count == 1) ) &&
01740 ploc->rep_count * (ploc+1)->rep_count <
01741 MAX_REP_COUNT) {
01742
01743 unsigned int size;
01744 fmt_type *ppsp;
01745
01746
01747
01748 pfmt->pptr = pfmt->pptr - 1;
01749 ppsp = ploc + 1;
01750
01751 switch (ppsp->op_code) {
01752
01753 case P_ED:
01754 case BN_ED:
01755 case BZ_ED:
01756 case COLON_ED:
01757 case S_ED:
01758 case SP_ED:
01759 case SS_ED:
01760 case T_ED:
01761 case DOLLAR_ED:
01762
01763
01764
01765 break;
01766
01767 case SLASH_ED:
01768 case TL_ED:
01769 case TR_ED:
01770
01771
01772
01773
01774
01775
01776 size = ploc->rep_count *
01777 ppsp->field_width;
01778
01779 if (size < MAX_FIELD_WIDTH) {
01780 ppsp->field_width =
01781 size;
01782 ppsp->rep_count = 1;
01783 }
01784 else
01785 ppsp->rep_count =
01786 ppsp->rep_count *
01787 ploc->rep_count;
01788
01789 break;
01790
01791 default:
01792
01793
01794
01795 ppsp->rep_count =
01796 ppsp->rep_count *
01797 ploc->rep_count;
01798 break;
01799
01800 }
01801
01802
01803
01804 (void) memmove((void *) ploc, (void *) ppsp,
01805 (pfmt->pptr - ploc) * sizeof(fmt_type));
01806
01807
01808
01809 (void) memset((void *) pfmt->pptr, 0, 2 * sizeof(fmt_type));
01810
01811 }
01812 else {
01813 pfmt->pptr->op_code = ENDREP_OP;
01814 pfmt->pptr->rep_count = ploc - pfmt->pptr;
01815 pfmt->pptr->offset = pfmt->fmt_pos;
01816 pfmt->pptr = pfmt->pptr + 1;
01817
01818 if (pfmt->maxdepth < pfmt->depth)
01819 pfmt->maxdepth = pfmt->depth;
01820 }
01821 }
01822 }
01823
01824 pfmt->depth = pfmt->depth - 1;
01825
01826 GET(pfmt);
01827
01828 if (data_ed)
01829 num_eds = -num_eds;
01830
01831 return(num_eds);
01832
01833 }