📄 opt.c
字号:
break; case VSTRING: s = argnext(ag); if( OPTVALUE(char *,i) != NULL ) free( OPTVALUE(char *,i)); /* if prev. malloc'd */ *((char **)(optlist[i].value)) = (char *)malloc( strlen(s)+1 ); strcpy( OPTVALUE(char *,i) , s ); break; case CSTRING: strncpy( optlist[i].value , argnext(ag), OPT_MAXSTRLEN ); break; case UNDELIMC: case UNDELIMV: opt_fatal("opt_delim: can't process UNDELIM type"); break; default: opt_fatal("opt_delim: don't know this type"); break; } return(1);}/* opt_proc.c *//* * process options in the OPT package */#ifndef SINGLEFILE#include <stdio.h>#include <ctype.h>#ifdef convex#include <strings.h>#else#include <string.h>#endif#ifdef __TURBOC__#include <alloc.h>#include <stdarg.h>#endif#include "ag.h"#include "opt_p.h"static char gstr[160]; /* general purpose global string */#endif /* SINGLEFILE *//****************** * Global variables */char *opt_program_name;flag fileflag = False;char *optfile_name; char *opt_envstring=NULL;char *opt_defstring=NULL;PFI dfilter_fcn=NULL, ufilter_fcn=NULL, verify_fcn=NULL, /* NOTE: this has been disabled ! */ doc_fcn=NULL, quit_fcn=NULL, help_fcn=NULL, run_fcn=NULL;/**************************** * Static Function prototypes */static int line2argv();static int l2a();static flag break_word();static char *Title = NULL;static char *Usage = NULL;/*************************** * set title, usage, etc. * ***************************/voidopt_title_set(s)char *s;{ if(Title != NULL) free(Title); Title = (char *)calloc(strlen(s)+1,sizeof(char)); if(Title == NULL) sprintf(gstr,"opt_title_set: cannot allocate for %s",s), opt_fatal(gstr); strcpy(Title,s);}voidopt_wr_title(){ sprintf(gstr,"%s\n", (Title==NULL ? opt_program_name : Title)); opt_message(gstr);}voidopt_usage_set(s)char *s;{ if(Usage != NULL) free(Usage); Usage = (char *)calloc(strlen(s)+1,sizeof(char)); if(Usage == NULL) sprintf(gstr,"opt_usage_set: cannot allocate for %s",s), opt_fatal(gstr); strcpy(Usage,s);}voidopt_dfilter_set(fcn)PFI fcn;{ extern PFI dfilter_fcn; dfilter_fcn = fcn;}voidopt_ufilter_set(fcn)PFI fcn;{ extern PFI ufilter_fcn; ufilter_fcn = fcn;}voidopt_verify_set(fcn)PFI fcn;{ extern PFI verify_fcn; opt_warning("The verify facility has been disabled!!"); verify_fcn = fcn;}voidopt_quit_set(fcn)PFI fcn;{ extern PFI quit_fcn; quit_fcn = fcn;}voidopt_doc_set(fcn)PFI fcn;{ extern PFI doc_fcn; doc_fcn = fcn;}voidopt_help_setf(fcn)PFI fcn;{ extern PFI help_fcn; help_fcn = fcn;}voidopt_run_set(fcn)PFI fcn;{ extern PFI run_fcn; run_fcn = fcn;}voidopt_env_set(s)char *s;{ extern char *opt_envstring; opt_envstring = s;}voidopt_default_set(s)char *s;{ extern char *opt_defstring; opt_defstring = s;}/* ------------------------------------------------------------------ */ /* ------- */ /* getopts */ /* ------- *//* * this is the routine that is called from main(argc,argv). * returns value of argc. */intgetopts(argc,argv)int argc;char *argv[];{ int nargc; char **nargv; char *short_progname(); char *append_string(); /* * Before processing, set the global variables * opt_program_name : name of routine that is running * optfile_name : default name of options file */ opt_program_name = short_progname(argv[0]); optfile_name = append_string(opt_program_name,OPT_EXT); /* Begin options processing */ /* ------------------------ */ /* First process default string */ opt_lineprocess(opt_defstring); /* Second, check environment variable */ if(opt_envstring != NULL) { char *s; char *getenv(); s = getenv(opt_envstring); opt_lineprocess(s); } /* Finally, parse the command line */ opt_process(argc-1,argv+1); return(argc);}char *append_string(s,t)char *s,*t;{ /* input two strings "s" and "t": * concatenates them to get string "st" * which it allocates space for and returns */ char *st; st = (char *)malloc( strlen(s)+strlen(t)+1 ); strcpy(st,s); strcat(st,t); return(st);}char *short_progname(pname)char *pname;{ char *p; int len; /* * inelegant routine * returns the shortened name of the program named [pname]. * It (recursively) strips off leading directory or drive number * and trailing ".EXE" in the case of MS-DOS executable */ p = pname; while( *p != '/' && *p!='\\' && *p!=':' && *p!='\0' ) ++p; if( *p=='\0') { /* remove .EXE if it exists */ len = strlen(pname); if( len > 4 ) { if( ( 0==strcmp(pname+len-4,".EXE") || 0==strcmp(pname+len-4,".exe") ) ) pname[len-4]='\0'; } return( pname ); } else return( short_progname(++p) );}/* ----------------------------------------------------------------- */ /* ------- */ /* process */ /* ------- *//**************************************************************** * opt_process(): * INPUT: * argc, argv; * * this is the central receiving facility for the options package. * opt_process takes an argument list given by (argc,argv) and * and processes it, * Although the input may come from either of * system command line * options file * interactive command line * the behavior is slightly different if the global menuflag is set */voidopt_process(argc,argv)int argc;char *argv[];{ char c; char *s; int iword; ARGVECTOR agvect,*ag; /* * convert the argument vector (argc,argv) into * an ARGVECTOR structure, to ease manipulations */ if( argc==0 ) return; ag = &agvect; ag_new(argc,argv,ag); if(DEBUG) { ag_fprint(stderr,ag); } /* Loop through the options in the argument vector */ while( !ag_end(ag) ) { if( ag_eow(ag) ) /* if necessary... */ ag_w_advance(ag); /* advance to next word */ if(DEBUG) if( ag->ic != 0 ) /* this should never happen */ opt_warning("opt_process: not on first character"); c=ag_c_advance(ag); /* first character of word */ /* ------ */ /* switch */ /* ------ */ switch( c ) { case DELIM: case ALTDELIM: /* if unadorned "-" */ if( ag_eow(ag) ) { if (!menuflag && !fileflag) { usage(""); /* usage message */ opt_abort_run(); } ag_clear(ag); } /* if "--something" */ else if( ag_c(ag) == c ) { if (!menuflag && !fileflag) { usage(argnext(ag)); opt_abort_run(); } } /* if "-something" */ else { iword = ag_w_number(ag); while( iword==ag_w_number(ag) && !ag_eow(ag) ) opt_delim(ag); } break; case OPTFROMFILE: if(1) { flag tmp_fileflag; tmp_fileflag = fileflag; fileflag = True; opt_fromfname(argnext(ag)); fileflag = tmp_fileflag; } break; case OPTTOFILE: opt_tofname(argnext(ag)); break; case HELPCH: if( !fileflag) opt_help(argnext(ag)); break; case INTERACT: if ( !menuflag ) /* If not called already */ opt_menu(); /* Call the menu */ else /* otherwise */ { menuflag=False; /* turn off menu */ ag_clear(ag); } break; case IGNOREEOL: ag_clear(ag); break; case RUN: if( run_fcn != NULL ) opt_begin_run(run_fcn); else { /* if run_fcn is not set, and 'RUN' is called * from the menu, then exit the menu, so that * the routine is run, and then program will exit */ if ( menuflag ) { menuflag=False; /* turn off menu */ ag_clear(ag); } else { /* RUN called from a file or the command line: * There is no reason to be doing this. */ opt_warning("No Run Function has been registered"); } break; case QUITCH: opt_quit(); break; case BANG: if (!menuflag) opt_warning("Shell can only be invoked from the menu"); else { sprintf(gstr,"Shell to system invalid unless \'%c\'",BANG); strcat(gstr," is the first character in the line\n"); opt_warning(gstr); }#if 0 /* bang...shell to system */ if(1) { char s[160]; strcpy(s,argnext(ag)); system(s); break; }#endif case ' ': /* blanks and empty characters, ignore */ case '\t': case '\0': break; default: /* in the default case, option may be undelimited */ /* ---------------------------------------------- */ ag_backspace(ag); if(DEBUG) { sprintf(gstr, "opt_process: in default section [%s]\n",ag_s(ag)); opt_warning(gstr); } if(1) { char s[80]; strcpy(s,ag_s(ag)); if( opt_undelim(ag) == 0) { sprintf(gstr, "%c (in %s) is invalid delimeter\n", c,s); opt_warning(gstr); } } break; } } }}/*opt_process*//* opt_lineprocess() * process a string, by converting it first into an argument vector * then calling opt_process * return the number of processed arguments */intopt_lineprocess(line)char *line;{ int nargc; char **nargv; if( line==NULL || *line=='\0') return(0); line2argv(&nargc,&nargv,line); opt_process(nargc,nargv); return(nargc);}/* line2argv(): converts a one-line string into an argument vector */static intline2argv(pargc,pargv,line)int *pargc;char ***pargv;char *line;{ char *lincp; if(line==NULL) { *pargc = 0; **pargv = NULL; return(0); } /* * First thing to do is copy the line into * a buffer ("lincp") so that input line will * not be corrupted -- also so that input line * doesn't have to be double null terminated */ lincp = (char *)calloc(strlen(line)+2,sizeof(char)); strcpy(lincp,line); /* * Next step is to double null terminate * the copied line */ lincp[strlen(line)+1]='\0'; /* count words in line */ *pargc = l2a(lincp,NULL); /* allocate array for arg vector */ *pargv = (char **)malloc(((*pargc)+1)*sizeof(char *)); /* fill arg vector with words in line */ l2a(lincp,*pargv); /* * Note that lincp cannot be freed since * that space is used by pargv */ return(*pargc);}#define QUOTE '\"'#define BKSLASH '\\'/* l2a *//* l2a() is slave routine to line2argv() *//* if argv==NULL then count the words in the line *//* if argv!=NULL then put those words into argv[] *//* WARNINGS: * l2a assumes that input line is double-null terminated!! * the line buffer is pointed to by argv[]'s so do not * free the input line buffer */ /* quoted material counts as a single word */ /* so that -s"string with spaces"-g is parsed */ /* into -s string with spaces -g */ /* Comment: should be able to escape with backslash */static intl2a(line,argv)char *line;char **argv;{ flag inquote=False; /* flag: inside quotation */ int iarg; for(iarg=0; *line != '\0'; ++iarg) { if(!inquote) { while( isspace(*line) ) ++line; /* skip leading blank spaces */ if( *line == QUOTE ) { inquote=True; ++line; /* skip past leading quote */ } } if(argv!=NULL) /* point to */ argv[iarg] = line; /* first character of line */ while( !break_word(inquote,line) ) ++line; if( *line==QUOTE ) /* toggle quote */ { inquote = (inquote==True ? False : True ); if(argv==NULL) ++line; /* skip past quote */ } if(argv!=NULL) { *line='\0'; /* Null terminate string */ ++line; /* and go to next character */ } else while( isspace(*line) ) ++line; /* skip trailing blanks */ } return(iarg);}static flagbreak_word(inquote,line)flag inquote;char *line;{ if( *line == '\0' || *line==QUOTE ) return(True); if( !inquote && isspace(*line) ) return(True); return(False);} /* --------------------------- */ /* write out a usage statement */ /* --------------------------- *//* usage("") gives minimal usage message usage("-") gives fuller usage message usage("--") gives output document */static void short_usage();static void long_usage();static void doc_usage();voidusage(s)char *s;{ if (s==NULL || *s=='\0') { short_usage(); sprintf(gstr,"For a list of options, type:\n"), opt_message(gstr); sprintf(gstr,"\t%s %c%c\n",opt_program_name,DELIM,DELIM); doc_usage(); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -