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