📄 goptions.c
字号:
if(args[j].argnumptr) *args[j].argnumptr = 0; /* reset the # */ break; } } } /* 4th: the bool options, 1 char length, can be clustered */ if(j >= num_args){ if(all_flag_args(argv[i] + 1, args, num_args)){ argtable[i] = OPTION_FLAGS; } } break; } } for(i = 0; i < num_args; i++){ /* now some variables must be */ if(args[i].countflag){ /* initialized */ *((Int32 *) args[i].arglist[0]) = 0; } } /* now step through the command line and process the arguments */ /* of the options with names longer than 1 character */ for(i = 1; i < argc; i++){ idx = argtable[i]; /* get the connection to the option's record */ if(idx != NOT_USED && idx != OPTION_FLAGS){ if(args[idx].argtype == TypeUChar){ /* 1st case: bool option */ if(args[idx].plusopt){ /* +/- Option */ if(argv[i][0] == '+') *((UChar *) args[idx].arglist[0]) = 1; else *((UChar *) args[idx].arglist[0]) = 0; } else{ /* simple -sth - flag */ if(argv[i][0] == '+'){ /* used with +: only warning */ if(! no_msgs) fprintf(stderr, T_("Warning: option `%s' should not be used with a '+'.\n"), args[idx].optname); } *((UChar *) args[idx].arglist[0]) = 1; } continue; /* that's it - bool option has no args */ } if(args[idx].countflag){ /* 2nd case: bool counter option */ (*((Int32 *) args[idx].arglist[0]))++; continue; /* that's it - bool counter option has no args */ } if(args[idx].minargs > 0 || args[idx].maxargs > 0){ j = 0; /* other option with arguments */ argoffset = 1; /* this indicates, whether the 1st argument is */ if(strlen(args[idx].optname) == 1){ /* clutched to the option, */ if(strlen(argv[i] + 1) > 1){ /* what is possible, if the option */ j = 1; /* name is consisting of 1 char. */ argstrings[0] = argv[i] + 2; /* here we have the arg */ argoffset = 0; } } for(; j < args[idx].minargs; j++){ /* these are mandatory */ if(argtable[i + j + argoffset] != NOT_USED){ if(! no_msgs) fprintf(stderr, T_("Error: option `%s' has not enough arguments.\n"), args[argtable[i]].optname); r = -1; CLEANUP; } argstrings[j] = argv[i + j + argoffset]; } for(; j < args[idx].maxargs; j++){ /* these are optional */ if(argtable[i + j + argoffset] != NOT_USED) break; argstrings[j] = argv[i + j + argoffset]; } } used_args = 0; /* count the really used arguments */ for(j = 0; j < args[idx].maxargs; j++){ /* step thru the arguments */ if(argtable[i + j + argoffset] != NOT_USED && j + argoffset > 0) break; /* here we can stop: next option starts */ if(args[idx].argtype == TypeUCharPTR){ /* option wants a string */ *((UChar **) args[idx].arglist[j]) = strdup((UChar *) argstrings[j]); if(! *((UChar **) args[idx].arglist[j])) errexit(errno); } else{ /* option wants a float, int, ... */ n = sscanXValue(argstrings[j], args[idx].arglist[j], args[idx].argtype, NULL); if(n < 1){ /* the argument can't be converted */ if(j >= args[idx].minargs - 1) /* but it's optional */ break; if(! no_msgs) fprintf(stderr, /* critical: the argument is necessary */ T_("Warning: cannot convert `%s' into requested type.\n"), argstrings[j]); break; } } argtable[i + j + argoffset] = argtable[i]; /* mark as used */ if(args[idx].argnumptr) /* increment user's counter */ (*args[idx].argnumptr)++; used_args++; /* increment our own counter */ } if(args[idx].plusopt) /* if a + is allowed: set user's flag */ *args[idx].plusoptptr = (argv[i][0] == '+' ? 1 : 0); else{ if(argv[i][0] == '+') /* if not, but used: just warn user */ if(! no_msgs) fprintf(stderr, T_("Warning: option `%s' should not be used with a '+'.\n"), args[idx].optname); } i += used_args - 1 + argoffset; /* set i to the next option in the */ } /* command line */ } for(i = 1; i < argc; i++){ /* step again through the command line and */ idx = argtable[i]; /* process the boolean options with */ if(idx != OPTION_FLAGS) /* a name with 1 character length */ continue; for(cptr = argv[i] + 1; *cptr; cptr++){ /* step through a cluster */ for(j = 0; j < num_args; j++){ /* of options */ if(strlen(args[j].optname) == 1 && args[j].optname[0] == *cptr && (args[j].argtype == TypeUChar || args[j].countflag)) break; } if(j < num_args){ if(args[j].countflag){ (*((Int32 *) args[j].arglist[0]))++; } else if(args[j].plusopt){ *((UChar *) args[j].arglist[0]) = (argv[i][0] == '+' ? 1 : 0); } else{ if(argv[i][0] == '+'){ if(! no_msgs) fprintf(stderr, T_("Warning: option `%s' should not be used with a '+'.\n"), args[j].optname); } *((UChar *) args[j].arglist[0]) = 1; } } else fprintf(stderr, T_("Internal error: option classified as flag, but not in list.\n")); } } /* look for unprocessed command line arguments, that may */ /* be assigned to non-boolean options with no/empty option names */ for(j = 0; j < num_args; j++){ if(strlen(args[j].optname) == 0 && args[j].argtype != TypeUChar){ if(args[j].argnumptr) *args[j].argnumptr = 0; break; } } if(j < num_args){ /* there are some "absolute" cmd-line args */ nonames = 0; /* this is the counter for them */ for(i = 1; i < argc; i++){ if(nonames >= args[j].maxargs) /* we have enough of them -> stop */ break; if(argtable[i] != NOT_USED) /* this is already in use */ continue; if(args[j].argtype == TypeUCharPTR){ /* we want strings */ *((UChar **)args[j].arglist[nonames]) = strdup(argv[i]); if(! *((UChar **)args[j].arglist[nonames])) errexit(errno); } else{ /* we want some other (float, int ... ) */ n = sscanXValue(argv[i], args[j].arglist[nonames], args[j].argtype, NULL); if(n < 1){ if(unused_args_idx >= 0) /* user wants unused be collected */ continue; if(! no_msgs) fprintf(stderr, T_("Warning: cannot convert `%s' into the requested type.\n"), argv[i]); continue; } } if(args[j].argnumptr) /* increment the users pointer, if present */ (*args[j].argnumptr)++; nonames++; /* increment our pointer of absolute args */ argtable[i] = 1; /* mark the argument as in use (with dummy 1) */ } if(nonames < args[j].minargs){ /* not enough have been found */ if(! no_msgs) fprintf(stderr, T_("Error: not enough absolute arguments (must be%s %ld).\n"), (args[j].minargs < args[j].maxargs ? T_(" at least") : ""), (long int) args[j].minargs); r = -1; CLEANUP; } } for(i = 1, j = 0; i < argc; i++) /* look for unprocessed command */ if(argtable[i] == NOT_USED){ /* line arguments */ j++; n = i; } if(j > 0){ if(unused_args_idx < 0){ if(!no_msgs){ if(j == 1){ /* if any are found: print them out as error msg */ fprintf(stderr, T_("Error: unknown option `%s'.\n"), argv[n]); } else{ fprintf(stderr, T_("Error: %ld unknown options:"), (long int) j); for(i = 1; i < argc; i++) if(argtable[i] == NOT_USED) fprintf(stderr, " %s", argv[i]); fprintf(stderr, "\n"); } } r = -1; CLEANUP; } else{ UChar **unused_args; unused_args = NEWP(UChar *, j + 1); if(! unused_args){ r = errno; GETOUT; } unused_args[j] = NULL; for(i = 0, n = 1; i < j; i++, n++){ while(argtable[n] != NOT_USED) n++; unused_args[i] = strdup(argv[n]); if(! unused_args[i]){ r = errno; for(i--; i >= 0; i--) free(unused_args[i]); free(unused_args); GETOUT; } } *((UChar ***) args[unused_args_idx].arglist[1]) = unused_args; *((Int32 *) args[unused_args_idx].arglist[0]) = j; } } cleanup: if(argtable) /* clean up normally */ free(argtable); if(argstrings) free(argstrings); if(optstring) free(optstring); if(args){ for(i = 0; i < num_args; i++){ if(args[i].optname) free(args[i].optname); if(args[i].arglist) free(args[i].arglist); } free(args); } return(r); getout: /* clean up in case of emergency exit */ r = errno; CLEANUP;}static Int32 /* look in options' record, whether the argstr */all_flag_args( /* 1-char option cluster is regular */ UChar *argstr, struct optdesc *args, Int32 num_args){ Int32 i; Flag this_is_a_flag; if(! *argstr) /* empty -> standalone + or - -> no option cluster */ return(0); while(*argstr){ this_is_a_flag = NO; for(i = 0; i < num_args; i++){ if((args[i].argtype == TypeUChar || args[i].countflag) && strlen(args[i].optname) == 1){ if(*argstr == args[i].optname[0]){ this_is_a_flag = YES; /* option name character is found */ break; } } } if(!this_is_a_flag) /* not found: tilt, game over */ return(0); argstr++; } return(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -