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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #ifdef _KEEP_RCS_ID
00057 static const char source_file[] = __FILE__;
00058 static const char rcs_id[] = "$Source: /depot/CVSROOT/javi/src/sw/cmplr/common/util/flags.c,v $ $Revision: 1.1 $";
00059 #endif
00060
00061 #include <string.h>
00062 #include "defs.h"
00063 #include "flags.h"
00064 #include "erglob.h"
00065 #include "tracing.h"
00066 #include "config.h"
00067
00068 extern char *SBar;
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 INT64
00083 Get_Numeric_Flag (
00084 char **cp,
00085 INT64 min,
00086 INT64 max,
00087 INT64 def,
00088 char *flag
00089 )
00090 {
00091 INT64 val = 0;
00092 INT64 radix = 10;
00093 char c;
00094 BOOL done = FALSE;
00095 BOOL negate = FALSE;
00096
00097
00098 c = **cp;
00099 if (c == '-') {
00100 c = *++(*cp);
00101 negate = TRUE;
00102 }
00103 if ( c < '0' || c > '9' ) return def;
00104
00105
00106 if ( c == '0' ) {
00107 c = *++(*cp);
00108 if ( c == 'x' || c == 'X' ) {
00109 c = *++(*cp);
00110 radix = 16;
00111 } else radix = 8;
00112 }
00113
00114
00115 while ( ! done ) {
00116 switch ( c ) {
00117 case '8':
00118 case '9': if ( radix == 8 ) {
00119 ErrMsg ( EC_Flag_Digit, c, flag );
00120 return def;
00121 }
00122
00123 case '0':
00124 case '1':
00125 case '2':
00126 case '3':
00127 case '4':
00128 case '5':
00129 case '6':
00130 case '7': val = val*radix + (c-'0');
00131 break;
00132 case 'a':
00133 case 'b':
00134 case 'c':
00135 case 'd':
00136 case 'e':
00137 case 'f': if ( radix != 16 ) done = TRUE;
00138 else val = val*radix + 10 + (c-'a');
00139 break;
00140 case 'A':
00141 case 'B':
00142 case 'C':
00143 case 'D':
00144 case 'E':
00145 case 'F': if ( radix != 16 ) done = TRUE;
00146 else val = val*radix + 10 + (c-'A');
00147 break;
00148 default: done = TRUE;
00149 break;
00150 }
00151 if ( ! done ) c = *++(*cp);
00152 }
00153
00154 if (negate) val = -val;
00155
00156
00157 if ( val >= min && val <= max ) return val;
00158 ErrMsg ( EC_Flag_Range, val, min, max, flag );
00159 return def;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 BOOL
00179 Atoi_KMG ( const char* s, INT64* val, BOOL suffix_required )
00180 {
00181 BOOL seen_digit = FALSE;
00182 INT64 v = 0;
00183
00184 for (;;) {
00185 char c;
00186 switch (c = *s++) {
00187 case 'k':
00188 case 'K':
00189 *val = v * 1024;
00190 return seen_digit;
00191 case 'm':
00192 case 'M':
00193 *val = v * (1024 * 1024);
00194 return seen_digit;
00195 case 'g':
00196 case 'G':
00197 *val = v * (1024 * 1024 * 1024);
00198 return seen_digit;
00199 default:
00200 if (c >= '0' && c <= '9') {
00201 v = v*10 + c - '0';
00202 seen_digit = TRUE;
00203 } else {
00204 *val = v;
00205 return seen_digit && (!suffix_required || v == 0);
00206 }
00207 }
00208 }
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 #define ODESC_orig_specified(o) ((o)->aux)
00228 #define ODESC_aux(o) ((ODESC_AUX *)((o)->aux))
00229 #define Set_ODESC_aux(o,a) (((o)->aux)=(ODESC_AUX *)(a))
00230
00231 typedef union optval {
00232 UINT64 i;
00233 void *p;
00234 } OPTVAL;
00235
00236 typedef struct odesc_aux {
00237 INT16 flags;
00238 BOOL *specified;
00239 OPTION_DESC *primary;
00240 OPTVAL orig;
00241 OPTVAL last;
00242 } ODESC_AUX;
00243
00244 #define ODF_SET_USER 0x01
00245 #define ODF_SET_INT 0x02
00246 #define ODF_SET 0x03
00247 #define ODF_MOD_USER 0x04
00248 #define ODF_MOD_INT 0x08
00249 #define ODF_MOD 0x0c
00250 #define ODF_PRINT 0x10
00251 #define ODF_PRINTED 0x20
00252
00253 #define ODA_flags(o) ((o)->flags)
00254 #define ODA_specified(o) ((o)->specified)
00255 #define ODESC_specified(o) ODA_specified(ODESC_aux(o))
00256 #define ODA_primary(o) ((o)->primary)
00257 #define ODESC_primary(o) ODA_primary(ODESC_aux(o))
00258 #define ODA_orig(o) ((o)->orig)
00259 #define ODA_orig_i(o) ((o)->orig.i)
00260 #define ODA_orig_p(o) ((o)->orig.p)
00261 #define ODA_last(o) ((o)->last)
00262 #define ODA_last_i(o) ((o)->last.i)
00263 #define ODA_last_p(o) ((o)->last.p)
00264 #define ODA_set_user(o) (ODA_flags(o) & ODF_SET_USER)
00265 #define Set_ODA_set_user(o) (ODA_flags(o) |= ODF_SET_USER)
00266 #define Reset_ODA_set_user(o) (ODA_flags(o) &= ~ODF_SET_USER)
00267 #define ODA_set_int(o) (ODA_flags(o) & ODF_SET_INT)
00268 #define Set_ODA_set_int(o) (ODA_flags(o) |= ODF_SET_INT)
00269 #define Reset_ODA_set_int(o) (ODA_flags(o) &= ~ODF_SET_INT)
00270 #define Set_ODA_set(o) (ODA_flags(o) |= ODF_SET)
00271 #define ODA_mod_user(o) (ODA_flags(o) & ODF_MOD_USER)
00272 #define Set_ODA_mod_user(o) (ODA_flags(o) |= ODF_MOD_USER)
00273 #define Reset_ODA_mod_user(o) (ODA_flags(o) &= ~ODF_MOD_USER)
00274 #define ODA_mod_int(o) (ODA_flags(o) & ODF_MOD_INT)
00275 #define Set_ODA_mod_int(o) (ODA_flags(o) |= ODF_MOD_INT)
00276 #define Reset_ODA_mod_int(o) (ODA_flags(o) &= ~ODF_MOD_INT)
00277 #define Set_ODA_mod(o) (ODA_flags(o) |= ODF_MOD)
00278 #define ODA_print(o) (ODA_flags(o) & ODF_PRINT)
00279 #define Set_ODA_print(o) (ODA_flags(o) |= ODF_PRINT)
00280 #define Reset_ODA_print(o) (ODA_flags(o) &= ~ODF_PRINT)
00281 #define ODA_printed(o) (ODA_flags(o) & ODF_PRINTED)
00282 #define Set_ODA_printed(o) (ODA_flags(o) |= ODF_PRINTED)
00283 #define Reset_ODA_printed(o) (ODA_flags(o) &= ~ODF_PRINTED)
00284
00285
00286
00287
00288 #define OGROUP_aux(o) ((OGROUP_AUX *)((o)->aux))
00289 #define Set_OGROUP_aux(o,a) (((o)->aux)=(OGROUP_AUX *)(a))
00290
00291 typedef struct ogroup_aux {
00292 mINT16 flags;
00293 mINT16 count;
00294 ODESC_AUX *odesc_aux;
00295 } OGROUP_AUX;
00296
00297 #define OGF_SET 0x01
00298 #define OGF_INTERNAL 0x02
00299
00300 #define OGA_flags(o) ((o)->flags)
00301 #define OGA_count(o) ((o)->count)
00302 #define OGA_odesc_aux(o) ((o)->odesc_aux)
00303 #define OGA_set(o) (OGA_flags(o) & OGF_SET)
00304 #define Set_OGA_set(o) (OGA_flags(o) |= OGF_SET)
00305 #define Reset_OGA_set(o) (OGA_flags(o) &= ~OGF_SET)
00306 #define OGA_internal(o) (OGA_flags(o) & OGF_INTERNAL)
00307 #define Set_OGA_internal(o) (OGA_flags(o) |= OGF_INTERNAL)
00308 #define Reset_OGA_internal(o) (OGA_flags(o) &= ~OGF_INTERNAL)
00309
00310
00311
00312
00313
00314
00315
00316 static INT
00317 Copy_option(OPTION_DESC *odesc, char *container, BOOL save)
00318 {
00319 void *var = ODESC_variable(odesc);
00320 Is_True(ODESC_can_change_by_pragma(odesc),
00321 ("Copy_option, trying to copy option that cannot change"));
00322
00323 if (save) {
00324 switch (ODESC_kind(odesc)) {
00325 case OVK_NONE:
00326 case OVK_BOOL:
00327 *((BOOL *)container) = *((BOOL *)var);
00328 return sizeof(BOOL);
00329 case OVK_INT32:
00330 *((INT32 *)container) = *((INT32 *)var);
00331 return sizeof(INT32);
00332 case OVK_UINT32:
00333 *((UINT32 *)container) = *((UINT32 *)var);
00334 return sizeof(UINT32);
00335 case OVK_INT64:
00336 *((INT64 *)container) = *((INT64 *)var);
00337 return sizeof(INT64);
00338 case OVK_UINT64:
00339 *((UINT64 *)container) = *((UINT64 *)var);
00340 return sizeof(UINT64);
00341 case OVK_NAME:
00342 case OVK_SELF:
00343 *((char **)container) = *((char **)var);
00344 return sizeof(char *);
00345 case OVK_LIST:
00346 *((OPTION_LIST **)container) = *((OPTION_LIST **)var);
00347 return sizeof(OPTION_LIST *);
00348 default:
00349 return 0;
00350 }
00351 } else {
00352 switch (ODESC_kind(odesc)) {
00353 case OVK_NONE:
00354 case OVK_BOOL:
00355 *((BOOL *)var) = *((BOOL *)container);
00356 return sizeof(BOOL);
00357 case OVK_INT32:
00358 *((INT32 *)var) = *((INT32 *)container);
00359 return sizeof(INT32);
00360 case OVK_UINT32:
00361 *((UINT32 *)var) = *((UINT32 *)container);
00362 return sizeof(UINT32);
00363 case OVK_INT64:
00364 *((INT64 *)var) = *((INT64 *)container);
00365 return sizeof(INT64);
00366 case OVK_UINT64:
00367 *((UINT64 *)var) = *((UINT64 *)container);
00368 return sizeof(UINT64);
00369 case OVK_NAME:
00370 case OVK_SELF:
00371 *((char **)var) = *((char **)container);
00372 return sizeof(char *);
00373 case OVK_LIST:
00374 *((OPTION_LIST **)var) = *((OPTION_LIST **)container);
00375 return sizeof(OPTION_LIST *);
00376 default:
00377 return 0;
00378 }
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 static void
00398 Duplicate_Value ( OPTION_DESC *odesc, OPTVAL *container )
00399 {
00400 void *var = ODESC_variable(odesc);
00401
00402 switch ( ODESC_kind(odesc) ) {
00403 case OVK_NONE:
00404 case OVK_BOOL:
00405 container->i = *((BOOL *)var);
00406 break;
00407 case OVK_INT32:
00408 container->i = *((INT32 *)var);
00409 break;
00410 case OVK_UINT32:
00411 container->i = *((UINT32 *)var);
00412 break;
00413 case OVK_INT64:
00414 container->i = *((INT64 *)var);
00415 break;
00416 case OVK_UINT64:
00417 container->i = *((UINT64 *)var);
00418 break;
00419 case OVK_NAME:
00420 case OVK_SELF:
00421 container->p = *((char **)var);
00422 break;
00423 case OVK_LIST:
00424 container->p = *((OPTION_LIST **)var);
00425 break;
00426 default:
00427 break;
00428 }
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 static void
00450 Initialize_Option_Group ( OPTION_GROUP *ogroup )
00451 {
00452 OGROUP_AUX *ogaux;
00453 INT16 count, i;
00454 OPTION_DESC *odesc;
00455 ODESC_AUX *odaux;
00456
00457
00458 if ( OGROUP_aux(ogroup) != NULL ) return;
00459
00460
00461 count = 1;
00462 for ( odesc = OGROUP_options(ogroup);
00463 ODESC_kind(odesc) != OVK_COUNT
00464 && ODESC_kind(odesc) != OVK_OLD_COUNT;
00465 ++odesc )
00466 {
00467 ++count;
00468 }
00469
00470
00471 ogaux = (OGROUP_AUX *) calloc ( 1, sizeof (OGROUP_AUX) );
00472 if ( ogaux == NULL ) {
00473 ErrMsg ( EC_No_Mem, "Initialize_Option_Group: OGROUP_aux" );
00474 }
00475 Set_OGROUP_aux ( ogroup, ogaux );
00476 odaux = (ODESC_AUX *) calloc ( count, sizeof (ODESC_AUX) );
00477 if ( odaux == NULL ) {
00478 ErrMsg ( EC_No_Mem, "Initialize_Option_Group: ODESC_aux" );
00479 }
00480 OGA_odesc_aux(ogaux) = odaux;
00481 OGA_count(ogaux) = count-1;
00482
00483
00484 for ( i = 0, odesc = OGROUP_options(ogroup);
00485 i < count;
00486 ++i, ++odesc, ++odaux )
00487 {
00488 ODA_specified(odaux) = ODESC_orig_specified(odesc);
00489 Set_ODESC_aux ( odesc, odaux );
00490 Duplicate_Value ( odesc, &ODA_orig(odaux) );
00491 ODA_last(odaux) = ODA_orig(odaux);
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 for ( odesc = OGROUP_options(ogroup);
00506 ODESC_kind(odesc) != OVK_COUNT
00507 && ODESC_kind(odesc) != OVK_OLD_COUNT;
00508 ++odesc )
00509 {
00510 if ( ODA_primary ( ODESC_aux(odesc) ) == NULL
00511 && ( ODESC_kind(odesc) == OVK_LIST
00512 || ODESC_kind(odesc) == OVK_NAME
00513 || ODESC_kind(odesc) == OVK_SELF ) )
00514 {
00515 OPTION_DESC *sdesc;
00516
00517 ODA_primary ( ODESC_aux(odesc) ) = odesc;
00518 for ( sdesc = odesc+1;
00519 ODESC_kind(sdesc) != OVK_COUNT
00520 && ODESC_kind(sdesc) != OVK_OLD_COUNT;
00521 ++sdesc )
00522 {
00523 if ( ODESC_variable(sdesc) == ODESC_variable(odesc)
00524 && ODESC_specified(sdesc) == ODESC_specified(odesc) )
00525 {
00526 Set_ODESC_aux ( sdesc, ODESC_aux(odesc) );
00527 }
00528 }
00529 }
00530 }
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 void
00545 Set_Option_Internal ( OPTION_GROUP *ogroup, const char *name )
00546 {
00547 if ( name == NULL ) {
00548 Set_OGA_internal ( OGROUP_aux (ogroup) );
00549 return;
00550 } else {
00551 OPTION_DESC *o;
00552
00553 for ( o = OGROUP_options(ogroup);
00554 ODESC_kind(o) != OVK_COUNT
00555 && ODESC_kind(o) != OVK_OLD_COUNT;
00556 ++o )
00557 {
00558 if ( strcasecmp ( name, ODESC_name(o) ) == 0 ) {
00559 ODESC_visibility(o) = OV_INTERNAL;
00560 }
00561 }
00562 }
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 void
00583 Initialize_Option_Groups ( OPTION_GROUP *ogroups )
00584 {
00585 OPTION_GROUP *group;
00586
00587 for (group = ogroups; group && OGROUP_options(group); group++) {
00588 Initialize_Option_Group ( group );
00589
00590
00591 if ( OGROUP_name(group) == NULL ) break;
00592 }
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 static void
00612 Update_Scalar_Value ( OPTION_DESC *odesc, UINT64 val )
00613 {
00614 void *var = ODESC_variable(odesc);
00615 ODESC_AUX *aux = ODESC_aux(odesc);
00616
00617 if ( val != ODA_last_i(aux) ) {
00618 Set_ODA_mod(aux);
00619 ODA_last_i(aux) = val;
00620 }
00621 Set_ODA_set(aux);
00622
00623 switch ( ODESC_kind(odesc) ) {
00624 case OVK_NONE:
00625 case OVK_BOOL:
00626 *((BOOL *)var) = (BOOL)val;
00627 break;
00628 case OVK_INT32:
00629 *((INT32 *)var) = (INT32)val;
00630 break;
00631 case OVK_UINT32:
00632 *((UINT32 *)var) = (UINT32)val;
00633 break;
00634 case OVK_INT64:
00635 *((INT64 *)var) = (UINT64)val;
00636 break;
00637 case OVK_UINT64:
00638 *((UINT64 *)var) = (UINT64)val;
00639 break;
00640 default:
00641 break;
00642 }
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 static void
00662 Update_Pointer_Value ( OPTION_DESC *odesc, void *val )
00663 {
00664 void **var = (void **)ODESC_variable(odesc);
00665 ODESC_AUX *aux = ODESC_aux(odesc);
00666
00667 if ( val != ODA_last_p(aux) ) {
00668 Set_ODA_mod(aux);
00669 ODA_last_p(aux) = val;
00670 }
00671 Set_ODA_set(aux);
00672 *var = val;
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 BOOL
00685 Process_Command_Line_Group (char *flag, OPTION_GROUP *opt_groups)
00686 {
00687 OPTION_GROUP *group;
00688 char *option, *copy, *cp, *next_cp;
00689 size_t tidx;
00690 char sep[3];
00691 BOOL hasval;
00692 char *val = NULL;
00693 BOOL bval;
00694 INT64 ival;
00695 OPTION_DESC *odesc, *found, *first_found;
00696 OPTION_LIST *olist, *ol;
00697
00698
00699 Initialize_Option_Groups ( opt_groups );
00700
00701
00702 option = NULL;
00703 for (group = opt_groups; group && OGROUP_name(group); group++) {
00704 register INT group_name_len;
00705
00706 if (flag[0] != *OGROUP_name(group))
00707 continue;
00708
00709 group_name_len = strlen(OGROUP_name(group));
00710
00711 if (strncmp(flag, OGROUP_name(group), group_name_len) == 0 &&
00712 flag[group_name_len] == OGROUP_separator(group)) {
00713
00714
00715
00716 option = flag + group_name_len + 1;
00717 break;
00718 }
00719 }
00720
00721
00722 if (option == NULL)
00723 return FALSE;
00724
00725 cp = copy = strdup ( option );
00726 next_cp = cp;
00727
00728
00729 sep[0] = OGROUP_valmarker(group);
00730 sep[1] = OGROUP_separator(group);
00731 sep[2] = 0;
00732
00733 #ifdef Is_True_On
00734
00735
00736
00737 for ( odesc=OGROUP_options(group);
00738 ODESC_kind(odesc) != OVK_COUNT
00739 && ODESC_kind(odesc) != OVK_OLD_COUNT;
00740 odesc++)
00741 {
00742 const char *abbrev = ODESC_abbrev(odesc);
00743 const char *name = ODESC_name(odesc);
00744 Is_True ( abbrev == NULL
00745 || strncmp(abbrev, name, strlen(abbrev)) == 0,
00746 ( "Option group (%s) configuration error: "
00747 "'%s' not prefix of '%s'",
00748 OGROUP_name(group), abbrev, name ) );
00749 }
00750 #endif
00751
00752 while ( next_cp != NULL ) {
00753 char this_flag[256];
00754
00755 cp = next_cp;
00756
00757
00758 tidx = strcspn ( cp, sep );
00759 next_cp = ( cp[tidx] == 0 ) ? NULL : cp+tidx+1;
00760
00761
00762 hasval = ( cp[tidx] == OGROUP_valmarker(group) );
00763 cp[tidx] = 0;
00764 if ( hasval ) {
00765 val = next_cp;
00766
00767 tidx = strcspn ( val, &sep[1] );
00768 next_cp = ( val[tidx] == 0 ) ? NULL : val+tidx+1;
00769 val[tidx] = 0;
00770 }
00771
00772
00773
00774
00775
00776 sprintf(this_flag, "%.50s%c%.100s", OGROUP_name(group),
00777 OGROUP_separator(group), cp);
00778 if (hasval)
00779 sprintf(this_flag+strlen(this_flag), "%c%.100s",
00780 OGROUP_valmarker(group), val);
00781
00782
00783 first_found = found = NULL;
00784 for ( odesc = OGROUP_options(group);
00785 !found
00786 && ODESC_kind(odesc) != OVK_COUNT
00787 && ODESC_kind(odesc) != OVK_OLD_COUNT;
00788 odesc++ )
00789 {
00790
00791
00792
00793
00794
00795
00796 if (!ODESC_abbrev(odesc)) {
00797
00798 if (strcasecmp(cp, ODESC_name(odesc)) == 0) found = odesc;
00799 } else {
00800 INT32 alen = strlen(ODESC_abbrev(odesc));
00801 INT32 clen = strlen(cp);
00802 if (alen == 0) {
00803
00804
00805
00806
00807
00808 if (strncasecmp(cp, ODESC_name(odesc), clen) == 0) {
00809 if (!first_found) first_found = odesc;
00810 else found = odesc;
00811 }
00812 } else {
00813
00814 if (strncasecmp(ODESC_abbrev(odesc), cp, alen) == 0 &&
00815 strncasecmp(cp, ODESC_name(odesc), clen) == 0)
00816 found = odesc;
00817 }
00818 }
00819 }
00820
00821
00822 if (first_found) {
00823 if (found) {
00824 ErrMsg(EC_Ambig_In_Grp, cp, OGROUP_name(group), this_flag);
00825 continue;
00826 }
00827 found = first_found;
00828 }
00829
00830 if ( found == NULL ) {
00831
00832 ErrMsg ( EC_Not_In_Grp, cp, OGROUP_name(group), this_flag );
00833 } else {
00834 ODESC_AUX *aux = ODESC_aux(found);
00835
00836
00837 if ( ODA_specified(aux) ) *ODA_specified(aux) = TRUE;
00838
00839 switch ( ODESC_kind(found) ) {
00840 case OVK_NONE:
00841 if ( hasval ) {
00842 ErrMsg (EC_Inv_Grp_Val, cp, OGROUP_name(group), val,
00843 this_flag);
00844 }
00845 Update_Scalar_Value ( found, (UINT64)TRUE );
00846 break;
00847
00848 case OVK_OBSOLETE:
00849 ErrMsg ( EC_Obsolete_Opt, this_flag );
00850 break;
00851
00852 case OVK_REPLACED:
00853 ErrMsg ( EC_Replaced_Opt, this_flag,
00854 (char *)ODESC_variable(found) );
00855 break;
00856
00857 case OVK_UNIMPLEMENTED:
00858 ErrMsg ( EC_Unimp_Opt, this_flag );
00859 break;
00860
00861 case OVK_BOOL:
00862 if ( hasval ) {
00863 bval = ( strcasecmp ( val, "ON" ) == 0
00864 || strcasecmp ( val, "TRUE" ) == 0
00865 || strcasecmp ( val, "YES" ) == 0
00866 || ( strcasecmp ( val, "OFF" ) != 0
00867 && strcasecmp ( val, "FALSE" ) != 0
00868 && strcasecmp ( val, "NO" ) != 0
00869 && strcmp ( val, "0" ) != 0 ) );
00870 } else {
00871 bval = TRUE;
00872 }
00873 Update_Scalar_Value ( found, (UINT64)bval );
00874 break;
00875
00876 case OVK_INT32:
00877 case OVK_INT64:
00878 case OVK_UINT64:
00879 case OVK_UINT32:
00880 if ( ! hasval ) {
00881 ival = ODESC_def_val(found);
00882 } else {
00883 char *tval = val;
00884 if ((*val < '0' || *val > '9') && *val != '-')
00885 ErrMsg(EC_Flag_Int_Expected, this_flag);
00886 ival = Get_Numeric_Flag ( &tval,
00887 ODESC_min_val(found),
00888 ODESC_max_val(found),
00889 ODESC_def_val(found),
00890 this_flag );
00891 }
00892 Update_Scalar_Value ( found, (UINT64)ival );
00893 break;
00894
00895 #if 0
00896 case OVK_INT64:
00897 case OVK_UINT64:
00898 if ( ODESC_min_val(found) < INT32_MIN ||
00899 ODESC_max_val(found) > INT32_MAX )
00900 {
00901 ErrMsg ( EC_Unimplemented,
00902 "Process_Command_Line_Group: "
00903 "> 32-bit flag values" );
00904 }
00905 if ( ! hasval ) {
00906 ival = ODESC_def_val(found);
00907 } else {
00908 char *tval = val;
00909 if ((*val < '0' || *val > '9') && *val != '-')
00910 ErrMsg(EC_Flag_Int_Expected, this_flag);
00911 ival = Get_Numeric_Flag ( &tval,
00912 ODESC_min_val(found),
00913 ODESC_max_val(found),
00914 ODESC_def_val(found),
00915 this_flag );
00916 }
00917 Update_Scalar_Value ( found, (UINT64)ival );
00918 break;
00919 #endif
00920
00921 case OVK_NAME:
00922 if ( ! hasval ) {
00923 val = "";
00924 }
00925 Update_Pointer_Value ( found, strdup (val) );
00926 break;
00927
00928 case OVK_SELF:
00929 if ( ! hasval ) {
00930 val = cp;
00931 }
00932 Update_Pointer_Value ( found, strdup (val) );
00933 break;
00934
00935 case OVK_LIST:
00936 olist =
00937 (OPTION_LIST *) calloc ( sizeof(OPTION_LIST), 1 );
00938 OLIST_val(olist) = val ? strdup ( val ) : NULL;
00939 OLIST_opt(olist) = ODESC_name(found);
00940 ol = *(OPTION_LIST **)ODESC_variable(found);
00941
00942 if ( ol == NULL ) {
00943 Update_Pointer_Value ( found, olist );
00944
00945 } else {
00946 while ( OLIST_next(ol) != NULL ) ol = OLIST_next(ol);
00947 OLIST_next(ol) = olist;
00948
00949
00950
00951
00952
00953 Set_ODA_mod ( aux );
00954 Set_ODA_set ( aux );
00955 }
00956 break;
00957
00958 default:
00959 break;
00960 }
00961 }
00962 }
00963
00964 free(copy);
00965
00966 return TRUE;
00967 }
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 static BOOL
00986 Modified_Option ( OPTION_DESC *odesc )
00987 {
00988 void *var = ODESC_variable(odesc);
00989 ODESC_AUX *aux = ODESC_aux(odesc);
00990 UINT64 cur;
00991
00992 switch ( ODESC_kind(odesc) ) {
00993 case OVK_NONE:
00994 case OVK_BOOL:
00995 cur = (UINT64)*((BOOL*)var);
00996 break;
00997 case OVK_INT32:
00998 cur = (UINT64)*((INT32*)var);
00999 break;
01000 case OVK_UINT32:
01001 cur = (UINT64)*((UINT32*)var);
01002 break;
01003 case OVK_INT64:
01004 cur = (UINT64)*((INT64*)var);
01005 break;
01006 case OVK_UINT64:
01007 cur = (UINT64)*((UINT64*)var);
01008 break;
01009 case OVK_NAME:
01010 case OVK_SELF:
01011 case OVK_LIST:
01012 return ( *((void**)var) != ODA_last_p(aux) );
01013 default:
01014 break;
01015 }
01016
01017
01018 return ( cur != ODA_last_i(aux) );
01019 }
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048 void
01049 Print_Option_Group ( FILE *tf, OPTION_GROUP *og, const char *prefix,
01050 BOOL internal, BOOL full, BOOL update )
01051 {
01052 OPTION_DESC *desc = OGROUP_options(og);
01053 ODESC_AUX *aux;
01054 OPTION_LIST **this;
01055 OPTION_LIST *list;
01056 BOOL option_set = FALSE;
01057 BOOL visible_option = FALSE;
01058 char *bar = SBar + 12;
01059
01060
01061 if ( !internal && OGA_internal ( OGROUP_aux(og) ) ) return;
01062
01063
01064 for ( desc = OGROUP_options(og);
01065 ODESC_kind(desc) != OVK_COUNT
01066 && ODESC_kind(desc) != OVK_OLD_COUNT;
01067 desc++ )
01068 {
01069 aux = ODESC_aux(desc);
01070 Reset_ODA_printed ( aux );
01071 if ( ( internal
01072 && ( ODA_set_int(aux) || Modified_Option(desc) ) )
01073 || ( ! internal
01074 && ODESC_visibility(desc) != OV_INTERNAL
01075 && ( ODA_set_user(aux) || Modified_Option(desc) ) ) )
01076 {
01077 Set_ODA_print(aux);
01078 option_set = TRUE;
01079 } else {
01080 Reset_ODA_print(aux);
01081 if ( ODESC_visibility(desc) != OV_INTERNAL ) {
01082 visible_option = TRUE;
01083 }
01084 }
01085 }
01086
01087
01088 if ( ! ( option_set || full ) ) return;
01089 if ( ! ( option_set || internal || visible_option ) ) return;
01090
01091
01092 fprintf ( tf, "\n%s%s%s -%s Option Group\n",
01093 prefix, bar, prefix, OGROUP_name(og) );
01094 if ( OGROUP_description(og) != NULL ) {
01095 fprintf ( tf, "%s\t%s\n", prefix, OGROUP_description(og) );
01096 }
01097 fprintf ( tf, "%s%s", prefix, bar );
01098
01099 for ( desc = OGROUP_options(og);
01100 ODESC_kind(desc) != OVK_COUNT
01101 && ODESC_kind(desc) != OVK_OLD_COUNT;
01102 desc++ )
01103 {
01104 char mchar;
01105
01106 aux = ODESC_aux(desc);
01107 if ( ! ODA_print(aux) && ! full ) continue;
01108 if ( ! internal && ODESC_visibility(desc) == OV_INTERNAL ) continue;
01109
01110
01111 if ( ( ! internal && (ODA_mod_user(aux) || Modified_Option(desc) ) )
01112 || ( internal && (ODA_mod_int(aux) || Modified_Option(desc) ) ) )
01113 {
01114 mchar = '#';
01115 } else if ( ( ! internal && ODA_set_user(aux) )
01116 || ( internal && ODA_set_int(aux) ) )
01117 {
01118 mchar = '=';
01119 } else {
01120 mchar = ' ';
01121 }
01122
01123 fprintf ( tf, "%s%c %-20s= ", prefix, mchar, ODESC_name(desc));
01124
01125 switch (ODESC_kind(desc)) {
01126 case OVK_BOOL:
01127 fprintf ( tf, "%s", *((BOOL *) ODESC_variable(desc)) ?
01128 "ON" : "OFF");
01129 break;
01130 case OVK_INT32:
01131 fprintf ( tf, "%d", *((INT32 *) ODESC_variable(desc)));
01132 break;
01133 case OVK_INT64:
01134 fprintf ( tf, "%lld", *((INT64 *) ODESC_variable(desc)));
01135 break;
01136 case OVK_UINT32:
01137 fprintf ( tf, "%u", *((UINT32 *) ODESC_variable(desc)));
01138 break;
01139 case OVK_UINT64:
01140 fprintf ( tf, "%llu", *((UINT64 *) ODESC_variable(desc)));
01141 break;
01142
01143 case OVK_NAME:
01144 case OVK_SELF:
01145
01146
01147
01148
01149 if ( ODESC_primary(desc) == desc
01150 || ODESC_primary(desc) == NULL )
01151 {
01152 #ifdef KEY
01153
01154 char ** var = (char **) ODESC_variable(desc);
01155 if ( *var != NULL )
01156 fprintf ( tf, "%s", *var);
01157 #else
01158 fprintf ( tf, "%s", *((char **) ODESC_variable(desc)));
01159 #endif
01160 } else {
01161 fprintf ( tf, " (See '%s' above)",
01162 ODESC_name(ODESC_primary(desc)) );
01163 }
01164 break;
01165
01166 case OVK_LIST:
01167
01168
01169
01170
01171 if ( ODESC_primary(desc) == desc
01172 || ODESC_primary(desc) == NULL )
01173 {
01174 char sep = ' ';
01175
01176 this = (OPTION_LIST **)ODESC_variable(desc);
01177 for ( list = *this; list != NULL; list = OLIST_next(list) ) {
01178 fprintf ( tf, "%c%s%c%s", sep, OLIST_opt(list),
01179 OGROUP_valmarker(og), OLIST_val(list) );
01180 sep = OGROUP_separator(og);
01181 }
01182 } else {
01183 fprintf ( tf, " (See '%s' above)",
01184 ODESC_name(ODESC_primary(desc)) );
01185 }
01186 break;
01187
01188 default:
01189 break;
01190 }
01191 fprintf ( tf, "\n" );
01192
01193 if ( ODESC_description(desc) != NULL ) {
01194 fprintf ( tf, "%s (%s)\n",
01195 prefix, ODESC_description(desc) );
01196 }
01197 }
01198
01199 fprintf ( tf, "%s%s\n", prefix, bar );
01200
01201 if ( update ) {
01202 for ( desc = OGROUP_options(og);
01203 ODESC_kind(desc) != OVK_COUNT
01204 && ODESC_kind(desc) != OVK_OLD_COUNT;
01205 desc++ )
01206 {
01207 aux = ODESC_aux(desc);
01208 if ( internal ) {
01209 Reset_ODA_set_int(aux);
01210 Reset_ODA_mod_int(aux);
01211 } else {
01212 Reset_ODA_set_user(aux);
01213 Reset_ODA_mod_user(aux);
01214 }
01215 }
01216 }
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231 void
01232 Trace_Option_Group ( FILE *tf, OPTION_GROUP *og, BOOL full )
01233 {
01234 Print_Option_Group ( tf, og, "", TRUE, full, TRUE );
01235 }
01236
01237
01238
01239 void
01240 Trace_Command_Line_Group ( FILE *tf, OPTION_GROUP *og )
01241 {
01242 Print_Option_Group ( tf, og, "", TRUE, FALSE, TRUE );
01243 }
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254 void
01255 Print_Option_Groups ( FILE *tf, OPTION_GROUP *og, const char *prefix,
01256 BOOL internal, BOOL full, BOOL update )
01257 {
01258 while ( OGROUP_name(og) != NULL ) {
01259 Print_Option_Group ( tf, og, prefix, internal, full, update );
01260 ++og;
01261 }
01262 }
01263
01264
01265
01266 void
01267 Trace_Option_Groups ( FILE *tf, OPTION_GROUP *og, BOOL full )
01268 {
01269 Print_Option_Groups ( tf, og, "", TRUE, full, TRUE );
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 OPTION_GROUP *
01284 Get_Command_Line_Group ( OPTION_GROUP *og, const char *name )
01285 {
01286 INT32 i;
01287
01288 for ( i = 0; OGROUP_name(og+i) != NULL; i++ ) {
01289 if ( strcmp ( OGROUP_name(og+i), name ) == 0 ) return og+i;
01290 }
01291 return NULL;
01292 }
01293
01294
01295
01296
01297
01298 #define individual_option(opt, str) \
01299 ODESC_kind(&odesc) = OVK_INT32; \
01300 ODESC_variable(&odesc) = (void *)&opt; \
01301 ODESC_can_change_by_pragma(&odesc) = TRUE; \
01302 incr = Copy_option(&odesc, (char *)(memory+offset), save); \
01303 offset += incr; \
01304 Is_Trace(trace, (TFile, " %s %d: %s (%d bytes)\n", \
01305 save ? "saving" : "restoring", offset, str, incr));
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316 void Save_or_restore_options(char *memory, INT32 size, BOOL save)
01317 {
01318 OPTION_GROUP *ogroups = Common_Option_Groups;
01319 OPTION_GROUP *group;
01320 BOOL trace = Get_Trace(TP_MISC, 0x80);
01321 INT32 incr, offset = 0;
01322
01323 Is_Trace(trace, (TFile, "Save_or_restore_options: %s called\n",
01324 save ? "save" : "restore"));
01325
01326
01327
01328 for (group = ogroups; group && OGROUP_options(group) && OGROUP_name(group);
01329 group++) {
01330 OPTION_DESC *odesc;
01331 OGROUP_AUX *ogaux = OGROUP_aux(group);
01332 ODESC_AUX *odaux = OGA_odesc_aux(ogaux);
01333 INT16 i, count = OGA_count(ogaux);
01334
01335 Is_Trace(trace, (TFile, "group = %s\n", OGROUP_name(group)));
01336
01337
01338 for (i=0, odesc=OGROUP_options(group); i<count; i++, odesc++, odaux++) {
01339
01340 if (ODESC_can_change_by_pragma(odesc)) {
01341 incr = Copy_option(odesc, (char *)(memory+offset), save);
01342 Is_Trace(trace, (TFile, " %s %d: %s (%d bytes)\n",
01343 save ? "saving" : "restoring",
01344 offset, ODESC_name(odesc), incr));
01345 offset += incr;
01346 #ifdef Is_True_On
01347 Is_True(offset < size,
01348 ("OPTIONS_SIZE in options_stack.h needs to be bigger\n"));
01349 #endif
01350 }
01351 }
01352
01353 }
01354
01355
01356
01357 { OPTION_DESC odesc;
01358
01359 Is_Trace(trace, (TFile, "group = Individual Options\n"));
01360
01361
01362 individual_option(Opt_Level, "Opt_Level");
01363 }
01364
01365
01366 Is_Trace(trace, (TFile, "max offset = %d\n", offset));
01367 }