Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "GetOpt.h"
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- // How many argument can each option receive at maximum
- #define MAX_NBR_ARGS_PER_OPT 10
- int GetOpt(int argc, char *argv[], tOptionList optlst)
- {
- int err=0;// Will be set to non zero if an error occurs
- int n;// Index to iterate over argv
- int p;// Index to iterate over known options
- int lastopt=0;// 1+index of option in optlst previously found, 0 if no option previously found, -1 for unknown option
- // To store all the arguments of an option
- char optsn[2];// Buffer to render option short name into
- int optargc;
- char* optargv[1+(MAX_NBR_ARGS_PER_OPT)];
- optargc=0;
- optargv[optargc]=NULL;
- // Iterate over all arguments received by main to check for option match
- for(n=0;n<argc;++n)
- {
- int isopt=0;// 0 for no option found, -1 for unknown option, 1..n for option found, corresponding to its 1+index
- char* firstoptarg=NULL;
- // Check for long options, starting with --
- if(argv[n][0]=='-' && argv[n][1]=='-')
- {
- for(p=0;optlst[p].longopt!=NULL;++p)
- {
- if(strcasecmp(&argv[n][2],optlst[p].longopt)==0)
- {
- if(isopt)
- {
- printf("Error: ambiguous option %s\n",argv[n]);
- ++err;
- }
- isopt=1+p;
- }
- }
- if(!isopt)
- {
- printf("Error: Unknown long option %s\n",argv[n]);
- ++err;
- isopt=-1;
- }
- }
- // Check for short options, starting with - or / and one character long
- if((argv[n][0]=='-' || argv[n][0]=='/') && isalnum((int)argv[n][1]))
- {
- for(p=0;optlst[p].longopt!=NULL;++p)
- {
- if(argv[n][1]==optlst[p].shortopt)
- {
- if(isopt)
- {
- printf("Error: ambiguous option %s\n",argv[n]);
- ++err;
- }
- isopt=1+p;
- if(argv[n][2])
- {
- firstoptarg=&argv[n][2];
- }
- }
- }
- if(!isopt)
- {
- printf("Error: Unknown short option %s\n",argv[n]);
- ++err;
- isopt=-1;
- }
- }
- // If current argument is an option
- if(isopt)
- {
- if(lastopt && lastopt!=-1)
- {
- // Take into account previous option if a new option is found
- (*optlst[lastopt-1].fct)(optargc,optargv);
- }
- // Now that previous opt has been treated, reset opt arg list for the current opt
- optargc=0;
- optargv[optargc]=NULL;
- // First argument is the option name with which it was found
- optargv[optargc++]=optlst[isopt].longopt;
- optargv[optargc]=NULL;
- // If current opt had an arg glued to the option flag
- if(firstoptarg)
- {
- optargv[optargc++]=firstoptarg;
- optargv[optargc]=NULL;
- }
- lastopt=isopt;
- }
- else
- {// Not a new option
- if(lastopt && lastopt!=-1)
- {// Store as arg of previous option
- if(optargc<MAX_NBR_ARGS_PER_OPT)
- {
- optargv[optargc++]=argv[n];
- optargv[optargc]=NULL;
- }
- else
- {
- printf("Error: Option %s has over %d args, ignoring \"%s\".\n",optlst[lastopt-1].longopt,MAX_NBR_ARGS_PER_OPT,argv[n]);
- ++err;
- }
- }
- else
- {
- if(n>0)// argv[0] is just the name of the program being run, not an option
- {
- printf("Error: argument ignored: %s\n",argv[n]);
- ++err;
- }
- }
- }
- }
- // We're done iterating over all argv
- if(lastopt && lastopt!=-1)
- {// If we reach end of argument list with an option hanging, treat it
- (*optlst[lastopt-1].fct)(optargc,optargv);
- }
- // If an error occurred, print help
- if(err)
- {
- PrintOptList(optlst);
- }
- return err;
- }
- void PrintOptList(tOptionList optlst)
- {
- int p;
- static int wasOptListPrinted=0;
- if(wasOptListPrinted)
- return;
- wasOptListPrinted=1;
- printf("\n");
- printf("List of allowed options:\n");
- for(p=0;optlst[p].longopt!=NULL;++p)
- {
- if(isalnum((int)optlst[p].shortopt))
- {
- printf("-%c --%s : %s\n",optlst[p].shortopt,optlst[p].longopt,optlst[p].description);
- }
- else
- {
- printf(" --%s : %s\n",optlst[p].longopt,optlst[p].description);
- }
- }
- printf("Compiled on the %s at %s\n",__DATE__,__TIME__);
- printf("\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement