general.h File Reference

This header defines macros that provide a simple, C-based method for handling flags. More...

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

Go to the source code of this file.

Defines

#define FALSE   0
#define TRUE   1
#define DO_COMMAND_TAB   " "
#define DO_COMMAND_EOLN   ""
#define SIMPLE_FLAG_OPTN(string, var)   FLAG_OPTN(string, (var) = TRUE)
 Sets var to TRUE on encountering the flag -s (s is an unquoted string of letters and digits).

#define FLAG_OPTN(string, stmt)
 Executes stmt on encountering -s. More...

#define CFLAG_OPTN(char, stmt)
 Like FLAG_OPTN but requires s to be a single character and allows multiple flags to be concatenated (as in ls -AF). More...

#define SIMPLE_CFLAG_OPTN(char, var)   CFLAG_OPTN(char, (var) = 1)
 Like SIMPLE_FLAG_OPTN but requires s to be a single character and allows multiple flags to be concatenated (as in ls -AF).

#define DATA_OPTN(string, desc, stmt)
 Assumes a switch of the form -sdata or -s data, and executes stmt with _OPTION_ set to the start of the data string. More...

#define DATA_OPTN2(string, desc, stmt1, stmt2)
 Assumes a switch of the form -sdata1 data2 or -s data1 data2, and executes stmt1 with _OPTION_ set to the start of the data string and stmt2 with _OPTION_ set to the start of the NEXT data string. More...

#define NON_SWITCH(desc, stmt)
 Executes stmt for the rest of the arguments. More...

#define FREE_ARGS_CONT()
 Ends the argument processing if the given flag is found. More...

#define FREE_ARGS()
 Ends the arguement processing by setting the argc and argv arguments. More...

#define REQ_ARG(desc, stmt)
 Executes stmt for an argument that does not begin with "-". More...

#define OPT_ARG(desc, stmt)
 Executes stmt for an argument that does not begin with "-". More...

#define ANY_OPTION(desc, stmt)
 Executes stmt for any argument. More...

#define COMMAND_LINE_ERROR   { __ACTION__ = 1; continue;}
#define DO_STANDARD_COMMAND_LINE(stmts)
 Processes argv[1..argc-1] according to the (semicolon-separated) statements in stmts. More...


Detailed Description

This header defines macros that provide a simple, C-based method for handling flags.

This macro-based approach works very well for C code, though it can certainly be done better for C++ code.

Author:
Anonymous

Define Documentation

#define ANY_OPTION desc,
stmt   
 

Value:

