This blog is under construction

Sunday, 3 February 2013

getopt_long_only example in C


Header file:
    getopt.h

Synopsis:
     int getopt_long_only (int argc, char *const *argv, const char *shortopts,
               const struct option *longopts, int indexptr);

Description:
     It is similar to getopt_long but it allows user to represent long option with single hypen (-) or double hypen(--).  Initially, it tries to parse the option with long option and if none of the long option matches, the option is parsed as short option.

Please know about getopt and getopt_long to get better understanding on getopt_long_only.


getopt_long_only function C example


  #include <stdio.h>
  #include <getopt.h>
  #include <string.h>
  #include <stdlib.h>
  static int myflag;
  struct option longopts[] = {
        {"setflag",   optional_argument, &myflag,  1},
        {"clearflag", no_argument,       &myflag,  2},
        {"list",      optional_argument, 0,      'l'},
        {"touch",     required_argument, 0,      'm'},
        {"rm",        required_argument, 0,      'r'},
        {"date",      no_argument,       0,      'd'}
  };

  int main (int argc, char **argv) {
        int i, ch, indexptr = 0, status = 0;
        char str[100];
        opterr = 0;
        while ((ch = getopt_long_only(argc, argv, "l::m:r:d",
                                longopts, &indexptr)) != -1) {
                switch (ch) {
                        case 0:
                                if (*(longopts[indexptr].flag) == 1) {
                                        status = 1;
                                        printf("long opt: %s\n",
                                                longopts[indexptr].name);
                                        printf("U've set status flag\n");
                                } else if (*(longopts[indexptr].flag) == 2) {
                                        status = 0;
                                        printf("long opt: %s\n",
                                                longopts[indexptr].name);
                                        printf("U've unset status flag\n");
                                }
                                break;
                        case 'd':
                                printf("short option - %c  long option - %s\n",
                                        ch, longopts[indexptr].name);
                                system("date");
                                break;
                        case 'l':
                                printf("short option - %c  long option - %s\n",
                                        ch, longopts[indexptr].name);
                                strcpy(str, "ls -l ");
                                if (optarg)
                                        strcat(str, optarg);
                                system(str);
                                break;
                        case 'm':
                                printf("short option - %c  long option - %s\n",
                                        ch, longopts[indexptr].name);
                                strcpy(str, "touch ");
                                strcat(str, optarg);
                                system(str);
                                break;
                        case 'r':
                                printf("short option - %c  long option - %s\n",
                                        ch, longopts[indexptr].name);
                                strcpy(str, "rm ");
                                strcat(str, optarg);
                                system(str);
                                break;
                        case '?':
                                if (optopt == 'r' || optopt == 'm')
                                        printf("Argument is mandatory for --%s\n",
                                                longopts[indexptr].name);
                                else if (isprint (optopt))
                                        printf("U have given an unknown option - %c\n",
                                                optopt);
                                else
                                        printf("Unknown Error-0x%08x\n", optopt);
                                break;
                        default:
                                exit(0);
                }
        }
        for (i = optind; i < argc; i++)
                printf("Redundant argument - %s\n", argv[i]);

        return 0;

  }



  Output:

  jp@jp-VirtualBox:$ ./a.out -setflag --touch file1 --list=file1
  long opt: setflag
  U've set status flag
  short option - m  long option - touch
  short option - l  long option - list
  -rw-r--r-- 1 jp jp 0 2013-02-03 13:16 file1
  jp@jp-VirtualBox:$ ./a.out -clearflag -date
  long opt: clearflag
  U've unset status flag
  short option - d  long option - date
  Sun Feb  3 13:16:35 IST 2013


Note:
If flag is not NULL, getopt_long or getopt_long_only returns 0 on parsing its corresponding long option and the flag will point to the value val in the structure option

static int myflag;
struct option longopt[] {
     {"setflag",    no_argument, &myflag,   9},
     {"clearflag", no_argument, &myflag, 10}
};

./a.out -setflag

In this case, getopt_long_only returns 0 on parsing the long option setflag and the flag "*(longopt[indexptr].flag)" will point to the value of val field (val is '9' here)in the structure option.

No comments:

Post a Comment