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 #pragma ident "@(#) libf/fort/argchck.c 92.3 10/29/99 21:41:49"
00043 #include <liberrno.h>
00044 #include <stdio.h>
00045 #include <string.h>
00046
00047 #if defined(_UNICOS)
00048 extern int _who_called_me();
00049 #endif
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 enum arg_type_values {
00086 Null_Arg,
00087 Short_Integer_Arg,
00088 Long_Integer_Arg,
00089 Real_Arg,
00090 Double_Arg,
00091 Complex_Arg,
00092 Logical_Arg,
00093 Character_Arg,
00094 Pointer_Arg,
00095 Typeless_Arg,
00096 Character_Pointer_Arg,
00097 Label_Arg,
00098 Subroutine_Arg,
00099 Null_Function_Arg,
00100 Short_Integer_Function_Arg,
00101 Long_Integer_Function_Arg,
00102 Real_Function_Arg,
00103 Double_Function_Arg,
00104 Complex_Function_Arg,
00105 Logical_Function_Arg,
00106 Character_Function_Arg,
00107 Pointer_Function_Arg,
00108 Typeless_Function_Arg,
00109 Character_Pointer_Function_Arg,
00110 Subprogram_Arg,
00111 Derived_Type_Arg,
00112 Derived_Type_Function_Arg };
00113
00114 typedef enum arg_type_values arg_type_type;
00115
00116 struct arg_desc_header {
00117 unsigned int seen_this :1;
00118 unsigned int f90_flag :1;
00119 unsigned int num_ck_only :1;
00120 unsigned int suppress_msg :1;
00121 unsigned int unused1 :4;
00122 #if defined(_UNICOS)
00123 unsigned int unused2 :24;
00124 unsigned int unused3 :8;
00125 #endif
00126 unsigned int arg_count :24;
00127 };
00128
00129 typedef struct arg_desc_header arg_desc_header_type;
00130
00131 struct arg_desc_node {
00132 long arg_type;
00133 long kind;
00134
00135
00136
00137 long size;
00138 long char_len;
00139 long rank;
00140 long line;
00141 char name[32];
00142 #if defined(_UNICOS)
00143 unsigned int unused2 :32;
00144 #endif
00145 unsigned int unused1 :18;
00146 unsigned int pgm_unknown :1;
00147 unsigned int pgm_unit :1;
00148 unsigned int ignore_tkr :1;
00149 unsigned int dope_vector :1;
00150 unsigned int pointer :1;
00151 unsigned int default_kind :1;
00152 unsigned int optional :1;
00153 unsigned int intent_out :1;
00154 unsigned int assumed_shape :1;
00155 unsigned int assumed_size_array :1;
00156 unsigned int assumed_size_char :1;
00157 unsigned int defineable :1;
00158 unsigned int array_element :1;
00159 unsigned int generic_call :1;
00160 long *derived_type_tbl;
00161 };
00162
00163 typedef struct arg_desc_node arg_desc_node_type;
00164
00165
00166 #define SUBROUTINE_ATYPE 12
00167 #define SUBPROGRAM_ATYPE 24
00168 #define MAX_ENT_LEN 32
00169
00170 static char *(arg_msg[27]) = {
00171 "NULL",
00172 "SHORT INTEGER",
00173 "LONG INTEGER",
00174 "REAL",
00175 "DOUBLE",
00176 "COMPLEX",
00177 "LOGICAL",
00178 "CHARACTER",
00179 "POINTER",
00180 "TYPELESS",
00181 "CHARACTER POINTER",
00182 "LABEL",
00183 "SUBROUTINE",
00184 "NULL FUNCTION",
00185 "SHORT INTEGER FUNCTION",
00186 "LONG INTEGER FUNCTION",
00187 "REAL FUNCTION",
00188 "DOUBLE FUNCTION",
00189 "COMPLEX FUNCTION",
00190 "LOGICAL FUNCTION",
00191 "CHARACTER FUNCTION",
00192 "POINTER FUNCTION",
00193 "TYPELESS FUNCTION",
00194 "CHARACTER POINTER FUNCTION",
00195 "SUBPROGRAM",
00196 "DERIVED TYPE",
00197 "DERIVED TYPE FUNCTION" };
00198
00199 static int _check_derived_type(long *, long *);
00200
00201 static int _suppress_message(long);
00202 static long *_a_suppress_msg_list;
00203 static long *_d_suppress_msg_list;
00204
00205 #ifdef _UNICOS
00206 #pragma _CRI duplicate _ARGCHCK as $ARGCHCK
00207 #endif
00208
00209 static void issue_msg();
00210
00211 int _ARGCHCK(long **argdes, long **dargdes)
00212 {
00213 int i, k, traced;
00214 char name[MAX_ENT_LEN];
00215 char callee[MAX_ENT_LEN];
00216 long lineno;
00217 arg_desc_header_type *a_header;
00218 arg_desc_header_type *d_header;
00219 arg_desc_node_type *a_node;
00220 arg_desc_node_type *d_node;
00221 int arg_counts_match = 1;
00222 int generic_call = 0;
00223 long *long_ptr;
00224
00225 traced = 0;
00226 a_header = (arg_desc_header_type *)argdes;
00227 d_header = (arg_desc_header_type *)dargdes;
00228
00229 _a_suppress_msg_list = NULL;
00230 _d_suppress_msg_list = NULL;
00231
00232 argdes++;
00233 dargdes++;
00234 a_node = (arg_desc_node_type *)*argdes;
00235 d_node = (arg_desc_node_type *)*dargdes;
00236
00237 if (a_header->f90_flag && d_header->f90_flag) {
00238 strcpy(callee, a_node->name);
00239 strcpy(name, d_node->name);
00240 lineno = a_node->line;
00241 traced = 1;
00242 }
00243
00244
00245
00246 if (a_header->seen_this == 0) {
00247
00248
00249
00250 a_header->seen_this = 1;
00251
00252 if (a_header->f90_flag && a_header->suppress_msg) {
00253 _a_suppress_msg_list = (long *)argdes;
00254 _a_suppress_msg_list += a_header->arg_count + 1;
00255 }
00256
00257 if (d_header->f90_flag && d_header->suppress_msg) {
00258 _d_suppress_msg_list = (long *)dargdes;
00259 _d_suppress_msg_list += d_header->arg_count + 1;
00260 }
00261
00262 if (a_header->arg_count != d_header->arg_count) {
00263
00264
00265 issue_msg(FWNUMARG, a_header->arg_count,
00266 d_header->arg_count, 0, &traced, callee, name,
00267 &lineno);
00268 arg_counts_match = 0;
00269 }
00270
00271 if ((a_header->f90_flag && a_header->num_ck_only) ||
00272 (d_header->f90_flag && d_header->num_ck_only)) {
00273 goto EXIT;
00274 }
00275
00276
00277 if (a_node->arg_type != d_node->arg_type) {
00278 issue_msg(FWFUNTYP, a_node->arg_type, d_node->arg_type,
00279 0, &traced, callee, name, &lineno);
00280 } else if (a_header->f90_flag && d_header->f90_flag) {
00281 if (a_node->generic_call) {
00282 generic_call = 1;
00283 }
00284
00285
00286 if ((a_node->arg_type != Subroutine_Arg) &&
00287 (a_node->arg_type != Subprogram_Arg)) {
00288
00289
00290
00291
00292 if (a_node->kind != d_node->kind) {
00293 issue_msg(FWFUNKTP, a_node->kind,
00294 d_node->kind, 0, &traced,
00295 callee, name, &lineno);
00296 }
00297
00298
00299 if (a_node->pointer && (!d_node->pointer)) {
00300 issue_msg(FWFUNNPT, 0, 0, 0, &traced,
00301 callee, name, &lineno);
00302 } else if ((!a_node->pointer) &&
00303 d_node->pointer) {
00304 issue_msg(FWFUNPTR, 0, 0, 0, &traced,
00305 callee, name, &lineno);
00306 } else if (a_node->rank != d_node->rank) {
00307 issue_msg(FWFUNRNK, a_node->rank,
00308 d_node->rank, 0, &traced,
00309 callee, name, &lineno);
00310 } else if ((d_node->rank != 0 ) &&
00311 (a_node->size != d_node->size)) {
00312 issue_msg(FWFUNSIZ, a_node->size,
00313 d_node->size, 0, &traced,
00314 callee, name, &lineno);
00315 }
00316
00317
00318 if ((a_node->arg_type ==
00319 Character_Function_Arg) &&
00320 (a_node->char_len != d_node->char_len) &&
00321 (!d_node->assumed_size_char)) {
00322 issue_msg(FWFUNCHL, a_node->char_len,
00323 d_node->char_len, 0, &traced,
00324 callee, name, &lineno);
00325 }
00326
00327
00328 if (a_node->arg_type ==
00329 Derived_Type_Function_Arg) {
00330
00331 if (!_check_derived_type(
00332 a_node->derived_type_tbl,
00333 d_node->derived_type_tbl)) {
00334 issue_msg(FWFUNDVT, 0, 0, 0,
00335 &traced, callee, name,
00336 &lineno);
00337 }
00338 }
00339 }
00340 }
00341
00342 if (arg_counts_match) {
00343 k = a_header->arg_count;
00344 i = 0;
00345 argdes++;
00346 dargdes++;
00347 a_node = (arg_desc_node_type *)*argdes;
00348 d_node = (arg_desc_node_type *)*dargdes;
00349
00350 while (++i <= k) {
00351
00352 if (a_node == NULL) {
00353
00354
00355
00356
00357 if ((!d_header->f90_flag) ||
00358 (!d_node->optional)) {
00359 issue_msg(FWARGOPT, 0, 0,
00360 i, &traced, callee,
00361 name, &lineno);
00362 }
00363 } else if (a_node->pgm_unit && d_node->pgm_unit) {
00364 if (! a_node->pgm_unknown &&
00365 ! d_node->pgm_unknown &&
00366 a_node->arg_type != d_node->arg_type &&
00367 ! d_node->ignore_tkr) {
00368 issue_msg(FWARGTYP,
00369 a_node->arg_type,
00370 d_node->arg_type, i,
00371 &traced, callee, name,
00372 &lineno);
00373 }
00374 } else if (a_node->arg_type != d_node->arg_type &&
00375 ! d_node->ignore_tkr &&
00376 ! (a_node->arg_type == Typeless_Arg &&
00377 (d_node->arg_type == Short_Integer_Arg ||
00378 d_node->arg_type == Long_Integer_Arg ||
00379 d_node->arg_type == Real_Arg ||
00380 d_node->arg_type == Double_Arg ||
00381 d_node->arg_type == Complex_Arg ||
00382 d_node->arg_type == Logical_Arg ||
00383 d_node->arg_type == Character_Arg))) {
00384
00385 if ((a_node->arg_type !=
00386 Subprogram_Arg) &&
00387 (d_node->arg_type != Subprogram_Arg)) {
00388 issue_msg(FWARGTYP,
00389 a_node->arg_type,
00390 d_node->arg_type, i,
00391 &traced, callee, name,
00392 &lineno);
00393 } else if ((a_node->arg_type ==
00394 Subprogram_Arg) &&
00395 (d_node->arg_type !=
00396 Derived_Type_Function_Arg) &&
00397 ((d_node->arg_type <
00398 Subroutine_Arg) ||
00399 (d_node->arg_type >
00400 Subprogram_Arg))) {
00401 issue_msg(FWARGTYP,
00402 a_node->arg_type,
00403 d_node->arg_type,
00404 i, &traced, callee,
00405 name, &lineno);
00406 } else if ((d_node->arg_type ==
00407 Subprogram_Arg) &&
00408 (a_node->arg_type !=
00409 Derived_Type_Function_Arg) &&
00410 ((a_node->arg_type <
00411 Subroutine_Arg) ||
00412 (a_node->arg_type >
00413 Subprogram_Arg))) {
00414 issue_msg(FWARGTYP,
00415 a_node->arg_type,
00416 d_node->arg_type,
00417 i, &traced, callee,
00418 name, &lineno);
00419 }
00420 } else if (a_header->f90_flag &&
00421 d_header->f90_flag) {
00422
00423
00424
00425 if ((a_node->arg_type ==
00426 Derived_Type_Arg) ||
00427 (a_node->arg_type ==
00428 Derived_Type_Function_Arg)) {
00429
00430
00431 if (! d_node->ignore_tkr &&
00432 !_check_derived_type(
00433 a_node->derived_type_tbl,
00434 d_node->derived_type_tbl)) {
00435 issue_msg(FWARGDVT, 0, 0,
00436 i, &traced, callee,
00437 name, &lineno);
00438 }
00439 } else if (a_node->arg_type != Typeless_Arg &&
00440 a_node->kind != d_node->kind &&
00441 ! d_node->ignore_tkr) {
00442 issue_msg(FWARGKTP, a_node->kind,
00443 d_node->kind, i,
00444 &traced, callee, name,
00445 &lineno);
00446 }
00447
00448 if (d_node->intent_out &&
00449 (!a_node->defineable)) {
00450 issue_msg(FWARGOUT, 0, 0, i,
00451 &traced, callee, name,
00452 &lineno);
00453 }
00454
00455 if (d_node->pointer) {
00456 if (!a_node->pointer) {
00457 issue_msg(FWARGPTR, 0, 0,
00458 i, &traced,
00459 callee, name,
00460 &lineno);
00461 } else {
00462 if (a_node->rank !=
00463 d_node->rank &&
00464 ! d_node->ignore_tkr) {
00465 issue_msg(FWARGRNK,
00466 a_node->rank,
00467 d_node->rank,
00468 i, &traced,
00469 callee, name,
00470 &lineno);
00471 }
00472 if ((a_node->arg_type ==
00473 Character_Arg) &&
00474 ! d_node->ignore_tkr &&
00475 (a_node->char_len !=
00476 d_node->char_len)) {
00477 issue_msg(FWARGPCL,
00478 a_node->char_len,
00479 d_node->char_len,
00480 i, &traced,
00481 callee, name,
00482 &lineno);
00483 }
00484 }
00485 } else if (d_node->assumed_shape) {
00486 if (!a_node->dope_vector) {
00487 issue_msg(FWARGASS, 0, 0, i,
00488 &traced, callee, name,
00489 &lineno);
00490 } else {
00491 if (a_node->rank !=
00492 d_node->rank &&
00493 ! d_node->ignore_tkr) {
00494 issue_msg(FWARGRNK,
00495 a_node->rank,
00496 d_node->rank,
00497 i, &traced,
00498 callee, name,
00499 &lineno);
00500 }
00501 if ((a_node->arg_type ==
00502 Character_Arg) &&
00503 (!d_node->assumed_size_char) &&
00504 (! d_node->ignore_tkr) &&
00505 (a_node->char_len !=
00506 d_node->char_len)) {
00507 issue_msg(FWARGPCL,
00508 a_node->char_len,
00509 d_node->char_len,
00510 i, &traced,
00511 callee, name,
00512 &lineno);
00513 }
00514 }
00515 } else if ((d_node->rank == 0) &&
00516 (a_node->rank != 0) &&
00517 (! d_node->ignore_tkr)) {
00518 issue_msg(FWARGSCA, 0, 0, i,
00519 &traced, callee, name,
00520 &lineno);
00521 } else if (a_node->arg_type == Character_Arg &&
00522 ! d_node->ignore_tkr) {
00523
00524
00525 if (d_node->rank == 0) {
00526 if (d_node->char_len >
00527 a_node->char_len) {
00528 issue_msg(FWARGCHL,
00529 a_node->char_len,
00530 d_node->char_len,
00531 i, &traced,
00532 callee, name,
00533 &lineno);
00534 }
00535 } else if ((a_node->rank == 0) &&
00536 (!a_node->array_element)) {
00537 issue_msg(FWARGARS, 0, 0,
00538 i, &traced,
00539 callee, name,
00540 &lineno);
00541 } else if ((!d_node->assumed_size_array) &&
00542 (!a_node->assumed_size_array)) {
00543 if (d_node->size > a_node->size &&
00544 ! a_node->array_element) {
00545 issue_msg(FWARGSIZ,
00546 a_node->size,
00547 d_node->size, i,
00548 &traced, callee,
00549 name, &lineno);
00550 }
00551 }
00552 } else if (d_node->rank > 0 &&
00553 ! d_node->ignore_tkr) {
00554 if ((a_node->rank == 0) &&
00555 (! a_node->array_element)) {
00556 issue_msg(FWARGARS, 0, 0, i,
00557 &traced, callee, name,
00558 &lineno);
00559 } else if ((!d_node->assumed_size_array) &&
00560 (!a_node->assumed_size_array) &&
00561 (! a_node->array_element) &&
00562 (d_node->size > a_node->size)) {
00563 issue_msg(FWARGSIZ,
00564 a_node->size,
00565 d_node->size,
00566 i, &traced, callee,
00567 name, &lineno);
00568 }
00569 }
00570 }
00571 argdes++;
00572 dargdes++;
00573 a_node = (arg_desc_node_type *)*argdes;
00574 d_node = (arg_desc_node_type *)*dargdes;
00575 }
00576 }
00577 }
00578
00579 EXIT:
00580 return(0);
00581 }
00582
00583
00584 static void
00585 issue_msg(which, nnum, dnum, indx, traced, nm1, nm2, lineno)
00586 long which, nnum, dnum, indx, *traced, *lineno;
00587 char *nm1, *nm2;
00588 {
00589 int l1, l2, temp;
00590
00591 if (_suppress_message(which)) {
00592 return;
00593 }
00594
00595 if (*traced == 0) {
00596
00597 *traced = 1;
00598
00599 #if defined(_UNICOS)
00600 l1 = _who_called_me(lineno, nm1, MAX_ENT_LEN, 3);
00601 #else
00602 l1 = -1;
00603 #endif
00604
00605 if (l1 < 0) {
00606 nm1[0] = '?';
00607 nm1[1] = '?';
00608 nm1[2] = '?';
00609 l1 = 3;
00610 }
00611
00612 #if defined(_UNICOS)
00613 l2 = _who_called_me(&temp, nm2, MAX_ENT_LEN, 2);
00614 #else
00615 l2 = -1;
00616 #endif
00617
00618 if (l2 < 0) {
00619 nm2[0] = '?';
00620 nm2[1] = '?';
00621 nm2[2] = '?';
00622 l2 = 3;
00623 }
00624
00625
00626
00627 nm1[l1] = '\0';
00628 nm2[l2] = '\0';
00629
00630 }
00631
00632 switch (which) {
00633
00634 case FWNUMARG:
00635 (void) _fwarn(which, nm2, nm1, *lineno, nnum, dnum);
00636 break;
00637
00638 case FWARGTYP:
00639 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00640 arg_msg[nnum], arg_msg[dnum]);
00641 break;
00642
00643 case FWFUNTYP:
00644 (void) _fwarn(which, nm2, nm1, *lineno, nm2,
00645 arg_msg[nnum], nm2, arg_msg[dnum]);
00646 break;
00647
00648 case FWFUNKTP:
00649 (void) _fwarn(which, nm2, nm1, *lineno, nm2,
00650 nnum, nm2, dnum);
00651 break;
00652
00653 case FWFUNRNK:
00654 (void) _fwarn(which, nm2, nm1, *lineno, nm2,
00655 nnum, nm2, dnum);
00656 break;
00657
00658 case FWFUNSIZ:
00659 (void) _fwarn(which, nm2, nm1, *lineno, nm2,
00660 nnum, nm2, dnum);
00661 break;
00662
00663 case FWFUNCHL:
00664 (void) _fwarn(which, nm2, nm1, *lineno, nm2,
00665 nnum, nm2, dnum);
00666 break;
00667
00668 case FWFUNDVT:
00669 (void) _fwarn(which, nm2, nm1, *lineno);
00670 break;
00671
00672 case FWFUNNPT:
00673 (void) _fwarn(which, nm2, nm1, *lineno, nm2);
00674 break;
00675
00676 case FWFUNPTR:
00677 (void) _fwarn(which, nm2, nm1, *lineno, nm2);
00678 break;
00679
00680 case FWARGOPT:
00681 (void) _fwarn(which, nm2, nm1, *lineno, indx);
00682 break;
00683
00684 case FWARGKTP:
00685 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00686 nnum, dnum);
00687 break;
00688
00689 case FWARGDVT:
00690 (void) _fwarn(which, nm2, nm1, *lineno, indx);
00691 break;
00692
00693 case FWARGOUT:
00694 (void) _fwarn(which, nm2, nm1, *lineno, indx);
00695 break;
00696
00697 case FWARGPTR:
00698 (void) _fwarn(which, nm2, nm1, *lineno, indx);
00699 break;
00700
00701 case FWARGRNK:
00702 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00703 nnum, dnum);
00704 break;
00705
00706 case FWARGPCL:
00707 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00708 nnum, dnum);
00709 break;
00710
00711 case FWARGASS:
00712 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00713 indx);
00714 break;
00715
00716 case FWARGSCA:
00717 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00718 indx);
00719 break;
00720
00721 case FWARGCHL:
00722 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00723 nnum, dnum);
00724 break;
00725
00726 case FWARGARS:
00727 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00728 indx);
00729 break;
00730
00731 case FWARGSIZ:
00732 (void) _fwarn(which, nm2, nm1, *lineno, indx,
00733 nnum, dnum);
00734 break;
00735
00736 default:
00737 break;
00738 }
00739
00740 return;
00741 }
00742
00743 static int
00744 _check_derived_type( long *a_struct,
00745 long *d_struct)
00746 {
00747 int count;
00748 int i;
00749 int result = 1;
00750
00751 if (a_struct[0] != d_struct[0])
00752 result = 0;
00753 else {
00754 count = a_struct[0];
00755
00756 for (i = 1; i < count; i++) {
00757 if (a_struct[i] != d_struct[i]) {
00758 result = 0;
00759 break;
00760 }
00761 }
00762 }
00763 return(result);
00764 }
00765
00766 static int
00767 _suppress_message(long message_number)
00768
00769 {
00770 int i;
00771 int result = 0;
00772
00773 if (_a_suppress_msg_list != NULL) {
00774 i = 0;
00775 while (_a_suppress_msg_list[i] != 0) {
00776 if (_a_suppress_msg_list[i] == message_number) {
00777 result = 1;
00778 break;
00779 }
00780 i++;
00781 }
00782 }
00783
00784 if (result == 0 &&
00785 _d_suppress_msg_list != NULL) {
00786 i = 0;
00787 while (_d_suppress_msg_list[i] != 0) {
00788 if (_d_suppress_msg_list[i] == message_number) {
00789 result = 1;
00790 break;
00791 }
00792 i++;
00793 }
00794 }
00795
00796 return(result);
00797 }
00798