ARGS.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:5k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include "cmdline.h"
  25. /*
  26.  * This module handles command line arguments.  The main program defines
  27.  * an array specifying what arguments are allowed and what the activity
  28.  * should be for each argument and then calls parse_args giving it
  29.  * argv and argc as arguments.  Parse-args dispatches any arguments it
  30.  * finds to the action routine and then deletes the argument it found
  31.  * from argv[]
  32.  */
  33. /*
  34.  * The main program must define this array.  It customizes the types of
  35.  * arguments that will be allowed
  36.  *
  37.  */
  38. extern ARGLIST ArgList[];
  39. static BOOL use_case; /* Gets set for case sensitivity */
  40. /* 
  41.  * Function that unlinks the argument from che argv[] chain
  42.  */
  43. static void remove_arg(int pos, int *count, char *list[])
  44. {
  45.   int i;
  46.   /* Decrement length of list */
  47.   (*count)--;
  48.   /* move items down */
  49.   for (i=pos; i<*count; i++)
  50.     list[i] = list[i+1];
  51. }
  52. /*
  53.  * ompare two characters, ignoring case if necessary
  54.  */
  55. static BOOL cmatch(char t1, char t2)
  56. {
  57.   if (use_case)
  58.     return(t1 == t2);
  59.   return(toupper(t1) == toupper(t2));
  60. }
  61. /* Routine scans a string to see if any of the characters match
  62.  *  the arguments, then dispatches to the action routine if so.
  63.  */
  64. /* Callbacks of the form
  65.  *   void boolcallback( char selectchar, BOOL value)
  66.  *   void switchcallback( char selectchar, BOOL value)  ;; value always true
  67.  *   void stringcallback( char selectchar, char *string)
  68.  */
  69. static int scan_args(char *string, int index, char *arg)
  70. {
  71.   int i=-1;
  72.   while (ArgList[++i].id) {
  73.     switch( ArgList[i].mode) {
  74. case ARG_SWITCHSTRING:
  75.               if (cmatch(string[index], ArgList[i].id)) {
  76. (* ArgList[i].routine)(string[index],&string[index]);
  77.  return (ARG_NEXTCHAR);
  78.       }
  79.       break;
  80.       case ARG_SWITCH:
  81.               if (cmatch(string[index], ArgList[i].id)) {
  82. (* ArgList[i].routine)(string[index],(char *)TRUE);
  83.  return (ARG_NEXTCHAR);
  84.       }
  85.       break;
  86.       case ARG_BOOL:
  87.       if (cmatch(string[index], ArgList[i].id)) {
  88. if (string[0] == ARG_SEPTRUE)
  89.   (* ArgList[i].routine)(string[index],(char *)TRUE);
  90. else
  91.   (* ArgList[i].routine)(string[index],(char *)FALSE);
  92. return(ARG_NEXTCHAR);
  93.       }
  94.       break;
  95.       case ARG_CONCATSTRING:
  96.       if (cmatch(string[index], ArgList[i].id)) {
  97. (* ArgList[i].routine)(string[index], string+index+1);
  98. return(ARG_NEXTARG);
  99.       }
  100.       break;
  101.       case ARG_NOCONCATSTRING:
  102.       if (cmatch(string[index], ArgList[i].id)) {
  103. if (!arg)
  104.   return(ARG_NOARG);
  105.                 (* ArgList[i].routine)(string[index], arg);
  106.                 return(ARG_NEXTNOCAT);
  107.               }
  108.               break;
  109.     }
  110.   }
  111.   return(ARG_NOMATCH);
  112. }
  113. /*
  114.  * Main parse routine.  Scans for '-', then scan for arguments and
  115.  * delete from the argv[] array if so.
  116.  */
  117. BOOL parse_args(int *argc, char *argv[], BOOL case_sensitive)
  118. {
  119.   int pos = 0;
  120.   BOOL retval = TRUE;
  121.   use_case = case_sensitive;
  122.   while(++pos < *argc) {
  123.     if ((argv[pos][0] == ARG_SEPSWITCH) || (argv[pos][0] == ARG_SEPFALSE)
  124.           || (argv[pos][0] == ARG_SEPTRUE)) {
  125.       int argmode;
  126.       int index = 1;
  127.       int done = FALSE;
  128.       do {
  129.         /* Scan the present arg */
  130.         if (pos < *argc - 1)
  131.           argmode = scan_args(argv[pos], index, argv[pos+1]);
  132.         else
  133.           argmode = scan_args(argv[pos], index, 0);
  134.         switch(argmode) {
  135.           case ARG_NEXTCHAR:
  136.                   /* If it was a char, go to the next one */
  137.                   if (!argv[pos][++index])
  138.                     done = TRUE;
  139.                   break;
  140.           case ARG_NEXTNOCAT:
  141.                   /* Otherwise if it was a nocat, remove the extra arg */
  142.                   remove_arg(pos, argc, argv);
  143.                   /* Fall through to NEXTARG */
  144.           case ARG_NEXTARG:
  145.                   /* Just a next arg, go do it */
  146.                   done = TRUE;
  147.                   break;
  148.           case ARG_NOMATCH:
  149.                   /* No such arg, spit an error  */
  150.                   fprintf(stderr,"Invalid Arg: %sn", argv[pos]);
  151.                   done = TRUE;
  152.                   retval = FALSE;
  153.                   break;
  154.           case ARG_NOARG:
  155.                   /* Missing the arg for a CONCAT type, spit the error */
  156.                   fprintf(stderr,"Missing string for Arg %sn", argv[pos]);
  157.                   done = TRUE;
  158.                   retval = FALSE;
  159.                   break;
  160.         };
  161.       } while (!done);
  162.       /* We'll always get rid of the present arg
  163.        * And back up one
  164.  */
  165.       remove_arg(pos--, argc, argv);
  166.     }
  167.   }
  168.   return(retval);
  169. }