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