if (__ACTION__ == 0) { \
    stmt; \
    continue; \
  } \
  else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB,stderr); \
    (void) fputs("" #desc "",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Executes stmt for any argument.

The desc is as for NON_SWITCH. _OPTION_ is set to the argument.

#define CFLAG_OPTN char,
stmt   
 

Value:

if (__ACTION__ == 0 && _OPTION_[1] == (#char)[0]) { \
    __ACTION__ = 2; \
    _OPTION_ += 1; \
  }  \
  if (__ACTION__ == 2 && _OPTION_[0] == (#char)[0]) { \
    {stmt;} \
    continue; \
  } else if (__ACTION__ == 1) { \
    (void) fputs(DO_COMMAND_TAB,stderr); \
    (void) fputs("[-" #char , stderr); \
    __ACTION__ = 3; \
  } else if (__ACTION__ == 3) { \
    (void) fputs(#char, stderr); \
  } else if (__ACTION__ == 5) { \
    __ACTION__ = 4; \
  }
Like FLAG_OPTN but requires s to be a single character and allows multiple flags to be concatenated (as in ls -AF).

#define DATA_OPTN string,
desc,
stmt   
 

Value:

if (__ACTION__ == 0 \
      && strncmp(_OPTION_, "-" #string, sizeof("-" #string) - 1) == 0) { \
    if (_OPTION_[sizeof("-" #string)-1] == '\0') { \
      __i__ += 1; \
      if (__i__ >= argc) __ACTION__ = 1; \
      _OPTION_ = argv[__i__]; \
    } \
    else _OPTION_ += sizeof("-" #string); \
    if (__ACTION__ != 1) {stmt;} \
    continue; \
  } else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB,stderr); \
    (void) fputs("[-" #string #desc "]",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Assumes a switch of the form -sdata or -s data, and executes stmt with _OPTION_ set to the start of the data string.

The desc is used as descriptive text in a "Usage" message.

#define DATA_OPTN2 string,
desc,
stmt1,
stmt2   
 

Value:

if (__ACTION__ == 0 \
      && strncmp(_OPTION_, "-" #string, sizeof("-" #string) - 1) == 0) { \
    if (_OPTION_[sizeof("-" #string)-1] == '\0') { \
      __i__ += 1; \
      if (__i__ >= argc) __ACTION__ = 1; \
      _OPTION_ = argv[__i__]; \
    } \
    else _OPTION_ += sizeof("-" #string); \
    if (__ACTION__ != 1) { \
        stmt1; \
        __i__ += 1; \
        if (__i__ >= argc) \
           __ACTION__ = 1; \
        else { \
           _OPTION_ = argv[__i__]; \
           stmt2; \
           } \
        } \
    continue; \
  } else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB,stderr); \
    (void) fputs("[-" #string #desc "]",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Assumes a switch of the form -sdata1 data2 or -s data1 data2, and executes stmt1 with _OPTION_ set to the start of the data string and stmt2 with _OPTION_ set to the start of the NEXT data string.

The desc is used as descriptive text in a "Usage" message.

#define DO_STANDARD_COMMAND_LINE stmts   
 

Processes argv[1..argc-1] according to the (semicolon-separated) statements in stmts.

Possible statements include

  • SIMPLE_FLAG_OPTN
  • FLAG_OPTN
  • SIMPLE_CFLAG_OPTN
  • CFLAG_OPTN
  • DATA_OPTN
  • DATA_OPTN2
  • REQ_ARG
  • OPT_ARG
  • NON_SWITCH
  • FREE_ARGS
  • FREE_ARGS_CONT
  • ANY_OPTION In case an error is detected, an error message is constructed from the flag names and descriptive text, and the program exits abnormally after printing the message. Within one of the statements, the programmer can cause such an error message and termination with the macro COMMAND_LINE_ERROR.

#define FLAG_OPTN string,
stmt   
 

Value:

if (__ACTION__ == 0) { \
    if (strcmp(_OPTION_, "-" #string) == 0) { \
      {stmt;} \
      continue; \
    } \
  } \
  else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB,stderr);  \
    (void) fputs("[-" #string "]",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Executes stmt on encountering -s.

 
#define FREE_ARGS  
 

Value:

if (__ACTION__ == 6) { \
     int i; \
     for (i=1; i<__i__; i++) \
       argv++; \
     argc -= __i__-1; \
     __ACTION__ = 7; \
  } \
  else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB,stderr); \
    (void) fputs("[argv1 argv2 ...]",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Ends the arguement processing by setting the argc and argv arguments.

These are set so argv[0] has the first free argument.

 
#define FREE_ARGS_CONT  
 

Value:

if (__ACTION__ == 6) { \
     int i; \
     char* tmp = argv[0];\
     for (i=1; i<__i__; i++) \
       argv++; \
     argv[0] = tmp;\
     argc -= __i__-1; \
     __ACTION__ = 7; \
  } \
  else if (__ACTION__ == 1 || __ACTION__ == 4) \
    (void) fputs(DO_COMMAND_EOLN, stderr);
Ends the argument processing if the given flag is found.

The argc and argv arguments are set so argv[1] has the first free argument.

#define NON_SWITCH desc,
stmt   
 

Value:

if (__ACTION__ == 6) { \
     while (__i__ < argc) { \
       _OPTION_ = argv[__i__]; \
       stmt; \
       __i__++; \
       } \
  } \
  else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB,stderr); \
    (void) fputs("[" #desc "...]",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Executes stmt for the rest of the arguments.

Here, desc is used as descriptive text in a "Usage" message. _OPTION_ is set to the argument.

#define OPT_ARG desc,
stmt   
 

Value:

if ((__ACTION__ == 6) && (__i__ < argc)) { \
    stmt; \
    __i__ += 1; \
    if (__i__ < argc) \
       _OPTION_ = argv[__i__]; \
  } \
  else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB,stderr); \
    (void) fputs("[<" #desc ">]",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Executes stmt for an argument that does not begin with "-".

Unlike REQ_ARG, this is an optional argument.

#define REQ_ARG desc,
stmt   
 

Value:

if (__ACTION__ == 6) { \
    if (__i__ >= argc) { \
       __ACTION__ = 1; \
       continue; \
    } \
    stmt; \
    __i__ += 1; \
    if (__i__ < argc) \
       _OPTION_ = argv[__i__]; \
  } \
  else if (__ACTION__ == 1 || __ACTION__ == 4) { \
    (void) fputs(DO_COMMAND_TAB, stderr); \
    (void) fputs("<" #desc ">",stderr); \
    (void) fputs(DO_COMMAND_EOLN, stderr); \
  }
Executes stmt for an argument that does not begin with "-".

Here, desc is used as descriptive text in a "Usage" message. _OPTION_ is set to the argument.