home *** CD-ROM | disk | FTP | other *** search
/ cs.rhul.ac.uk / www.cs.rhul.ac.uk.zip / www.cs.rhul.ac.uk / pub / rdp / rdp_cs3470.tar / rdp_supp / arg.c next >
C/C++ Source or Header  |  1998-05-07  |  3KB  |  126 lines

  1. /*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * arg.c - command line argument processing routines
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. *******************************************************************************/
  10. #include <stdlib.h>
  11. #include "arg.h"
  12. #include "memalloc.h"
  13. #include "textio.h"
  14.  
  15. static struct arg_data
  16. {
  17.   enum arg_kind_type kind; 
  18.   char key; 
  19.   char * description; 
  20.   int * intvalue; 
  21.   unsigned long * unsignedvalue; 
  22.   char * * str; 
  23.   struct arg_data * next; 
  24. } * base; 
  25.  
  26. static void add_node(enum arg_kind_type kind, 
  27. char key, 
  28. char * description, 
  29. int * intvalue, 
  30. unsigned long * unsignedvalue, 
  31. char * * str)
  32. {
  33.   struct arg_data * temp; 
  34.   
  35.   /* Create and load argument block */
  36.   temp =(struct arg_data *) mem_calloc(1, sizeof(struct arg_data)); 
  37.   temp->kind = kind; 
  38.   temp->key = key; 
  39.   temp->description = description; 
  40.   temp->intvalue = intvalue; 
  41.   temp->unsignedvalue = unsignedvalue; 
  42.   temp->str = str; 
  43.   temp->next = base; 
  44.   base = temp; 
  45.   
  46. }
  47.  
  48. void arg_message(char * description)
  49. {
  50.   add_node(ARG_BLANK, '\0', description, 0, 0, NULL); 
  51. }
  52.  
  53. void arg_boolean(char key, char * description, int * intvalue)
  54. {
  55.   add_node(ARG_BOOLEAN, key, description, intvalue, 0, NULL); 
  56. }
  57.  
  58. void arg_numeric(char key, char * description, unsigned long * unsignedvalue)
  59. {
  60.   add_node(ARG_NUMERIC, key, description, 0, unsignedvalue, NULL); 
  61. }
  62.  
  63. void arg_string(char key, char * description, char * * str)
  64. {
  65.   add_node(ARG_STRING, key, description, 0, 0, str); 
  66. }
  67.  
  68. /* return an array of filename strings */
  69. char * * arg_process(int argc, char * argv[])
  70. {
  71.   char * * ret =(char * *) mem_calloc(argc, sizeof(char *)); 
  72.   /* There can't be more than argc file descriptors! */
  73.   int file_count = 0; 
  74.   
  75.   while (--argc > 0)
  76.   {
  77.     if ((* ++argv)[0]== '-')  /* switch */
  78.     {
  79.       struct arg_data * temp = base; 
  80.       
  81.       while (temp->next != NULL && temp->key !=(* argv)[1])
  82.         temp = temp->next; 
  83.       
  84.       if (temp->key !=(* argv)[1])
  85.         arg_help("unknown command line argument"); 
  86.       
  87.       switch (temp->kind)
  88.       {
  89.         case ARG_BOOLEAN: 
  90.         *(temp->intvalue)^= 1; 
  91.         break; 
  92.         case ARG_NUMERIC: 
  93.         sscanf(* argv + 2, "%lu", temp->unsignedvalue); 
  94.         break; 
  95.         case ARG_STRING: 
  96.         *(temp->str)= * argv + 2; ; 
  97.         break; 
  98.         default: 
  99.         break; 
  100.       }
  101.     }
  102.     else
  103.       ret[file_count++]= * argv; 
  104.   }
  105.   return ret; 
  106. }
  107.  
  108. static void arg_print(struct arg_data * p)
  109. {
  110.   if (p == NULL)
  111.     return; 
  112.   
  113.   arg_print(p->next); 
  114.   if (p->kind != ARG_BLANK)
  115.     printf("-%c %s ", p->key, p->kind == ARG_NUMERIC ? "<n>": p->kind == ARG_STRING ? "<s>": "   "); 
  116.   printf("%s\n", p->description); 
  117. }
  118.  
  119. void arg_help(char * msg)
  120. {
  121.   printf("\n\nFatal - %s\n\n", msg == NULL ? "": msg); 
  122.   arg_print(base); 
  123.   exit(EXIT_FAILURE); 
  124. }
  125.  
  126.