home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / comp_lan / 85_febr / argparse.h < prev    next >
Text File  |  1988-07-25  |  7KB  |  247 lines

  1. /* argparse.h: @(#) macros for parsing command arguments. */
  2. /* by Alexander B. Abacus */
  3. /* Computer Language BBS file name ARGPARSE.H */
  4. /* This and related files make a more portable version of ARGPAR.H */
  5. /* related files: argparse.use, argbegin.h, argloop.h, argend.h */
  6.  
  7. #ifdef Hargsmall
  8.    /* #endfile                  -- this file already included */
  9. #else ! defined Hargparse       /* first inclusion */
  10.  
  11. #define Hargsmall
  12.                                 /* and really include this file */
  13. /*[ A.1 ] Required include. */
  14.  
  15. #ifndef FILE
  16. #include <stdio.h>
  17. #endif ! defined FILE
  18.  
  19. /*[ A.2 ] Output tutorial information. */
  20.  
  21. /* void */ ArgTutor(line)
  22. char ** line;
  23. {
  24.   for ( (line); ((*line) != (char *) 0); (++line) )
  25.   {
  26.     fprintf
  27.     ( stderr
  28.     , " %s"
  29.     , *line
  30.     );
  31.   }
  32.   exit(1);
  33. }
  34.  
  35. /*[ A.3 ] Dummy function for processing positional arguments. */
  36.  
  37. static
  38. char * argPos( a_keyChar, a_argString )
  39. char   a_keyChar;
  40. char * a_argString;
  41. {
  42. #ifdef DriverH
  43.   fprintf ( stderr, "Argument" );
  44.   if ( a_keyChar != '\0' )
  45.   {
  46.     fprintf ( stderr, " key-letter \'%c\'", a_keyChar );
  47.   }
  48.   if ( a_argString != (char *) 0 )
  49.   {
  50.     fprintf ( stderr, " text \"%s\"", a_argString );
  51.   }
  52.   fprintf ( stderr, ".\n" );
  53. #endif DriverH
  54.   return ( (char *) 0 );
  55. }
  56.  
  57. /*[ B.1 ] Standard heading for main(). */
  58.  
  59. #define MAIN() main(argc, argv, envp) int argc; char *argv[]; char *envp[];
  60.  
  61. /*[ B.2 ] Optional macros to override defaults. */
  62.  
  63. #define ArgMin(A_Min)          a0.minPositionals = (A_Min);
  64. #define ArgMax(A_Max)          a0.maxPositionals = (A_Max);
  65. #define ArgPosCall(A_Function) a0.ptrFunction = (A_Function);
  66. #define ArgKeyLeading          a0.keysLeading = 1;
  67. #define ArgTrigger(A_Trigger)  a0.keyTrigger = (A_Trigger);
  68. #define ArgDescription(A_Text) a0.tutorial = (A_Text);
  69.  
  70. /*[ C.1 ] Key-letter flag argument, deferred processing. */
  71.  
  72. #define ArgFlagSet(A_KeyLetter, A_FlagCounter) case A_KeyLetter: ++A_FlagCounter; break;
  73.  
  74. /*[ C.2 ] Key-letter flag argument, immediate processing. */
  75.  
  76. #define ArgFlagCall(A_KeyLetter, A_FlagFunction) case A_KeyLetter: if (A_FlagFunction ( *a0.keyPointer, (char *) 0 ) != (char *) 0 ) { ArgTutor( a0.tutorial ); } break;
  77.  
  78.  
  79. /*[ C.3 ] Key-letter text argument, deferred processing. */
  80.  
  81. #define ArgTextSet(A_KeyLetter, A_TextPointer) \
  82.      case A_KeyLetter: \
  83.        argText \
  84.        ( & A_TextPointer \
  85.        , & a0.keyPointer \
  86.        , & a0.argIndex \
  87.        ,   a0.charIndex \
  88.        ,   a0.keyTrigger \
  89.        ,   a0.argc \
  90.        ,   a0.argVector \
  91.        ,   a0.tutorial \
  92.        ,   A_KeyLetter \
  93.        ,   0 \
  94.        ); \
  95.        break;
  96.  
  97. /*[ C.4 ] Key-letter text argument, immediate processing. */
  98.  
  99. #define ArgTextCall(A_KeyLetter, A_TextFunction) \
  100.      case A_KeyLetter: \
  101.        argText \
  102.        ( & a0.textPointer \
  103.        , & a0.keyPointer \
  104.        , & a0.argIndex \
  105.        ,   a0.charIndex \
  106.        ,   a0.keyTrigger \
  107.        ,   a0.argc \
  108.        ,   a0.argVector \
  109.        ,   a0.tutorial \
  110.        ,   A_KeyLetter \
  111.        ,   A_TextFunction \
  112.        ); \
  113.        break;
  114.  
  115. /*[ D.2 ] Function common for key-letter text arguments. */
  116.  
  117. static /* void */ argText
  118. (       a_textPointer
  119. ,           a_keyPointer
  120. ,               a_argIndex
  121. ,                   a_charIndex
  122. ,                       a_keyTrigger
  123. ,                           a_argc
  124. ,                               a_argv
  125. ,                                   a_tutorial
  126. ,                                      a_keyLetter
  127. ,                                          a_textFunction
  128. )
  129. char ** a_textPointer;
  130. char **     a_keyPointer;
  131. int *           a_argIndex;
  132. int                 a_charIndex;
  133. char                    a_keyTrigger;
  134. int                         a_argc;
  135. char *                          a_argv[];
  136. char *                              a_tutorial[];
  137. char                                   a_keyLetter;
  138. char *                                   (*a_textFunction) ();
  139. { /* argText() */
  140.   if ( a_textFunction == 0 )
  141.   { /* ArgTextSet */
  142.     if ( (* a_textPointer) != (char *) 0 )
  143.     { /* second occurance of this key letter */
  144.       fprintf
  145.       ( stderr
  146.       , " Stop. Repeated key-letter '%c' with text.\n"
  147.       , a_keyLetter
  148.       );
  149.       ArgTutor( a_tutorial );
  150.     } /* second occurance of this key letter */
  151.   } /* ArgTextSet */
  152.  
  153.   if ( a_charIndex != 1 )
  154.   {
  155.     fprintf
  156.     ( stderr
  157.     , " Stop. Key letter with text must stand alone: \"%s\".\n"
  158.     , a_argv[*a_argIndex]
  159.     );
  160.     ArgTutor( & a_tutorial[0] );
  161.   }
  162.   else if ( ( (*a_keyPointer)[1]) != '\0' )
  163.   { /* text following key letter without a separating white space */
  164.     (*a_textPointer) = (char *) & (*a_keyPointer)[1];
  165.   }
  166.   else /* text must be in the following argument */
  167.   {
  168.     ++(*a_argIndex);
  169.     if ( ((*a_argIndex) >= a_argc)
  170.     ||   (a_keyTrigger == *a_argv[*a_argIndex]) )
  171.     { /* text is missing */
  172.       fprintf
  173.       ( stderr
  174.       , " Stop. Text not found after key letter \"%s\".\n"
  175.       , *a_keyPointer
  176.       );
  177.       --(*a_argIndex);
  178.       ArgTutor( & a_tutorial[0] );
  179.     }
  180.     else
  181.     {
  182.       (*a_textPointer) = (char *) a_argv[*a_argIndex];
  183.     } /* endif */
  184.   } /* endif */
  185.  
  186.   if ( a_textFunction != 0 )
  187.   { /* ArgTextCall */
  188.     if((*a_textFunction) ( a_keyLetter, (* a_textPointer) ) != (char *) 0 )
  189.     {
  190.       ArgTutor( a_tutorial );
  191.     }
  192.   } /* ArgTextCall */
  193.  
  194.   (*a_keyPointer) = (char *) 0;       /* to skip to next element of argv */
  195.  
  196.   return;
  197. } /* argText() */
  198.  
  199. /* --------------------------------------------------------------- */
  200.  
  201. #ifdef DriverH
  202.  
  203. /* T.1: Test driver for this include. */
  204.  
  205. static char * tutorial[] =
  206. {
  207. "Expected arguments are: file1 file2 \n",
  208. "   file1 is the source, \n",
  209. "   file2 is the target. \n",
  210. 0
  211. };
  212.  
  213. main(argCount, argVector)
  214. int    argCount;
  215. char * argVector[];
  216. {
  217.   int    f_flag = 0;
  218.   char  *t_text = (char *) 0;
  219.  
  220. #define ArgCount  argCount
  221. #define ArgVector argVector
  222. #include "argbegin.h"
  223.   ArgMin        (1)
  224.   ArgMax        (2)
  225.   ArgDescription(tutorial)
  226. #include "argloop.h"
  227.   ArgFlagSet  ('f', f_flag)
  228.   ArgFlagCall ('F', argPos)
  229.   ArgTextSet  ('t', t_text)
  230.   ArgTextCall ('T', argPos)
  231. #include "argend.h"
  232.  
  233.   fprintf ( stderr, "Flag counter: %d.\n", f_flag );
  234.   if ( t_text != (char *) 0 )
  235.   {
  236.     fprintf ( stderr, "Text: \"%s\".\n", t_text );
  237.   }
  238.  
  239.   exit (0);
  240. } /* main */
  241.  
  242. #endif DriverH
  243.  
  244. #endif Hargsmall
  245.  
  246. /* argparse.h: End of file. */
  247.