OpenCOBOL 1.1pre-rel
|
00001 /* 00002 * Copyright (C) 2001-2009 Keisuke Nishida 00003 * Copyright (C) 2007-2009 Roger While 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2, or (at your option) 00008 * any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this software; see the file COPYING. If not, write to 00017 * the Free Software Foundation, 51 Franklin Street, Fifth Floor 00018 * Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include "config.h" 00022 00023 #include <stdio.h> 00024 #include <stdlib.h> 00025 #include <string.h> 00026 #include <ctype.h> 00027 00028 #include "cobc.h" 00029 #include "tree.h" 00030 00031 #define PIC_ALPHABETIC 0x01 00032 #define PIC_NUMERIC 0x02 00033 #define PIC_NATIONAL 0x04 00034 #define PIC_EDITED 0x08 00035 #define PIC_ALPHANUMERIC (PIC_ALPHABETIC | PIC_NUMERIC) 00036 #define PIC_ALPHABETIC_EDITED (PIC_ALPHABETIC | PIC_EDITED) 00037 #define PIC_ALPHANUMERIC_EDITED (PIC_ALPHANUMERIC | PIC_EDITED) 00038 #define PIC_NUMERIC_EDITED (PIC_NUMERIC | PIC_EDITED) 00039 #define PIC_NATIONAL_EDITED (PIC_NATIONAL | PIC_EDITED) 00040 00041 /* Local variables */ 00042 00043 static const enum cb_class category_to_class_table[] = { 00044 CB_CLASS_UNKNOWN, /* CB_CATEGORY_UNKNOWN */ 00045 CB_CLASS_ALPHABETIC, /* CB_CATEGORY_ALPHABETIC */ 00046 CB_CLASS_ALPHANUMERIC, /* CB_CATEGORY_ALPHANUMERIC */ 00047 CB_CLASS_ALPHANUMERIC, /* CB_CATEGORY_ALPHANUMERIC_EDITED */ 00048 CB_CLASS_BOOLEAN, /* CB_CATEGORY_BOOLEAN */ 00049 CB_CLASS_INDEX, /* CB_CATEGORY_INDEX */ 00050 CB_CLASS_NATIONAL, /* CB_CATEGORY_NATIONAL */ 00051 CB_CLASS_NATIONAL, /* CB_CATEGORY_NATIONAL_EDITED */ 00052 CB_CLASS_NUMERIC, /* CB_CATEGORY_NUMERIC */ 00053 CB_CLASS_ALPHANUMERIC, /* CB_CATEGORY_NUMERIC_EDITED */ 00054 CB_CLASS_OBJECT, /* CB_CATEGORY_OBJECT_REFERENCE */ 00055 CB_CLASS_POINTER, /* CB_CATEGORY_DATA_POINTER */ 00056 CB_CLASS_POINTER, /* CB_CATEGORY_PROGRAM_POINTER */ 00057 }; 00058 00059 static struct int_node { 00060 struct int_node *next; 00061 cb_tree node; 00062 int n; 00063 } *int_node_table = NULL; 00064 00065 static char *treenamebuff = NULL; 00066 static int filler_id = 1; 00067 00068 /* Global variables */ 00069 00070 /* 00071 * Constants 00072 */ 00073 00074 cb_tree cb_any; 00075 cb_tree cb_true; 00076 cb_tree cb_false; 00077 cb_tree cb_null; 00078 cb_tree cb_zero; 00079 cb_tree cb_one; 00080 cb_tree cb_space; 00081 cb_tree cb_low; 00082 cb_tree cb_high; 00083 cb_tree cb_norm_low; 00084 cb_tree cb_norm_high; 00085 cb_tree cb_quote; 00086 cb_tree cb_int0; 00087 cb_tree cb_int1; 00088 cb_tree cb_int2; 00089 cb_tree cb_int3; 00090 cb_tree cb_int4; 00091 cb_tree cb_int5; 00092 cb_tree cb_i[8]; 00093 cb_tree cb_error_node; 00094 00095 cb_tree cb_intr_whencomp; 00096 cb_tree cb_intr_pi; 00097 cb_tree cb_intr_e; 00098 00099 cb_tree cb_standard_error_handler; 00100 00101 size_t gen_screen_ptr = 0; 00102 00103 /* Local functions */ 00104 00105 static char * 00106 to_cname (const char *s) 00107 { 00108 char *copy; 00109 unsigned char *p; 00110 00111 copy = strdup (s); 00112 for (p = (unsigned char *)copy; *p; p++) { 00113 *p = (*p == '-') ? '_' : toupper (*p); 00114 } 00115 return copy; 00116 } 00117 00118 static size_t 00119 hash (const unsigned char *s) 00120 { 00121 size_t val = 0; 00122 00123 for (; *s; s++) { 00124 val += toupper (*s); 00125 } 00126 return val % CB_WORD_HASH_SIZE; 00127 } 00128 00129 static struct cb_word * 00130 lookup_word (const char *name) 00131 { 00132 struct cb_word *p; 00133 size_t val; 00134 00135 val = hash ((const unsigned char *)name); 00136 /* find the existing word */ 00137 if (current_program) { 00138 for (p = current_program->word_table[val]; p; p = p->next) { 00139 if (strcasecmp (p->name, name) == 0) { 00140 return p; 00141 } 00142 } 00143 } 00144 00145 /* create new word */ 00146 p = cobc_malloc (sizeof (struct cb_word)); 00147 p->name = strdup (name); 00148 00149 /* insert it into the table */ 00150 if (current_program) { 00151 p->next = current_program->word_table[val]; 00152 current_program->word_table[val] = p; 00153 } 00154 00155 return p; 00156 } 00157 00158 static void 00159 file_error (cb_tree name, const char *clause) 00160 { 00161 cb_error_x (name, _("%s clause is required for file '%s'"), clause, 00162 CB_NAME (name)); 00163 } 00164 00165 /* 00166 * Tree 00167 */ 00168 00169 static void * 00170 make_tree (int tag, enum cb_category category, size_t size) 00171 { 00172 cb_tree x; 00173 00174 x = cobc_malloc (size); 00175 x->tag = tag; 00176 x->category = category; 00177 return x; 00178 } 00179 00180 static cb_tree 00181 make_constant (enum cb_category category, const char *val) 00182 { 00183 struct cb_const *p; 00184 00185 p = make_tree (CB_TAG_CONST, category, sizeof (struct cb_const)); 00186 p->val = val; 00187 return CB_TREE (p); 00188 } 00189 00190 static cb_tree 00191 make_constant_label (const char *name) 00192 { 00193 struct cb_label *p; 00194 00195 p = CB_LABEL (cb_build_label (cb_build_reference (name), NULL)); 00196 p->need_begin = 1; 00197 return CB_TREE (p); 00198 } 00199 00200 static int 00201 cb_name_1 (char *s, cb_tree x) 00202 { 00203 char *orig; 00204 struct cb_funcall *cbip; 00205 struct cb_binary_op *cbop; 00206 struct cb_reference *p; 00207 struct cb_intrinsic *cbit; 00208 cb_tree l; 00209 int i; 00210 00211 orig = s; 00212 switch (CB_TREE_TAG (x)) { 00213 case CB_TAG_CONST: 00214 if (x == cb_any) { 00215 strcpy (s, "ANY"); 00216 } else if (x == cb_true) { 00217 strcpy (s, "TRUE"); 00218 } else if (x == cb_false) { 00219 strcpy (s, "FALSE"); 00220 } else if (x == cb_null) { 00221 strcpy (s, "NULL"); 00222 } else if (x == cb_zero) { 00223 strcpy (s, "ZERO"); 00224 } else if (x == cb_space) { 00225 strcpy (s, "SPACE"); 00226 } else if (x == cb_low || x == cb_norm_low) { 00227 strcpy (s, "LOW-VALUE"); 00228 } else if (x == cb_high || x == cb_norm_high) { 00229 strcpy (s, "HIGH-VALUE"); 00230 } else if (x == cb_quote) { 00231 strcpy (s, "QUOTE"); 00232 } else if (x == cb_error_node) { 00233 strcpy (s, "Internal error node"); 00234 } else { 00235 strcpy (s, "#<unknown constant>"); 00236 } 00237 break; 00238 00239 case CB_TAG_LITERAL: 00240 if (CB_TREE_CLASS (x) == CB_CLASS_NUMERIC) { 00241 strcpy (s, (char *)CB_LITERAL (x)->data); 00242 } else { 00243 sprintf (s, "\"%s\"", CB_LITERAL (x)->data); 00244 } 00245 break; 00246 00247 case CB_TAG_FIELD: 00248 strcpy (s, CB_FIELD (x)->name); 00249 break; 00250 00251 case CB_TAG_REFERENCE: 00252 p = CB_REFERENCE (x); 00253 s += sprintf (s, "%s", p->word->name); 00254 if (p->subs) { 00255 l = p->subs = cb_list_reverse (p->subs); 00256 s += sprintf (s, " ("); 00257 for (; l; l = CB_CHAIN (l)) { 00258 s += cb_name_1 (s, CB_VALUE (l)); 00259 s += sprintf (s, CB_CHAIN (l) ? ", " : ")"); 00260 } 00261 p->subs = cb_list_reverse (p->subs); 00262 } 00263 if (p->offset) { 00264 s += sprintf (s, " ("); 00265 s += cb_name_1 (s, p->offset); 00266 s += sprintf (s, ":"); 00267 if (p->length) { 00268 s += cb_name_1 (s, p->length); 00269 } 00270 strcpy (s, ")"); 00271 } 00272 if (p->chain) { 00273 s += sprintf (s, " in "); 00274 s += cb_name_1 (s, p->chain); 00275 } 00276 break; 00277 00278 case CB_TAG_LABEL: 00279 sprintf (s, "%s", CB_LABEL (x)->name); 00280 break; 00281 00282 case CB_TAG_ALPHABET_NAME: 00283 sprintf (s, "%s", CB_ALPHABET_NAME (x)->name); 00284 break; 00285 00286 case CB_TAG_CLASS_NAME: 00287 sprintf (s, "%s", CB_CLASS_NAME (x)->name); 00288 break; 00289 00290 case CB_TAG_LOCALE_NAME: 00291 sprintf (s, "%s", CB_LOCALE_NAME (x)->name); 00292 break; 00293 00294 case CB_TAG_BINARY_OP: 00295 cbop = CB_BINARY_OP (x); 00296 if (cbop->op == '@') { 00297 s += sprintf (s, "("); 00298 s += cb_name_1 (s, cbop->x); 00299 s += sprintf (s, ")"); 00300 } else if (cbop->op == '!') { 00301 s += sprintf (s, "!"); 00302 s += cb_name_1 (s, cbop->x); 00303 } else { 00304 s += sprintf (s, "("); 00305 s += cb_name_1 (s, cbop->x); 00306 s += sprintf (s, " %c ", cbop->op); 00307 s += cb_name_1 (s, cbop->y); 00308 strcpy (s, ")"); 00309 } 00310 break; 00311 00312 case CB_TAG_FUNCALL: 00313 cbip = CB_FUNCALL (x); 00314 s += sprintf (s, "%s", cbip->name); 00315 for (i = 0; i < cbip->argc; i++) { 00316 s += sprintf (s, (i == 0) ? "(" : ", "); 00317 s += cb_name_1 (s, cbip->argv[i]); 00318 } 00319 s += sprintf (s, ")"); 00320 break; 00321 00322 case CB_TAG_INTRINSIC: 00323 cbit = CB_INTRINSIC (x); 00324 sprintf (s, "FUNCTION %s", cbit->intr_tab->name); 00325 break; 00326 default: 00327 sprintf (s, "#<unknown %d %p>", CB_TREE_TAG (x), x); 00328 } 00329 00330 return strlen (orig); 00331 } 00332 00333 static cb_tree 00334 make_intrinsic (cb_tree name, struct cb_intrinsic_table *cbp, cb_tree args, 00335 cb_tree field, cb_tree refmod) 00336 { 00337 struct cb_intrinsic *x; 00338 00339 /* Leave in, we may need this 00340 cb_tree l; 00341 for (l = args; l; l = CB_CHAIN(l)) { 00342 switch (CB_TREE_TAG (CB_VALUE(l))) { 00343 case CB_TAG_CONST: 00344 case CB_TAG_INTEGER: 00345 case CB_TAG_LITERAL: 00346 case CB_TAG_DECIMAL: 00347 case CB_TAG_FIELD: 00348 case CB_TAG_REFERENCE: 00349 case CB_TAG_INTRINSIC: 00350 break; 00351 default: 00352 cb_error (_("FUNCTION %s has invalid/not supported arguments - Tag %d"), 00353 cbp->name, CB_TREE_TAG(l)); 00354 return cb_error_node; 00355 00356 } 00357 } 00358 */ 00359 x = make_tree (CB_TAG_INTRINSIC, cbp->category, sizeof (struct cb_intrinsic)); 00360 x->name = name; 00361 x->args = args; 00362 x->intr_tab = cbp; 00363 x->intr_field = field; 00364 if (refmod) { 00365 x->offset = CB_PAIR_X (refmod); 00366 x->length = CB_PAIR_Y (refmod); 00367 } 00368 return CB_TREE (x); 00369 } 00370 00371 static cb_tree 00372 global_check (struct cb_reference *r, cb_tree items, size_t *ambiguous) 00373 { 00374 cb_tree candidate = NULL; 00375 struct cb_field *p; 00376 cb_tree v; 00377 cb_tree c; 00378 00379 for (; items; items = CB_CHAIN (items)) { 00380 /* find a candidate value by resolving qualification */ 00381 v = CB_VALUE (items); 00382 c = r->chain; 00383 if (CB_FIELD_P (v)) { 00384 if (!CB_FIELD (v)->flag_is_global) { 00385 continue; 00386 } 00387 /* in case the value is a field, it might be qualified 00388 by its parent names and a file name */ 00389 if (CB_FIELD (v)->flag_indexed_by) { 00390 p = CB_FIELD (v)->index_qual; 00391 } else { 00392 p = CB_FIELD (v)->parent; 00393 } 00394 /* resolve by parents */ 00395 for (; p; p = p->parent) { 00396 if (c && strcasecmp (CB_NAME (c), p->name) == 0) { 00397 c = CB_REFERENCE (c)->chain; 00398 } 00399 } 00400 00401 /* resolve by file */ 00402 if (c && CB_REFERENCE (c)->chain == NULL) { 00403 if (CB_REFERENCE (c)->word->count == 1 && CB_FILE_P (cb_ref (c)) 00404 && (CB_FILE (cb_ref (c)) == cb_field_founder (CB_FIELD (v))->file)) { 00405 c = CB_REFERENCE (c)->chain; 00406 } 00407 } 00408 } 00409 /* a well qualified value is a good candidate */ 00410 if (c == NULL) { 00411 if (candidate == NULL) { 00412 /* keep the first candidate */ 00413 candidate = v; 00414 } else { 00415 /* multiple candidates and possibly ambiguous */ 00416 *ambiguous = 1; 00417 } 00418 } 00419 } 00420 return candidate; 00421 } 00422 00423 /* Global functions */ 00424 00425 struct cb_literal * 00426 build_literal (enum cb_category category, const unsigned char *data, size_t size) 00427 { 00428 struct cb_literal *p; 00429 00430 p = make_tree (CB_TAG_LITERAL, category, sizeof (struct cb_literal)); 00431 p->data = cobc_malloc ((size_t) (size + 1)); 00432 p->size = size; 00433 memcpy (p->data, data, (size_t) size); 00434 /* RXW - malloc zeroes 00435 p->data[size] = 0; 00436 */ 00437 return p; 00438 } 00439 00440 char * 00441 cb_name (cb_tree x) 00442 { 00443 if (!treenamebuff) { 00444 treenamebuff = cobc_malloc (COB_NORMAL_BUFF); 00445 } 00446 cb_name_1 (treenamebuff, x); 00447 return treenamebuff; 00448 } 00449 00450 enum cb_class 00451 cb_tree_class (cb_tree x) 00452 { 00453 00454 return category_to_class_table[CB_TREE_CATEGORY (x)]; 00455 } 00456 00457 enum cb_category 00458 cb_tree_category (cb_tree x) 00459 { 00460 struct cb_cast *p; 00461 struct cb_reference *r; 00462 struct cb_field *f; 00463 00464 if (x == cb_error_node) { 00465 return 0; 00466 } 00467 if (x->category != CB_CATEGORY_UNKNOWN) { 00468 return x->category; 00469 } 00470 00471 switch (CB_TREE_TAG (x)) { 00472 case CB_TAG_CAST: 00473 p = CB_CAST (x); 00474 switch (p->type) { 00475 case CB_CAST_ADDRESS: 00476 case CB_CAST_ADDR_OF_ADDR: 00477 x->category = CB_CATEGORY_DATA_POINTER; 00478 break; 00479 case CB_CAST_PROGRAM_POINTER: 00480 x->category = CB_CATEGORY_PROGRAM_POINTER; 00481 break; 00482 default: 00483 fprintf (stderr, "Unexpected cast type -> %d\n", p->type); 00484 ABORT (); 00485 } 00486 break; 00487 case CB_TAG_REFERENCE: 00488 r = CB_REFERENCE (x); 00489 if (r->offset) { 00490 x->category = CB_CATEGORY_ALPHANUMERIC; 00491 } else { 00492 x->category = cb_tree_category (r->value); 00493 } 00494 break; 00495 case CB_TAG_FIELD: 00496 f = CB_FIELD (x); 00497 if (f->children) { 00498 x->category = CB_CATEGORY_ALPHANUMERIC; 00499 } else if (f->usage == CB_USAGE_POINTER && f->level != 88) { 00500 x->category = CB_CATEGORY_DATA_POINTER; 00501 } else if (f->usage == CB_USAGE_PROGRAM_POINTER && f->level != 88) { 00502 x->category = CB_CATEGORY_PROGRAM_POINTER; 00503 } else { 00504 switch (f->level) { 00505 case 66: 00506 if (f->rename_thru) { 00507 x->category = CB_CATEGORY_ALPHANUMERIC; 00508 } else { 00509 x->category = cb_tree_category (CB_TREE (f->redefines)); 00510 } 00511 break; 00512 case 88: 00513 x->category = CB_CATEGORY_BOOLEAN; 00514 break; 00515 default: 00516 x->category = f->pic->category; 00517 break; 00518 } 00519 } 00520 break; 00521 case CB_TAG_ALPHABET_NAME: 00522 case CB_TAG_LOCALE_NAME: 00523 x->category = CB_CATEGORY_ALPHANUMERIC; 00524 break; 00525 case CB_TAG_BINARY_OP: 00526 x->category = CB_CATEGORY_BOOLEAN; 00527 break; 00528 default: 00529 fprintf (stderr, "Unknown tree tag %d Category %d\n", CB_TREE_TAG (x), x->category); 00530 ABORT (); 00531 } 00532 00533 return x->category; 00534 } 00535 00536 int 00537 cb_tree_type (cb_tree x) 00538 { 00539 struct cb_field *f; 00540 00541 f = cb_field (x); 00542 if (f->children) { 00543 return COB_TYPE_GROUP; 00544 } 00545 00546 switch (CB_TREE_CATEGORY (x)) { 00547 case CB_CATEGORY_ALPHABETIC: 00548 case CB_CATEGORY_ALPHANUMERIC: 00549 return COB_TYPE_ALPHANUMERIC; 00550 case CB_CATEGORY_ALPHANUMERIC_EDITED: 00551 return COB_TYPE_ALPHANUMERIC_EDITED; 00552 case CB_CATEGORY_NUMERIC: 00553 switch (f->usage) { 00554 case CB_USAGE_DISPLAY: 00555 return COB_TYPE_NUMERIC_DISPLAY; 00556 case CB_USAGE_BINARY: 00557 case CB_USAGE_COMP_5: 00558 case CB_USAGE_COMP_X: 00559 case CB_USAGE_INDEX: 00560 case CB_USAGE_LENGTH: 00561 return COB_TYPE_NUMERIC_BINARY; 00562 case CB_USAGE_FLOAT: 00563 return COB_TYPE_NUMERIC_FLOAT; 00564 case CB_USAGE_DOUBLE: 00565 return COB_TYPE_NUMERIC_DOUBLE; 00566 case CB_USAGE_PACKED: 00567 return COB_TYPE_NUMERIC_PACKED; 00568 default: 00569 fprintf (stderr, "Unexpected numeric usage -> %d\n", f->usage); 00570 ABORT (); 00571 } 00572 case CB_CATEGORY_NUMERIC_EDITED: 00573 return COB_TYPE_NUMERIC_EDITED; 00574 case CB_CATEGORY_OBJECT_REFERENCE: 00575 case CB_CATEGORY_DATA_POINTER: 00576 case CB_CATEGORY_PROGRAM_POINTER: 00577 return COB_TYPE_NUMERIC_BINARY; 00578 default: 00579 fprintf (stderr, "Unexpected category -> %d\n", CB_TREE_CATEGORY (x)); 00580 ABORT (); 00581 } 00582 /* NOT REACHED */ 00583 return 0; 00584 } 00585 00586 int 00587 cb_fits_int (cb_tree x) 00588 { 00589 struct cb_literal *l; 00590 struct cb_field *f; 00591 00592 switch (CB_TREE_TAG (x)) { 00593 case CB_TAG_LITERAL: 00594 l = CB_LITERAL (x); 00595 if (l->scale <= 0 && l->size < 10) { 00596 return 1; 00597 } 00598 return 0; 00599 case CB_TAG_FIELD: 00600 f = CB_FIELD (x); 00601 switch (f->usage) { 00602 case CB_USAGE_INDEX: 00603 case CB_USAGE_LENGTH: 00604 return 1; 00605 case CB_USAGE_BINARY: 00606 case CB_USAGE_COMP_5: 00607 case CB_USAGE_COMP_X: 00608 if (f->pic->scale <= 0 && f->size <= (int)sizeof (int)) { 00609 return 1; 00610 } 00611 return 0; 00612 case CB_USAGE_DISPLAY: 00613 if (f->size < 10) { 00614 if (!f->pic || f->pic->scale <= 0) { 00615 return 1; 00616 } 00617 } 00618 return 0; 00619 case CB_USAGE_PACKED: 00620 if (f->pic->scale <= 0 && f->pic->digits < 10) { 00621 return 1; 00622 } 00623 return 0; 00624 default: 00625 return 0; 00626 } 00627 case CB_TAG_REFERENCE: 00628 return cb_fits_int (CB_REFERENCE (x)->value); 00629 default: 00630 return 0; 00631 } 00632 } 00633 00634 int 00635 cb_fits_long_long (cb_tree x) 00636 { 00637 struct cb_literal *l; 00638 struct cb_field *f; 00639 00640 switch (CB_TREE_TAG (x)) { 00641 case CB_TAG_LITERAL: 00642 l = CB_LITERAL (x); 00643 if (l->scale <= 0 && l->size < 19) { 00644 return 1; 00645 } 00646 return 0; 00647 case CB_TAG_FIELD: 00648 f = CB_FIELD (x); 00649 switch (f->usage) { 00650 case CB_USAGE_INDEX: 00651 case CB_USAGE_LENGTH: 00652 return 1; 00653 case CB_USAGE_BINARY: 00654 case CB_USAGE_COMP_5: 00655 case CB_USAGE_COMP_X: 00656 if (f->pic->scale <= 0 && f->size <= (int)sizeof (long long)) { 00657 return 1; 00658 } 00659 return 0; 00660 case CB_USAGE_DISPLAY: 00661 if (f->pic->scale <= 0 && f->size < 19) { 00662 return 1; 00663 } 00664 return 0; 00665 default: 00666 return 0; 00667 } 00668 case CB_TAG_REFERENCE: 00669 return cb_fits_long_long (CB_REFERENCE (x)->value); 00670 default: 00671 return 0; 00672 } 00673 } 00674 00675 int 00676 cb_get_int (cb_tree x) 00677 { 00678 struct cb_literal *l; 00679 size_t i; 00680 int val = 0; 00681 00682 l = CB_LITERAL (x); 00683 for (i = 0; i < l->size; i++) { 00684 if (l->data[i] != '0') { 00685 break; 00686 } 00687 } 00688 00689 /* RXWRXW 00690 if (l->size - i >= 10) { 00691 ABORT (); 00692 } 00693 */ 00694 00695 for (; i < l->size; i++) { 00696 val = val * 10 + l->data[i] - '0'; 00697 } 00698 if (l->sign < 0) { 00699 val = -val; 00700 } 00701 return val; 00702 } 00703 00704 long long 00705 cb_get_long_long (cb_tree x) 00706 { 00707 struct cb_literal *l; 00708 size_t i; 00709 long long val = 0; 00710 00711 l = CB_LITERAL (x); 00712 for (i = 0; i < l->size; i++) { 00713 if (l->data[i] != '0') { 00714 break; 00715 } 00716 } 00717 00718 if (l->size - i >= 19) { 00719 ABORT (); 00720 } 00721 00722 for (; i < l->size; i++) { 00723 val = val * 10 + l->data[i] - '0'; 00724 } 00725 if (l->sign < 0) { 00726 val = -val; 00727 } 00728 return val; 00729 } 00730 00731 void 00732 cb_init_constants (void) 00733 { 00734 char *s; 00735 int i; 00736 00737 cb_error_node = make_constant (CB_CATEGORY_UNKNOWN, NULL); 00738 cb_any = make_constant (CB_CATEGORY_UNKNOWN, NULL); 00739 cb_true = make_constant (CB_CATEGORY_BOOLEAN, "1"); 00740 cb_false = make_constant (CB_CATEGORY_BOOLEAN, "0"); 00741 cb_null = make_constant (CB_CATEGORY_DATA_POINTER, "0"); 00742 cb_zero = make_constant (CB_CATEGORY_NUMERIC, "&cob_zero"); 00743 cb_one = make_constant (CB_CATEGORY_NUMERIC, "&cob_one"); 00744 cb_space = make_constant (CB_CATEGORY_ALPHANUMERIC, "&cob_space"); 00745 cb_low = make_constant (CB_CATEGORY_ALPHANUMERIC, "&cob_low"); 00746 cb_norm_low = cb_low; 00747 cb_high = make_constant (CB_CATEGORY_ALPHANUMERIC, "&cob_high"); 00748 cb_norm_high = cb_high; 00749 cb_quote = make_constant (CB_CATEGORY_ALPHANUMERIC, "&cob_quote"); 00750 cb_int0 = cb_int (0); 00751 cb_int1 = cb_int (1); 00752 cb_int2 = cb_int (2); 00753 cb_int3 = cb_int (3); 00754 cb_int4 = cb_int (4); 00755 cb_int5 = cb_int (5); 00756 for (i = 1; i < 8; i++) { 00757 s = cobc_malloc (4); 00758 sprintf (s, "i%d", i); 00759 cb_i[i] = make_constant (CB_CATEGORY_NUMERIC, s); 00760 } 00761 cb_standard_error_handler = make_constant_label ("Default Error Handler"); 00762 } 00763 00764 /* 00765 * List 00766 */ 00767 00768 cb_tree 00769 cb_build_list (cb_tree purpose, cb_tree value, cb_tree rest) 00770 { 00771 struct cb_list *p; 00772 00773 p = make_tree (CB_TAG_LIST, CB_CATEGORY_UNKNOWN, sizeof (struct cb_list)); 00774 p->purpose = purpose; 00775 p->value = value; 00776 p->chain = rest; 00777 return CB_TREE (p); 00778 } 00779 00780 cb_tree 00781 cb_list_append (cb_tree l1, cb_tree l2) 00782 { 00783 cb_tree l; 00784 00785 if (l1 == NULL) { 00786 return l2; 00787 } else { 00788 l = l1; 00789 while (CB_CHAIN (l)) { 00790 l = CB_CHAIN (l); 00791 } 00792 CB_CHAIN (l) = l2; 00793 return l1; 00794 } 00795 } 00796 00797 cb_tree 00798 cb_list_add (cb_tree l, cb_tree x) 00799 { 00800 return cb_list_append (l, cb_list_init (x)); 00801 } 00802 00803 cb_tree 00804 cb_list_reverse (cb_tree l) 00805 { 00806 cb_tree next; 00807 cb_tree last = NULL; 00808 00809 for (; l; l = next) { 00810 next = CB_CHAIN (l); 00811 CB_CHAIN (l) = last; 00812 last = l; 00813 } 00814 return last; 00815 } 00816 00817 int 00818 cb_list_length (cb_tree l) 00819 { 00820 int n = 0; 00821 00822 for (; l; l = CB_CHAIN (l)) { 00823 n++; 00824 } 00825 return n; 00826 } 00827 00828 void 00829 cb_list_map (cb_tree (*func) (cb_tree x), cb_tree l) 00830 { 00831 for (; l; l = CB_CHAIN (l)) { 00832 CB_VALUE (l) = func (CB_VALUE (l)); 00833 } 00834 } 00835 00836 /* 00837 * Program 00838 */ 00839 00840 struct cb_program * 00841 cb_build_program (struct cb_program *last_program, int nest_level) 00842 { 00843 struct cb_program *p; 00844 00845 cb_reset_78 (); 00846 cb_reset_in_procedure (); 00847 cb_clear_real_field (); 00848 p = cobc_malloc (sizeof (struct cb_program)); 00849 p->next_program = last_program; 00850 p->nested_level = nest_level; 00851 p->decimal_point = '.'; 00852 p->currency_symbol = '$'; 00853 p->numeric_separator = ','; 00854 if (nest_level) { 00855 p->global_file_list = last_program->global_file_list; 00856 p->collating_sequence = last_program->collating_sequence; 00857 p->function_spec_list = last_program->function_spec_list; 00858 p->class_spec_list = last_program->class_spec_list; 00859 p->interface_spec_list = last_program->interface_spec_list; 00860 p->program_spec_list = last_program->program_spec_list; 00861 p->property_spec_list = last_program->property_spec_list; 00862 p->alphabet_name_list = last_program->alphabet_name_list; 00863 p->class_name_list = last_program->class_name_list; 00864 p->locale_list = last_program->locale_list; 00865 p->symbolic_list = last_program->symbolic_list; 00866 p->decimal_point = last_program->decimal_point; 00867 p->numeric_separator = last_program->numeric_separator; 00868 p->currency_symbol = last_program->currency_symbol; 00869 p->cb_return_code = last_program->cb_return_code; 00870 } else { 00871 functions_are_all = cb_flag_functions_all; 00872 } 00873 return p; 00874 } 00875 00876 /* 00877 * Integer 00878 */ 00879 00880 cb_tree 00881 cb_int (int n) 00882 { 00883 struct cb_integer *x; 00884 struct int_node *p; 00885 00886 for (p = int_node_table; p; p = p->next) { 00887 if (p->n == n) { 00888 return p->node; 00889 } 00890 } 00891 00892 x = make_tree (CB_TAG_INTEGER, CB_CATEGORY_NUMERIC, sizeof (struct cb_integer)); 00893 x->val = n; 00894 00895 p = cobc_malloc (sizeof (struct int_node)); 00896 p->n = n; 00897 p->node = CB_TREE (x); 00898 p->next = int_node_table; 00899 int_node_table = p; 00900 return p->node; 00901 } 00902 00903 /* 00904 * String 00905 */ 00906 00907 cb_tree 00908 cb_build_string (const unsigned char *data, size_t size) 00909 { 00910 struct cb_string *p; 00911 00912 p = make_tree (CB_TAG_STRING, CB_CATEGORY_ALPHANUMERIC, sizeof (struct cb_string)); 00913 p->size = size; 00914 p->data = data; 00915 return CB_TREE (p); 00916 } 00917 00918 /* 00919 * Alphabet-name 00920 */ 00921 00922 cb_tree 00923 cb_build_alphabet_name (cb_tree name, enum cb_alphabet_name_type type) 00924 { 00925 struct cb_alphabet_name *p; 00926 00927 p = make_tree (CB_TAG_ALPHABET_NAME, CB_CATEGORY_UNKNOWN, sizeof (struct cb_alphabet_name)); 00928 p->name = cb_define (name, CB_TREE (p)); 00929 p->cname = to_cname (p->name); 00930 p->type = type; 00931 return CB_TREE (p); 00932 } 00933 00934 /* 00935 * Class-name 00936 */ 00937 00938 cb_tree 00939 cb_build_class_name (cb_tree name, cb_tree list) 00940 { 00941 struct cb_class_name *p; 00942 char buff[COB_MINI_BUFF]; 00943 00944 p = make_tree (CB_TAG_CLASS_NAME, CB_CATEGORY_BOOLEAN, sizeof (struct cb_class_name)); 00945 p->name = cb_define (name, CB_TREE (p)); 00946 snprintf (buff, COB_MINI_MAX, "is_%s", to_cname (p->name)); 00947 p->cname = strdup (buff); 00948 p->list = list; 00949 return CB_TREE (p); 00950 } 00951 00952 /* 00953 * Locale-name 00954 */ 00955 00956 cb_tree 00957 cb_build_locale_name (cb_tree name, cb_tree list) 00958 { 00959 struct cb_class_name *p; 00960 00961 p = make_tree (CB_TAG_LOCALE_NAME, CB_CATEGORY_UNKNOWN, sizeof (struct cb_locale_name)); 00962 p->name = cb_define (name, CB_TREE (p)); 00963 p->cname = to_cname (p->name); 00964 p->list = list; 00965 return CB_TREE (p); 00966 } 00967 00968 /* 00969 * System-name 00970 */ 00971 00972 cb_tree 00973 cb_build_system_name (enum cb_system_name_category category, int token) 00974 { 00975 struct cb_system_name *p; 00976 00977 p = make_tree (CB_TAG_SYSTEM_NAME, CB_CATEGORY_UNKNOWN, sizeof (struct cb_system_name)); 00978 p->category = category; 00979 p->token = token; 00980 return CB_TREE (p); 00981 } 00982 00983 /* 00984 * Literal 00985 */ 00986 00987 cb_tree 00988 cb_build_numeric_literal (int sign, const unsigned char *data, int scale) 00989 { 00990 struct cb_literal *p; 00991 00992 p = build_literal (CB_CATEGORY_NUMERIC, data, strlen ((char *)data)); 00993 p->sign = (char)sign; 00994 p->scale = (char)scale; 00995 return CB_TREE (p); 00996 } 00997 00998 cb_tree 00999 cb_build_alphanumeric_literal (const unsigned char *data, size_t size) 01000 { 01001 return CB_TREE (build_literal (CB_CATEGORY_ALPHANUMERIC, data, size)); 01002 } 01003 01004 cb_tree 01005 cb_concat_literals (cb_tree x1, cb_tree x2) 01006 { 01007 unsigned char *buff; 01008 cb_tree x; 01009 unsigned char *data1; 01010 unsigned char *data2; 01011 size_t size1; 01012 size_t size2; 01013 01014 if (x1 == cb_error_node || x2 == cb_error_node) { 01015 return cb_error_node; 01016 } 01017 if (CB_LITERAL_P (x1)) { 01018 data1 = CB_LITERAL (x1)->data; 01019 size1 = CB_LITERAL (x1)->size; 01020 } else if (CB_CONST_P (x1)) { 01021 size1 = 1; 01022 if (x1 == cb_space) { 01023 data1 = (unsigned char *)" "; 01024 } else if (x1 == cb_zero) { 01025 data1 = (unsigned char *)"0"; 01026 } else if (x1 == cb_quote) { 01027 data1 = (unsigned char *)"\""; 01028 } else if (x1 == cb_norm_low) { 01029 data1 = (unsigned char *)"\0"; 01030 } else if (x1 == cb_norm_high) { 01031 data1 = (unsigned char *)"\255"; 01032 } else if (x1 == cb_null) { 01033 data1 = (unsigned char *)"\0"; 01034 } else { 01035 return cb_error_node; 01036 } 01037 } else { 01038 return cb_error_node; 01039 } 01040 if (CB_LITERAL_P (x2)) { 01041 data2 = CB_LITERAL (x2)->data; 01042 size2 = CB_LITERAL (x2)->size; 01043 } else if (CB_CONST_P (x2)) { 01044 size2 = 1; 01045 if (x2 == cb_space) { 01046 data2 = (unsigned char *)" "; 01047 } else if (x2 == cb_zero) { 01048 data2 = (unsigned char *)"0"; 01049 } else if (x2 == cb_quote) { 01050 data2 = (unsigned char *)"\""; 01051 } else if (x2 == cb_norm_low) { 01052 data2 = (unsigned char *)"\0"; 01053 } else if (x2 == cb_norm_high) { 01054 data2 = (unsigned char *)"\255"; 01055 } else if (x2 == cb_null) { 01056 data2 = (unsigned char *)"\0"; 01057 } else { 01058 return cb_error_node; 01059 } 01060 } else { 01061 return cb_error_node; 01062 } 01063 buff = cobc_malloc (size1 + size2 + 3); 01064 memcpy (buff, data1, size1); 01065 memcpy (buff + size1, data2, size2); 01066 x = cb_build_alphanumeric_literal (buff, size1 + size2); 01067 free (buff); 01068 return x; 01069 } 01070 01071 /* 01072 * Decimal 01073 */ 01074 01075 cb_tree 01076 cb_build_decimal (int id) 01077 { 01078 struct cb_decimal *p; 01079 01080 p = make_tree (CB_TAG_DECIMAL, CB_CATEGORY_NUMERIC, sizeof (struct cb_decimal)); 01081 p->id = id; 01082 return CB_TREE (p); 01083 } 01084 01085 /* 01086 * Picture 01087 */ 01088 01089 cb_tree 01090 cb_build_picture (const char *str) 01091 { 01092 struct cb_picture *pic; 01093 const char *p; 01094 size_t idx = 0; 01095 size_t buffcnt = 0; 01096 size_t at_beginning; 01097 size_t at_end; 01098 size_t p_char_seen; 01099 size_t s_char_seen; 01100 int category = 0; 01101 int size = 0; 01102 int allocated = 0; 01103 int digits = 0; 01104 int scale = 0; 01105 int s_count = 0; 01106 int v_count = 0; 01107 int i; 01108 int n; 01109 unsigned char c; 01110 unsigned char lastonechar = 0; 01111 unsigned char lasttwochar = 0; 01112 unsigned char buff[COB_SMALL_BUFF]; 01113 01114 pic = make_tree (CB_TAG_PICTURE, CB_CATEGORY_UNKNOWN, sizeof (struct cb_picture)); 01115 if (strlen (str) > 50) { 01116 goto error; 01117 } 01118 memset (buff, 0, sizeof (buff)); 01119 p_char_seen = 0; 01120 s_char_seen = 0; 01121 for (p = str; *p; p++) { 01122 n = 1; 01123 c = *p; 01124 repeat: 01125 /* count the number of repeated chars */ 01126 while (p[1] == c) { 01127 p++, n++; 01128 } 01129 01130 /* add parenthesized numbers */ 01131 if (p[1] == '(') { 01132 i = 0; 01133 p += 2; 01134 for (; *p == '0'; p++) { 01135 ; 01136 } 01137 for (; *p != ')'; p++) { 01138 if (!isdigit (*p)) { 01139 goto error; 01140 } else { 01141 allocated++; 01142 if (allocated > 9) { 01143 goto error; 01144 } 01145 i = i * 10 + (*p - '0'); 01146 } 01147 } 01148 if (i == 0) { 01149 goto error; 01150 } 01151 n += i - 1; 01152 goto repeat; 01153 } 01154 01155 /* check grammar and category */ 01156 /* FIXME: need more error check */ 01157 switch (c) { 01158 case 'A': 01159 if (s_char_seen || p_char_seen) { 01160 goto error; 01161 } 01162 category |= PIC_ALPHABETIC; 01163 break; 01164 01165 case 'X': 01166 if (s_char_seen || p_char_seen) { 01167 goto error; 01168 } 01169 category |= PIC_ALPHANUMERIC; 01170 break; 01171 01172 case '9': 01173 category |= PIC_NUMERIC; 01174 digits += n; 01175 if (v_count) { 01176 scale += n; 01177 } 01178 break; 01179 01180 case 'N': 01181 if (s_char_seen || p_char_seen) { 01182 goto error; 01183 } 01184 category |= PIC_NATIONAL; 01185 break; 01186 01187 case 'S': 01188 category |= PIC_NUMERIC; 01189 if (category & PIC_ALPHABETIC) { 01190 goto error; 01191 } 01192 s_count += n; 01193 if (s_count > 1 || idx != 0) { 01194 goto error; 01195 } 01196 s_char_seen = 1; 01197 continue; 01198 01199 case ',': 01200 case '.': 01201 category |= PIC_NUMERIC_EDITED; 01202 if (s_char_seen || p_char_seen) { 01203 goto error; 01204 } 01205 if (c != current_program->decimal_point) { 01206 break; 01207 } 01208 /* fall through */ 01209 case 'V': 01210 category |= PIC_NUMERIC; 01211 if (category & PIC_ALPHABETIC) { 01212 goto error; 01213 } 01214 v_count += n; 01215 if (v_count > 1) { 01216 goto error; 01217 } 01218 break; 01219 01220 case 'P': 01221 category |= PIC_NUMERIC; 01222 if (category & PIC_ALPHABETIC) { 01223 goto error; 01224 } 01225 if (p_char_seen) { 01226 goto error; 01227 } 01228 at_beginning = 0; 01229 at_end = 0; 01230 switch (buffcnt) { 01231 case 0: 01232 /* P..... */ 01233 at_beginning = 1; 01234 break; 01235 case 1: 01236 /* VP.... */ 01237 /* SP.... */ 01238 if (lastonechar == 'V' || lastonechar == 'S') { 01239 at_beginning = 1; 01240 } 01241 break; 01242 case 2: 01243 /* SVP... */ 01244 if (lasttwochar == 'S' && lastonechar == 'V') { 01245 at_beginning = 1; 01246 } 01247 break; 01248 } 01249 if (p[1] == 0 || (p[1] == 'V' && p[2] == 0)) { 01250 /* .....P */ 01251 /* ....PV */ 01252 at_end = 1; 01253 } 01254 if (!at_beginning && !at_end) { 01255 goto error; 01256 } 01257 p_char_seen = 1; 01258 if (at_beginning) { 01259 v_count++; /* implicit V */ 01260 } 01261 digits += n; 01262 if (v_count) { 01263 scale += n; 01264 } else { 01265 scale -= n; 01266 } 01267 break; 01268 01269 case '0': 01270 case 'B': 01271 case '/': 01272 category |= PIC_EDITED; 01273 if (s_char_seen || p_char_seen) { 01274 goto error; 01275 } 01276 break; 01277 01278 case '*': 01279 case 'Z': 01280 category |= PIC_NUMERIC_EDITED; 01281 if (category & PIC_ALPHABETIC) { 01282 goto error; 01283 } 01284 if (s_char_seen || p_char_seen) { 01285 goto error; 01286 } 01287 digits += n; 01288 if (v_count) { 01289 scale += n; 01290 } 01291 break; 01292 01293 case '+': 01294 case '-': 01295 category |= PIC_NUMERIC_EDITED; 01296 if (category & PIC_ALPHABETIC) { 01297 goto error; 01298 } 01299 if (s_char_seen || p_char_seen) { 01300 goto error; 01301 } 01302 digits += n - 1; 01303 s_count++; 01304 /* FIXME: need more check */ 01305 break; 01306 01307 case 'C': 01308 category |= PIC_NUMERIC_EDITED; 01309 if (!(p[1] == 'R' && p[2] == 0)) { 01310 goto error; 01311 } 01312 if (s_char_seen || p_char_seen) { 01313 goto error; 01314 } 01315 p++; 01316 s_count++; 01317 break; 01318 01319 case 'D': 01320 category |= PIC_NUMERIC_EDITED; 01321 if (!(p[1] == 'B' && p[2] == 0)) { 01322 goto error; 01323 } 01324 if (s_char_seen || p_char_seen) { 01325 goto error; 01326 } 01327 p++; 01328 s_count++; 01329 break; 01330 01331 default: 01332 if (c == current_program->currency_symbol) { 01333 category |= PIC_NUMERIC_EDITED; 01334 digits += n - 1; 01335 /* FIXME: need more check */ 01336 break; 01337 } 01338 01339 goto error; 01340 } 01341 01342 /* calculate size */ 01343 if (c != 'V' && c != 'P') { 01344 size += n; 01345 } 01346 if (c == 'C' || c == 'D' || c == 'N') { 01347 size += n; 01348 } 01349 01350 /* store in the buffer */ 01351 buff[idx++] = c; 01352 lasttwochar = lastonechar; 01353 lastonechar = c; 01354 memcpy (&buff[idx], (unsigned char *)&n, sizeof(int)); 01355 idx += sizeof(int); 01356 ++buffcnt; 01357 } 01358 buff[idx] = 0; 01359 01360 if (size == 0 && v_count) { 01361 goto error; 01362 } 01363 /* set picture */ 01364 pic->orig = strdup (str); 01365 pic->size = size; 01366 pic->digits = (unsigned char)digits; 01367 pic->scale = (signed char)scale; 01368 pic->have_sign = (unsigned char)s_count; 01369 01370 /* set picture category */ 01371 switch (category) { 01372 case PIC_ALPHABETIC: 01373 pic->category = CB_CATEGORY_ALPHABETIC; 01374 break; 01375 case PIC_NUMERIC: 01376 pic->category = CB_CATEGORY_NUMERIC; 01377 if (digits > 36) { 01378 cb_error (_("Numeric field cannot be larger than 36 digits")); 01379 } 01380 break; 01381 case PIC_ALPHANUMERIC: 01382 case PIC_NATIONAL: 01383 pic->category = CB_CATEGORY_ALPHANUMERIC; 01384 break; 01385 case PIC_NUMERIC_EDITED: 01386 pic->str = cobc_malloc (idx + 1); 01387 memcpy (pic->str, buff, idx); 01388 pic->category = CB_CATEGORY_NUMERIC_EDITED; 01389 pic->lenstr = idx; 01390 break; 01391 case PIC_EDITED: 01392 case PIC_ALPHABETIC_EDITED: 01393 case PIC_ALPHANUMERIC_EDITED: 01394 case PIC_NATIONAL_EDITED: 01395 pic->str = cobc_malloc (idx + 1); 01396 memcpy (pic->str, buff, idx); 01397 pic->category = CB_CATEGORY_ALPHANUMERIC_EDITED; 01398 pic->lenstr = idx; 01399 break; 01400 default: 01401 goto error; 01402 } 01403 goto end; 01404 01405 error: 01406 cb_error (_("Invalid picture string - '%s'"), str); 01407 01408 end: 01409 return CB_TREE (pic); 01410 } 01411 01412 /* 01413 * Field 01414 */ 01415 01416 cb_tree 01417 cb_build_field (cb_tree name) 01418 { 01419 struct cb_field *p; 01420 01421 p = make_tree (CB_TAG_FIELD, CB_CATEGORY_UNKNOWN, sizeof (struct cb_field)); 01422 p->id = cb_field_id++; 01423 p->name = cb_define (name, CB_TREE (p)); 01424 p->ename = NULL; 01425 p->usage = CB_USAGE_DISPLAY; 01426 p->storage = CB_STORAGE_WORKING; 01427 p->occurs_max = 1; 01428 return CB_TREE (p); 01429 } 01430 01431 cb_tree 01432 cb_build_implicit_field (cb_tree name, int len) 01433 { 01434 cb_tree x; 01435 char pic[32]; 01436 01437 x = cb_build_field (name); 01438 memset (pic, 0, sizeof(pic)); 01439 sprintf (pic, "X(%d)", len); 01440 CB_FIELD (x)->pic = CB_PICTURE (cb_build_picture (pic)); 01441 cb_validate_field (CB_FIELD (x)); 01442 return x; 01443 } 01444 01445 cb_tree 01446 cb_build_constant (cb_tree name, cb_tree value) 01447 { 01448 cb_tree x; 01449 01450 x = cb_build_field (name); 01451 x->category = cb_tree_category (value); 01452 CB_FIELD (x)->storage = CB_STORAGE_CONSTANT; 01453 CB_FIELD (x)->values = cb_list_init (value); 01454 return x; 01455 } 01456 01457 struct cb_field * 01458 cb_field (cb_tree x) 01459 { 01460 if (CB_REFERENCE_P (x)) { 01461 return CB_FIELD (cb_ref (x)); 01462 } else { 01463 return CB_FIELD (x); 01464 } 01465 } 01466 01467 struct cb_field * 01468 cb_field_add (struct cb_field *f, struct cb_field *p) 01469 { 01470 struct cb_field *t; 01471 01472 if (f == NULL) { 01473 return p; 01474 } 01475 for (t = f; t->sister; t = t->sister) { 01476 ; 01477 } 01478 t->sister = p; 01479 return f; 01480 } 01481 01482 int 01483 cb_field_size (cb_tree x) 01484 { 01485 struct cb_reference *r; 01486 struct cb_field *f; 01487 01488 switch (CB_TREE_TAG (x)) { 01489 case CB_TAG_LITERAL: 01490 return CB_LITERAL (x)->size; 01491 case CB_TAG_FIELD: 01492 return CB_FIELD (x)->size; 01493 case CB_TAG_REFERENCE: 01494 r = CB_REFERENCE (x); 01495 f = CB_FIELD (r->value); 01496 01497 if (r->length) { 01498 if (CB_LITERAL_P (r->length)) { 01499 return cb_get_int (r->length); 01500 } else { 01501 return -1; 01502 } 01503 } else if (r->offset) { 01504 if (CB_LITERAL_P (r->offset)) { 01505 return f->size - cb_get_int (r->offset) + 1; 01506 } else { 01507 return -1; 01508 } 01509 } else { 01510 return f->size; 01511 } 01512 default: 01513 fprintf (stderr, "Unexpected tree tag %d\n", CB_TREE_TAG (x)); 01514 ABORT (); 01515 } 01516 /* NOT REACHED */ 01517 return 0; 01518 } 01519 01520 struct cb_field * 01521 cb_field_founder (struct cb_field *f) 01522 { 01523 while (f->parent) { 01524 f = f->parent; 01525 } 01526 return f; 01527 } 01528 01529 struct cb_field * 01530 cb_field_variable_size (struct cb_field *f) 01531 { 01532 struct cb_field *p; 01533 01534 for (f = f->children; f; f = f->sister) { 01535 if (f->occurs_depending) { 01536 return f; 01537 } else if ((p = cb_field_variable_size (f)) != NULL) { 01538 return p; 01539 } 01540 } 01541 return NULL; 01542 } 01543 01544 struct cb_field * 01545 cb_field_variable_address (struct cb_field *f) 01546 { 01547 struct cb_field *p; 01548 01549 for (p = f->parent; p; f = f->parent, p = f->parent) { 01550 for (p = p->children; p != f; p = p->sister) { 01551 if (p->occurs_depending || cb_field_variable_size (p)) { 01552 return p; 01553 } 01554 } 01555 } 01556 return NULL; 01557 } 01558 01559 /* Return 1 if P is subordinate to F */ 01560 01561 int 01562 cb_field_subordinate (struct cb_field *p, struct cb_field *f) 01563 { 01564 for (p = p->parent; p; p = p->parent) { 01565 if (p == f) { 01566 return 1; 01567 } 01568 } 01569 return 0; 01570 } 01571 01572 /* 01573 * File 01574 */ 01575 01576 struct cb_file * 01577 build_file (cb_tree name) 01578 { 01579 struct cb_file *p; 01580 01581 p = make_tree (CB_TAG_FILE, CB_CATEGORY_UNKNOWN, sizeof (struct cb_file)); 01582 p->name = cb_define (name, CB_TREE (p)); 01583 p->cname = to_cname (p->name); 01584 01585 p->organization = COB_ORG_SEQUENTIAL; 01586 p->access_mode = COB_ACCESS_SEQUENTIAL; 01587 p->handler = CB_LABEL (cb_standard_error_handler); 01588 p->handler_prog = current_program; 01589 return p; 01590 } 01591 01592 void 01593 validate_file (struct cb_file *f, cb_tree name) 01594 { 01595 /* check RECORD/RELATIVE KEY clause */ 01596 switch (f->organization) { 01597 case COB_ORG_INDEXED: 01598 if (f->key == NULL) { 01599 file_error (name, "RECORD KEY"); 01600 } 01601 break; 01602 case COB_ORG_RELATIVE: 01603 if (f->key == NULL && f->access_mode != COB_ACCESS_SEQUENTIAL) { 01604 file_error (name, "RELATIVE KEY"); 01605 } 01606 break; 01607 } 01608 } 01609 01610 void 01611 finalize_file (struct cb_file *f, struct cb_field *records) 01612 { 01613 struct cb_field *p; 01614 struct cb_field *v; 01615 cb_tree l; 01616 cb_tree x; 01617 char buff[COB_MINI_BUFF]; 01618 01619 if (f->special) { 01620 f->organization = COB_ORG_LINE_SEQUENTIAL; 01621 } 01622 if (f->fileid_assign && !f->assign) { 01623 f->assign = cb_build_alphanumeric_literal ((unsigned char *)f->name, 01624 strlen (f->name)); 01625 } 01626 01627 /* check the record size if it is limited */ 01628 for (p = records; p; p = p->sister) { 01629 if (f->record_min > 0) { 01630 if (p->size < f->record_min) { 01631 cb_error (_("Record size too small '%s'"), p->name); 01632 } 01633 } 01634 if (f->record_max > 0) { 01635 if (p->size > f->record_max) { 01636 cb_error (_("Record size too large '%s' (%d)"), 01637 p->name, p->size); 01638 } 01639 } 01640 } 01641 01642 /* compute the record size */ 01643 if (f->record_min == 0) { 01644 if (records) { 01645 f->record_min = records->size; 01646 } else { 01647 f->record_min = 0; 01648 } 01649 } 01650 for (p = records; p; p = p->sister) { 01651 v = cb_field_variable_size (p); 01652 if (v && v->offset + v->size * v->occurs_min < f->record_min) { 01653 f->record_min = v->offset + v->size * v->occurs_min; 01654 } 01655 if (p->size < f->record_min) { 01656 f->record_min = p->size; 01657 } 01658 if (p->size > f->record_max) { 01659 f->record_max = p->size; 01660 } 01661 } 01662 01663 if (f->same_clause) { 01664 for (l = current_program->file_list; l; l = CB_CHAIN (l)) { 01665 if (CB_FILE (CB_VALUE (l))->same_clause == f->same_clause) { 01666 if (CB_FILE (CB_VALUE (l))->finalized) { 01667 if (f->record_max > CB_FILE (CB_VALUE (l))->record->memory_size) { 01668 CB_FILE (CB_VALUE (l))->record->memory_size = 01669 f->record_max; 01670 } 01671 f->record = CB_FILE (CB_VALUE (l))->record; 01672 for (p = records; p; p = p->sister) { 01673 p->file = f; 01674 p->redefines = f->record; 01675 } 01676 for (p = f->record->sister; p; p = p->sister) { 01677 if (!p->sister) { 01678 p->sister = records; 01679 break; 01680 } 01681 } 01682 f->finalized = 1; 01683 return; 01684 } 01685 } 01686 } 01687 } 01688 /* create record */ 01689 snprintf (buff, COB_MINI_MAX, "%s_record", f->name); 01690 if (f->record_max == 0) { 01691 f->record_max = 32; 01692 f->record_min = 32; 01693 } 01694 if (f->organization == COB_ORG_LINE_SEQUENTIAL) { 01695 f->record_min = 0; 01696 } 01697 f->record = CB_FIELD (cb_build_implicit_field (cb_build_reference (buff), 01698 f->record_max)); 01699 f->record->sister = records; 01700 f->record->count++; 01701 if (f->external) { 01702 has_external = 1; 01703 f->record->flag_external = 1; 01704 } 01705 01706 for (p = records; p; p = p->sister) { 01707 p->file = f; 01708 p->redefines = f->record; 01709 } 01710 f->finalized = 1; 01711 if (f->linage) { 01712 snprintf (buff, COB_MINI_MAX, "LC_%s", f->name); 01713 x = cb_build_field (cb_build_reference (buff)); 01714 CB_FIELD (x)->pic = CB_PICTURE (cb_build_picture ("9(9)")); 01715 CB_FIELD (x)->usage = CB_USAGE_COMP_5; 01716 CB_FIELD (x)->values = cb_list_init (cb_zero); 01717 CB_FIELD (x)->count++; 01718 cb_validate_field (CB_FIELD (x)); 01719 f->linage_ctr = cb_build_field_reference (CB_FIELD (x), NULL); 01720 current_program->working_storage = 01721 cb_field_add (current_program->working_storage, CB_FIELD (x)); 01722 } 01723 } 01724 01725 /* 01726 * Reference 01727 */ 01728 01729 cb_tree 01730 cb_build_reference (const char *name) 01731 { 01732 struct cb_reference *p; 01733 01734 p = make_tree (CB_TAG_REFERENCE, CB_CATEGORY_UNKNOWN, sizeof (struct cb_reference)); 01735 p->word = lookup_word (name); 01736 return CB_TREE (p); 01737 } 01738 01739 cb_tree 01740 cb_build_filler (void) 01741 { 01742 cb_tree x; 01743 char name[16]; 01744 01745 sprintf (name, "WORK$%d", filler_id++); 01746 x = cb_build_reference (name); 01747 x->source_line = cb_source_line; 01748 return x; 01749 } 01750 01751 cb_tree 01752 cb_build_field_reference (struct cb_field *f, cb_tree ref) 01753 { 01754 cb_tree x; 01755 struct cb_word *word; 01756 01757 x = cb_build_reference (f->name); 01758 word = CB_REFERENCE (x)->word; 01759 if (ref) { 01760 memcpy (x, ref, sizeof (struct cb_reference)); 01761 } 01762 x->category = CB_CATEGORY_UNKNOWN; 01763 CB_REFERENCE (x)->word = word; 01764 CB_REFERENCE (x)->value = CB_TREE (f); 01765 return x; 01766 } 01767 01768 const char * 01769 cb_define (cb_tree name, cb_tree val) 01770 { 01771 struct cb_word *w; 01772 01773 w = CB_REFERENCE (name)->word; 01774 w->items = cb_list_add (w->items, val); 01775 w->count++; 01776 val->source_file = name->source_file; 01777 val->source_line = name->source_line; 01778 CB_REFERENCE (name)->value = val; 01779 return w->name; 01780 } 01781 01782 void 01783 cb_define_system_name (const char *name) 01784 { 01785 cb_tree x; 01786 01787 x = cb_build_reference (name); 01788 if (CB_REFERENCE (x)->word->count == 0) { 01789 cb_define (x, lookup_system_name (name)); 01790 } 01791 } 01792 01793 cb_tree 01794 cb_ref (cb_tree x) 01795 { 01796 struct cb_reference *r; 01797 struct cb_field *p; 01798 struct cb_label *s; 01799 cb_tree candidate = NULL; 01800 cb_tree items; 01801 cb_tree cb1; 01802 cb_tree cb2; 01803 cb_tree v; 01804 cb_tree c; 01805 struct cb_program *prog; 01806 struct cb_word *w; 01807 size_t val; 01808 size_t ambiguous = 0; 01809 01810 r = CB_REFERENCE (x); 01811 /* if this reference has already been resolved (and the value 01812 has been cached), then just return the value */ 01813 if (r->value) { 01814 return r->value; 01815 } 01816 /* resolve the value */ 01817 01818 items = r->word->items; 01819 for (; items; items = CB_CHAIN (items)) { 01820 /* find a candidate value by resolving qualification */ 01821 v = CB_VALUE (items); 01822 c = r->chain; 01823 switch (CB_TREE_TAG (v)) { 01824 case CB_TAG_FIELD: 01825 /* in case the value is a field, it might be qualified 01826 by its parent names and a file name */ 01827 if (CB_FIELD (v)->flag_indexed_by) { 01828 p = CB_FIELD (v)->index_qual; 01829 } else { 01830 p = CB_FIELD (v)->parent; 01831 } 01832 /* resolve by parents */ 01833 for (; p; p = p->parent) { 01834 if (c && strcasecmp (CB_NAME (c), p->name) == 0) { 01835 c = CB_REFERENCE (c)->chain; 01836 } 01837 } 01838 01839 /* resolve by file */ 01840 if (c && CB_REFERENCE (c)->chain == NULL) { 01841 if (CB_REFERENCE (c)->word->count == 1 && CB_FILE_P (cb_ref (c)) 01842 && (CB_FILE (cb_ref (c)) == cb_field_founder (CB_FIELD (v))->file)) { 01843 c = CB_REFERENCE (c)->chain; 01844 } 01845 } 01846 01847 break; 01848 case CB_TAG_LABEL: 01849 /* in case the value is a label, it might be qualified 01850 by its section name */ 01851 s = CB_LABEL (v)->section; 01852 01853 /* unqualified paragraph name referenced within the section 01854 is resolved without ambiguity check if not duplicated */ 01855 if (c == NULL && r->offset && s == CB_LABEL (r->offset)) { 01856 for (cb1 = CB_CHAIN (items); cb1; cb1 = CB_CHAIN (cb1)) { 01857 cb2 = CB_VALUE (cb1); 01858 if (s == CB_LABEL (cb2)->section) { 01859 ambiguous_error (x); 01860 goto error; 01861 } 01862 } 01863 candidate = v; 01864 goto end; 01865 } 01866 01867 /* resolve by section name */ 01868 if (c && s && strcasecmp (CB_NAME (c), (char *)s->name) == 0) { 01869 c = CB_REFERENCE (c)->chain; 01870 } 01871 01872 break; 01873 default: 01874 /* other values cannot be qualified */ 01875 break; 01876 } 01877 01878 /* a well qualified value is a good candidate */ 01879 if (c == NULL) { 01880 if (candidate == NULL) { 01881 /* keep the first candidate */ 01882 candidate = v; 01883 } else { 01884 /* multiple candidates and possibly ambiguous */ 01885 ambiguous = 1; 01886 /* continue search because the reference might not 01887 be ambiguous and exit loop by "goto end" later */ 01888 } 01889 } 01890 } 01891 01892 /* there is no candidate */ 01893 if (candidate == NULL) { 01894 if (current_program->nested_level > 0) { 01895 /* Nested program - check parents for GLOBAL candidate */ 01896 ambiguous = 0; 01897 val = hash ((const unsigned char *)r->word->name); 01898 prog = current_program->next_program; 01899 for (; prog; prog = prog->next_program) { 01900 if (prog->nested_level >= current_program->nested_level) { 01901 continue; 01902 } 01903 for (w = prog->word_table[val]; w; w = w->next) { 01904 if (strcasecmp (r->word->name, w->name) == 0) { 01905 candidate = global_check (r, w->items, &ambiguous); 01906 if (candidate) { 01907 if (ambiguous) { 01908 ambiguous_error (x); 01909 goto error; 01910 } 01911 if (CB_FILE_P(candidate)) { 01912 current_program->gen_file_error = 1; 01913 } 01914 goto end; 01915 } 01916 } 01917 } 01918 if (prog->nested_level == 0) { 01919 break; 01920 } 01921 } 01922 } 01923 undefined_error (x); 01924 goto error; 01925 } 01926 01927 /* the reference is ambiguous */ 01928 if (ambiguous) { 01929 ambiguous_error (x); 01930 goto error; 01931 } 01932 01933 end: 01934 if (CB_FIELD_P (candidate)) { 01935 CB_FIELD (candidate)->count++; 01936 if (CB_FIELD (candidate)->flag_invalid) { 01937 goto error; 01938 } 01939 } 01940 01941 r->value = candidate; 01942 return r->value; 01943 01944 error: 01945 r->value = cb_error_node; 01946 return cb_error_node; 01947 } 01948 01949 /* 01950 * Expression 01951 */ 01952 01953 cb_tree 01954 cb_build_binary_op (cb_tree x, int op, cb_tree y) 01955 { 01956 struct cb_binary_op *p; 01957 enum cb_category category = CB_CATEGORY_UNKNOWN; 01958 01959 switch (op) { 01960 case '+': 01961 case '-': 01962 case '*': 01963 case '/': 01964 case '^': 01965 /* arithmetic operators */ 01966 if (CB_TREE_CLASS (x) == CB_CLASS_POINTER || 01967 CB_TREE_CLASS (y) == CB_CLASS_POINTER) { 01968 category = CB_CATEGORY_DATA_POINTER; 01969 break; 01970 } 01971 x = cb_check_numeric_value (x); 01972 y = cb_check_numeric_value (y); 01973 if (x == cb_error_node || y == cb_error_node) { 01974 return cb_error_node; 01975 } 01976 category = CB_CATEGORY_NUMERIC; 01977 break; 01978 01979 case '=': 01980 case '~': 01981 case '<': 01982 case '>': 01983 case '[': 01984 case ']': 01985 /* relational operators */ 01986 category = CB_CATEGORY_BOOLEAN; 01987 break; 01988 01989 case '!': 01990 case '&': 01991 case '|': 01992 /* logical operators */ 01993 if (CB_TREE_CLASS (x) != CB_CLASS_BOOLEAN || 01994 (y && CB_TREE_CLASS (y) != CB_CLASS_BOOLEAN)) { 01995 cb_error (_("Invalid expression")); 01996 return cb_error_node; 01997 } 01998 category = CB_CATEGORY_BOOLEAN; 01999 break; 02000 02001 case '@': 02002 /* parentheses */ 02003 category = CB_TREE_CATEGORY (x); 02004 break; 02005 02006 default: 02007 fprintf (stderr, "Unexpected operator -> %d\n", op); 02008 ABORT (); 02009 } 02010 02011 p = make_tree (CB_TAG_BINARY_OP, category, sizeof (struct cb_binary_op)); 02012 p->op = op; 02013 p->x = x; 02014 p->y = y; 02015 return CB_TREE (p); 02016 } 02017 02018 cb_tree 02019 cb_build_binary_list (cb_tree l, int op) 02020 { 02021 cb_tree e; 02022 02023 e = CB_VALUE (l); 02024 for (l = CB_CHAIN (l); l; l = CB_CHAIN (l)) { 02025 e = cb_build_binary_op (e, op, CB_VALUE (l)); 02026 } 02027 return e; 02028 } 02029 02030 /* 02031 * Function call 02032 */ 02033 02034 cb_tree 02035 cb_build_funcall (const char *name, int argc, cb_tree a1, cb_tree a2, cb_tree a3, 02036 cb_tree a4, cb_tree a5, cb_tree a6, cb_tree a7) 02037 { 02038 struct cb_funcall *p; 02039 02040 p = make_tree (CB_TAG_FUNCALL, CB_CATEGORY_BOOLEAN, sizeof (struct cb_funcall)); 02041 p->name = name; 02042 p->argc = argc; 02043 p->varcnt = 0; 02044 p->screenptr = gen_screen_ptr; 02045 p->argv[0] = a1; 02046 p->argv[1] = a2; 02047 p->argv[2] = a3; 02048 p->argv[3] = a4; 02049 p->argv[4] = a5; 02050 p->argv[5] = a6; 02051 p->argv[6] = a7; 02052 return CB_TREE (p); 02053 } 02054 02055 /* 02056 * Type cast 02057 */ 02058 02059 cb_tree 02060 cb_build_cast (enum cb_cast_type type, cb_tree val) 02061 { 02062 struct cb_cast *p; 02063 enum cb_category category; 02064 02065 if (type == CB_CAST_INTEGER) { 02066 category = CB_CATEGORY_NUMERIC; 02067 } else { 02068 category = CB_CATEGORY_UNKNOWN; 02069 } 02070 p = make_tree (CB_TAG_CAST, category, sizeof (struct cb_cast)); 02071 p->type = type; 02072 p->val = val; 02073 return CB_TREE (p); 02074 } 02075 02076 /* 02077 * Label 02078 */ 02079 02080 cb_tree 02081 cb_build_label (cb_tree name, struct cb_label *section) 02082 { 02083 struct cb_label *p; 02084 02085 p = make_tree (CB_TAG_LABEL, CB_CATEGORY_UNKNOWN, sizeof (struct cb_label)); 02086 p->id = cb_id++; 02087 p->name = (const unsigned char *)cb_define (name, CB_TREE (p)); 02088 p->orig_name = p->name; 02089 p->section = section; 02090 return CB_TREE (p); 02091 } 02092 02093 /* 02094 * Assign 02095 */ 02096 02097 cb_tree 02098 cb_build_assign (cb_tree var, cb_tree val) 02099 { 02100 struct cb_assign *p; 02101 02102 p = make_tree (CB_TAG_ASSIGN, CB_CATEGORY_UNKNOWN, sizeof (struct cb_assign)); 02103 p->var = var; 02104 p->val = val; 02105 return CB_TREE (p); 02106 } 02107 02108 /* 02109 * INITIALIZE 02110 */ 02111 02112 cb_tree 02113 cb_build_initialize (cb_tree var, cb_tree val, cb_tree rep, cb_tree def, int flag) 02114 { 02115 struct cb_initialize *p; 02116 02117 p = make_tree (CB_TAG_INITIALIZE, CB_CATEGORY_UNKNOWN, sizeof (struct cb_initialize)); 02118 p->var = var; 02119 p->val = val; 02120 p->rep = rep; 02121 p->def = def; 02122 p->flag_statement = flag; 02123 return CB_TREE (p); 02124 } 02125 02126 /* 02127 * SEARCH 02128 */ 02129 02130 cb_tree 02131 cb_build_search (int flag_all, cb_tree table, cb_tree var, cb_tree end_stmt, cb_tree whens) 02132 { 02133 struct cb_search *p; 02134 02135 p = make_tree (CB_TAG_SEARCH, CB_CATEGORY_UNKNOWN, sizeof (struct cb_search)); 02136 p->flag_all = flag_all; 02137 p->table = table; 02138 p->var = var; 02139 p->end_stmt = end_stmt; 02140 p->whens = whens; 02141 return CB_TREE (p); 02142 } 02143 02144 /* 02145 * CALL 02146 */ 02147 02148 cb_tree 02149 cb_build_call (cb_tree name, cb_tree args, cb_tree stmt1, cb_tree stmt2, cb_tree returning, int is_system_call) 02150 { 02151 struct cb_call *p; 02152 02153 p = make_tree (CB_TAG_CALL, CB_CATEGORY_UNKNOWN, sizeof (struct cb_call)); 02154 p->name = name; 02155 p->args = args; 02156 p->stmt1 = stmt1; 02157 p->stmt2 = stmt2; 02158 p->returning = returning; 02159 p->is_system = is_system_call; 02160 return CB_TREE (p); 02161 } 02162 02163 /* 02164 * GO TO 02165 */ 02166 02167 cb_tree 02168 cb_build_goto (cb_tree target, cb_tree depending) 02169 { 02170 struct cb_goto *p; 02171 02172 p = make_tree (CB_TAG_GOTO, CB_CATEGORY_UNKNOWN, sizeof (struct cb_goto)); 02173 p->target = target; 02174 p->depending = depending; 02175 return CB_TREE (p); 02176 } 02177 02178 /* 02179 * IF 02180 */ 02181 02182 cb_tree 02183 cb_build_if (cb_tree test, cb_tree stmt1, cb_tree stmt2) 02184 { 02185 struct cb_if *p; 02186 02187 p = make_tree (CB_TAG_IF, CB_CATEGORY_UNKNOWN, sizeof (struct cb_if)); 02188 p->test = test; 02189 p->stmt1 = stmt1; 02190 p->stmt2 = stmt2; 02191 return CB_TREE (p); 02192 } 02193 02194 /* 02195 * PERFORM 02196 */ 02197 02198 cb_tree 02199 cb_build_perform (int type) 02200 { 02201 struct cb_perform *p; 02202 02203 p = make_tree (CB_TAG_PERFORM, CB_CATEGORY_UNKNOWN, sizeof (struct cb_perform)); 02204 p->type = type; 02205 return CB_TREE (p); 02206 } 02207 02208 cb_tree 02209 cb_build_perform_varying (cb_tree name, cb_tree from, cb_tree by, cb_tree until) 02210 { 02211 struct cb_perform_varying *p; 02212 02213 p = make_tree (CB_TAG_PERFORM_VARYING, CB_CATEGORY_UNKNOWN, sizeof (struct cb_perform_varying)); 02214 p->name = name; 02215 p->from = from; 02216 p->step = name ? cb_build_add (name, by, cb_high) : NULL; 02217 p->until = until; 02218 return CB_TREE (p); 02219 } 02220 02221 /* 02222 * Statement 02223 */ 02224 02225 struct cb_statement * 02226 cb_build_statement (const char *name) 02227 { 02228 struct cb_statement *p; 02229 02230 p = make_tree (CB_TAG_STATEMENT, CB_CATEGORY_UNKNOWN, sizeof (struct cb_statement)); 02231 p->name = name; 02232 return p; 02233 } 02234 02235 /* 02236 * CONTINUE 02237 */ 02238 02239 cb_tree 02240 cb_build_continue (void) 02241 { 02242 struct cb_continue *p; 02243 02244 p = make_tree (CB_TAG_CONTINUE, CB_CATEGORY_UNKNOWN, sizeof (struct cb_continue)); 02245 return CB_TREE (p); 02246 } 02247 02248 /* 02249 * FUNCTION 02250 */ 02251 02252 cb_tree 02253 cb_build_any_intrinsic (cb_tree args) 02254 { 02255 struct cb_intrinsic_table *cbp; 02256 02257 cbp = lookup_intrinsic ("LENGTH", 0); 02258 return make_intrinsic (NULL, cbp, args, NULL, NULL); 02259 } 02260 02261 cb_tree 02262 cb_build_intrinsic (cb_tree name, cb_tree args, cb_tree refmod) 02263 { 02264 struct cb_intrinsic_table *cbp; 02265 cb_tree x; 02266 int numargs; 02267 02268 numargs = cb_list_length (args); 02269 02270 cbp = lookup_intrinsic (CB_NAME (name), 0); 02271 if (cbp) { 02272 if ((cbp->args != -1 && numargs != cbp->args) || 02273 (cbp->args == -1 && cbp->intr_enum != CB_INTR_RANDOM && numargs < 1)) { 02274 cb_error_x (name, _("FUNCTION %s has wrong number of arguments"), cbp->name); 02275 return cb_error_node; 02276 } 02277 if (refmod) { 02278 if (!cbp->refmod) { 02279 cb_error_x (name, _("FUNCTION %s can not have reference modification"), cbp->name); 02280 return cb_error_node; 02281 } 02282 if (CB_LITERAL_P(CB_PAIR_X(refmod)) && 02283 cb_get_int (CB_PAIR_X(refmod))< 1) { 02284 cb_error_x (name, _("FUNCTION %s has invalid reference modification"), cbp->name); 02285 return cb_error_node; 02286 } 02287 if (CB_PAIR_Y(refmod) && CB_LITERAL_P(CB_PAIR_Y(refmod)) && 02288 cb_get_int (CB_PAIR_Y(refmod))< 1) { 02289 cb_error_x (name, _("FUNCTION %s has invalid reference modification"), cbp->name); 02290 return cb_error_node; 02291 } 02292 } 02293 /* cb_tree x; */ 02294 switch (cbp->intr_enum) { 02295 case CB_INTR_LENGTH: 02296 case CB_INTR_BYTE_LENGTH: 02297 x = CB_VALUE (args); 02298 if (CB_INTRINSIC_P (x)) { 02299 return make_intrinsic (name, cbp, args, NULL, NULL); 02300 } else if ((CB_FIELD_P (x) || CB_REFERENCE_P (x)) && 02301 cb_field(x)->flag_any_length) { 02302 return make_intrinsic (name, cbp, args, NULL, NULL); 02303 } else { 02304 return cb_build_length (CB_VALUE (args)); 02305 } 02306 02307 case CB_INTR_WHEN_COMPILED: 02308 if (refmod) { 02309 return make_intrinsic (name, cbp, 02310 cb_list_init (cb_intr_whencomp), NULL, refmod); 02311 } else { 02312 return cb_intr_whencomp; 02313 } 02314 case CB_INTR_PI: 02315 return cb_intr_pi; 02316 case CB_INTR_E: 02317 return cb_intr_e; 02318 02319 case CB_INTR_LOWER_CASE: 02320 case CB_INTR_UPPER_CASE: 02321 case CB_INTR_REVERSE: 02322 /* RXW Why did I do this ? - still do not know 02323 if (CB_INTRINSIC_P (CB_VALUE (args))) { 02324 return make_intrinsic (name, cbp, args, cb_int0); 02325 } else { 02326 return make_intrinsic (name, cbp, args, 02327 cb_build_length (CB_VALUE (args))); 02328 } 02329 RXW */ 02330 02331 case CB_INTR_ABS: 02332 case CB_INTR_ACOS: 02333 case CB_INTR_ANNUITY: 02334 case CB_INTR_ASIN: 02335 case CB_INTR_ATAN: 02336 case CB_INTR_CHAR: 02337 case CB_INTR_COMBINED_DATETIME: 02338 case CB_INTR_COS: 02339 case CB_INTR_CURRENT_DATE: 02340 case CB_INTR_DATE_OF_INTEGER: 02341 case CB_INTR_DAY_OF_INTEGER: 02342 case CB_INTR_EXCEPTION_FILE: 02343 case CB_INTR_EXCEPTION_LOCATION: 02344 case CB_INTR_EXCEPTION_STATUS: 02345 case CB_INTR_EXCEPTION_STATEMENT: 02346 case CB_INTR_EXP: 02347 case CB_INTR_EXP10: 02348 case CB_INTR_FACTORIAL: 02349 case CB_INTR_FRACTION_PART: 02350 case CB_INTR_INTEGER: 02351 case CB_INTR_INTEGER_OF_DATE: 02352 case CB_INTR_INTEGER_OF_DAY: 02353 case CB_INTR_INTEGER_PART: 02354 case CB_INTR_LOCALE_DATE: 02355 case CB_INTR_LOCALE_TIME: 02356 case CB_INTR_LOCALE_TIME_FROM_SECS: 02357 case CB_INTR_LOG: 02358 case CB_INTR_LOG10: 02359 case CB_INTR_MOD: 02360 case CB_INTR_NUMVAL: 02361 case CB_INTR_NUMVAL_C: 02362 case CB_INTR_ORD: 02363 case CB_INTR_REM: 02364 case CB_INTR_SECONDS_FROM_FORMATTED_TIME: 02365 case CB_INTR_SECONDS_PAST_MIDNIGHT: 02366 case CB_INTR_SIGN: 02367 case CB_INTR_SIN: 02368 case CB_INTR_SQRT: 02369 case CB_INTR_STORED_CHAR_LENGTH: 02370 case CB_INTR_TAN: 02371 case CB_INTR_TEST_DATE_YYYYMMDD: 02372 case CB_INTR_TEST_DAY_YYYYDDD: 02373 case CB_INTR_TRIM: 02374 return make_intrinsic (name, cbp, args, NULL, refmod); 02375 02376 case CB_INTR_CONCATENATE: 02377 return make_intrinsic (name, cbp, args, cb_int1, refmod); 02378 case CB_INTR_DATE_TO_YYYYMMDD: 02379 case CB_INTR_DAY_TO_YYYYDDD: 02380 case CB_INTR_MAX: 02381 case CB_INTR_MEAN: 02382 case CB_INTR_MEDIAN: 02383 case CB_INTR_MIDRANGE: 02384 case CB_INTR_MIN: 02385 case CB_INTR_ORD_MAX: 02386 case CB_INTR_ORD_MIN: 02387 case CB_INTR_PRESENT_VALUE: 02388 case CB_INTR_RANDOM: 02389 case CB_INTR_RANGE: 02390 case CB_INTR_STANDARD_DEVIATION: 02391 case CB_INTR_SUM: 02392 case CB_INTR_VARIANCE: 02393 case CB_INTR_YEAR_TO_YYYY: 02394 return make_intrinsic (name, cbp, args, cb_int1, NULL); 02395 case CB_INTR_SUBSTITUTE: 02396 case CB_INTR_SUBSTITUTE_CASE: 02397 if (numargs < 3 || (numargs % 2) == 0) { 02398 cb_error_x (name, _("FUNCTION %s has wrong number of arguments"), cbp->name); 02399 return cb_error_node; 02400 } 02401 return make_intrinsic (name, cbp, args, cb_int1, refmod); 02402 02403 default: 02404 break; 02405 } 02406 } 02407 cb_error_x (name, _("FUNCTION %s not implemented"), CB_NAME (name)); 02408 return cb_error_node; 02409 }