Advertisement
Guest User

GetOpt.c

a guest
Oct 18th, 2016
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.95 KB | None | 0 0
  1.  
  2. #include "GetOpt.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6.  
  7. // How many argument can each option receive at maximum
  8. #define MAX_NBR_ARGS_PER_OPT 10
  9.  
  10. int GetOpt(int argc, char *argv[], tOptionList optlst)
  11. {
  12.     int err=0;// Will be set to non zero if an error occurs
  13.     int n;// Index to iterate over argv
  14.     int p;// Index to iterate over known options
  15.     int lastopt=0;// 1+index of option in optlst previously found, 0 if no option previously found, -1 for unknown option
  16.  
  17.     // To store all the arguments of an option
  18.     char optsn[2];// Buffer to render option short name into
  19.     int optargc;
  20.     char* optargv[1+(MAX_NBR_ARGS_PER_OPT)];
  21.     optargc=0;
  22.     optargv[optargc]=NULL;
  23.  
  24.     // Iterate over all arguments received by main to check for option match
  25.     for(n=0;n<argc;++n)
  26.     {
  27.         int isopt=0;// 0 for no option found, -1 for unknown option, 1..n for option found, corresponding to its 1+index
  28.         char* firstoptarg=NULL;
  29.         // Check for long options, starting with --
  30.         if(argv[n][0]=='-' && argv[n][1]=='-')
  31.         {
  32.             for(p=0;optlst[p].longopt!=NULL;++p)
  33.             {
  34.                 if(strcasecmp(&argv[n][2],optlst[p].longopt)==0)
  35.                 {
  36.                     if(isopt)
  37.                     {
  38.                         printf("Error: ambiguous option %s\n",argv[n]);
  39.                         ++err;
  40.                     }
  41.                     isopt=1+p;
  42.                 }
  43.             }
  44.             if(!isopt)
  45.             {
  46.                 printf("Error: Unknown long option %s\n",argv[n]);
  47.                 ++err;
  48.                 isopt=-1;
  49.             }
  50.         }
  51.         // Check for short options, starting with - or / and one character long
  52.         if((argv[n][0]=='-' || argv[n][0]=='/') && isalnum((int)argv[n][1]))
  53.         {
  54.             for(p=0;optlst[p].longopt!=NULL;++p)
  55.             {
  56.                 if(argv[n][1]==optlst[p].shortopt)
  57.                 {
  58.                     if(isopt)
  59.                     {
  60.                         printf("Error: ambiguous option %s\n",argv[n]);
  61.                         ++err;
  62.                     }
  63.                     isopt=1+p;
  64.                     if(argv[n][2])
  65.                     {
  66.                         firstoptarg=&argv[n][2];
  67.                     }
  68.                 }
  69.             }
  70.             if(!isopt)
  71.             {
  72.                 printf("Error: Unknown short option %s\n",argv[n]);
  73.                 ++err;
  74.                 isopt=-1;
  75.             }
  76.         }
  77.         // If current argument is an option
  78.         if(isopt)
  79.         {
  80.             if(lastopt && lastopt!=-1)
  81.             {
  82.                 // Take into account previous option if a new option is found
  83.                 (*optlst[lastopt-1].fct)(optargc,optargv);
  84.             }
  85.             // Now that previous opt has been treated, reset opt arg list for the current opt
  86.             optargc=0;
  87.             optargv[optargc]=NULL;
  88.             // First argument is the option name with which it was found
  89.             optargv[optargc++]=optlst[isopt].longopt;
  90.             optargv[optargc]=NULL;
  91.             // If current opt had an arg glued to the option flag
  92.             if(firstoptarg)
  93.             {
  94.                 optargv[optargc++]=firstoptarg;
  95.                 optargv[optargc]=NULL;
  96.             }
  97.             lastopt=isopt;
  98.         }
  99.         else
  100.         {// Not a new option
  101.             if(lastopt && lastopt!=-1)
  102.             {// Store as arg of previous option
  103.                 if(optargc<MAX_NBR_ARGS_PER_OPT)
  104.                 {
  105.                     optargv[optargc++]=argv[n];
  106.                     optargv[optargc]=NULL;
  107.                 }
  108.                 else
  109.                 {
  110.                     printf("Error: Option %s has over %d args, ignoring \"%s\".\n",optlst[lastopt-1].longopt,MAX_NBR_ARGS_PER_OPT,argv[n]);
  111.                     ++err;
  112.                 }
  113.             }
  114.             else
  115.             {
  116.                 if(n>0)// argv[0] is just the name of the program being run, not an option
  117.                 {
  118.                     printf("Error: argument ignored: %s\n",argv[n]);
  119.                     ++err;
  120.                 }
  121.             }
  122.         }
  123.     }
  124.     // We're done iterating over all argv
  125.     if(lastopt && lastopt!=-1)
  126.     {// If we reach end of argument list with an option hanging, treat it
  127.         (*optlst[lastopt-1].fct)(optargc,optargv);
  128.     }
  129.     // If an error occurred, print help
  130.     if(err)
  131.     {
  132.         PrintOptList(optlst);
  133.     }
  134.     return err;
  135. }
  136.  
  137. void PrintOptList(tOptionList optlst)
  138. {
  139.     int p;
  140.     static int wasOptListPrinted=0;
  141.     if(wasOptListPrinted)
  142.         return;
  143.     wasOptListPrinted=1;
  144.     printf("\n");
  145.     printf("List of allowed options:\n");
  146.     for(p=0;optlst[p].longopt!=NULL;++p)
  147.     {
  148.         if(isalnum((int)optlst[p].shortopt))
  149.         {
  150.             printf("-%c --%s : %s\n",optlst[p].shortopt,optlst[p].longopt,optlst[p].description);
  151.         }
  152.         else
  153.         {
  154.             printf("   --%s : %s\n",optlst[p].longopt,optlst[p].description);
  155.         }
  156.     }
  157.     printf("Compiled on the %s at %s\n",__DATE__,__TIME__);
  158.     printf("\n");
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement