cmd.c

Go to the documentation of this file.
00001 /*                           C M D . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1987-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup ray */
00023 /*@{*/
00024 /** @file librt/cmd.c
00025  *  Read and parse a viewpoint-control command stream.
00026  *  This module is intended to be common to all programs which
00027  *  read this type of command stream;  the routines to handle
00028  *  the various keywords should go in application-specific modules.
00029  *
00030  *  Author -
00031  *      Michael John Muuss
00032  *
00033  *  Source -
00034  *      SECAD/VLD Computing Consortium, Bldg 394
00035  *      The U. S. Army Ballistic Research Laboratory
00036  *      Aberdeen Proving Ground, Maryland  21005
00037  *
00038  */
00039 /*@}*/
00040 
00041 #ifndef lint
00042 static const char RCScmd[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/cmd.c,v 14.11 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00043 #endif
00044 
00045 #include "common.h"
00046 
00047 
00048 
00049 #include <stdio.h>
00050 #include <ctype.h>
00051 #ifdef HAVE_STRING_H
00052 #include <string.h>
00053 #else
00054 #include <strings.h>
00055 #endif
00056 #include "machine.h"
00057 #include "vmath.h"
00058 #include "raytrace.h"
00059 
00060 /*
00061  *                      R T _ R E A D _ C M D
00062  *
00063  *  Read one semi-colon terminated string of arbitrary length from
00064  *  the given file into a dynamicly allocated buffer.
00065  *  Various commenting and escaping conventions are implemented here.
00066  *
00067  *  Returns:
00068  *      NULL    On EOF
00069  *      char *  On good read
00070  */
00071 char *
00072 rt_read_cmd(register FILE *fp)
00073 {
00074         register int    c;
00075         register char   *buf;
00076         register int    curpos;
00077         register int    curlen;
00078 
00079         curpos = 0;
00080         curlen = 400;
00081         buf = bu_malloc( curlen, "rt_read_cmd command buffer" );
00082 
00083         do  {
00084                 c = fgetc(fp);
00085                 if( c == EOF )  {
00086                         c = '\0';
00087                 } else if( c == '#' )  {
00088                         /* All comments run to the end of the line */
00089                         while( (c = fgetc(fp)) != EOF && c != '\n' )  ;
00090                         continue;
00091                 } else if( c == '\n' )  {
00092                         c = ' ';
00093                 } else if( c == ';' )  {
00094                         c = '\0';
00095                 } else if( c == '\\' )  {
00096                         /*  Backslash takes next character literally.
00097                          *  EOF detection here is not a problem, next
00098                          *  pass will detect it.
00099                          */
00100                         c = fgetc(fp);
00101                 } else if( !isascii(c) )  {
00102                         c = '?';
00103                 }
00104                 if( c != '\0' && curpos == 0 && isspace(c) )  {
00105                         /*  Dispose of leading white space.
00106                          *  Necessary to slurp up what newlines turn into.
00107                          */
00108                         continue;
00109                 }
00110                 if( curpos >= curlen )  {
00111                         curlen *= 2;
00112                         buf = bu_realloc( buf, curlen, "rt_read_cmd command buffer" );
00113                 }
00114                 buf[curpos++] = c;
00115         } while( c != '\0' );
00116         if( curpos <= 1 )  {
00117                 bu_free( buf, "rt_read_cmd command buffer (EOF)" );
00118                 return( (char *)0 );            /* EOF */
00119         }
00120         return( buf );                          /* OK */
00121 }
00122 
00123 #define MAXWORDS        4096    /* Max # of args per command */
00124 
00125 /*
00126  *                      R T _ S P L I T _ C M D
00127  *
00128  *  Build argv[] array from input buffer, by splitting whitespace
00129  *  separated "words" into null terminated strings.
00130  *  The input buffer is altered by this process.
00131  *
00132  *  Returns -
00133  *       0      no words in input
00134  *      nwords  number of words of input, now in argv[]
00135  */
00136 int
00137 rt_split_cmd(char **argv, int lim, register char *lp)
00138 {
00139         register int    nwords;                 /* number of words seen */
00140         register char   *lp1;
00141 
00142         argv[0] = "_NIL_";              /* sanity */
00143 
00144         while( *lp != '\0' && isspace( *lp ) )
00145                 lp++;
00146 
00147         if( *lp == '\0' )
00148                 return(0);              /* No words */
00149 
00150 #ifdef HAVE_SHELL_ESCAPE
00151         /* Handle "!" shell escape char so the shell can parse the line */
00152         if( *lp == '!' )  {
00153                 int     ret;
00154                 ret = system( lp+1 );
00155                 if( ret != 0 )  {
00156                         perror("system(3)");
00157                         bu_log("rt_split_cmd() FAILED: !%s\n", lp);
00158                 }
00159                 return(0);              /* No words */
00160         }
00161 #endif
00162 
00163         /* some non-space string has been seen, argv[0] is set */
00164         nwords = 1;
00165         argv[0] = lp;
00166 
00167         for( ; *lp != '\0'; lp++ )  {
00168                 if( !isspace( *lp ) )
00169                         continue;       /* skip over current word */
00170 
00171                 *lp = '\0';             /* terminate current word */
00172                 lp1 = lp + 1;
00173                 if( *lp1 != '\0' && !isspace( *lp1 ) )  {
00174                         /* Begin next word */
00175                         if( nwords >= lim-1 )
00176                                 break;  /* argv[] full */
00177 
00178                         argv[nwords++] = lp1;
00179                 }
00180         }
00181         argv[nwords] = (char *)0;       /* safety */
00182         return( nwords );
00183 }
00184 
00185 /*
00186  *                      R T _ D O _ C M D
00187  *
00188  *  Slice up input buffer into whitespace separated "words",
00189  *  look up the first word as a command, and if it has the
00190  *  correct number of args, call that function.
00191  *
00192  *  Expected to return -1 to halt command processing loop.
00193  *
00194  *  Based heavily on mged/cmd.c by Chuck Kennedy.
00195  */
00196 int
00197 rt_do_cmd(struct rt_i *rtip, const char *ilp, register const struct command_tab *tp)
00198                                                 /* FUTURE:  for globbing */
00199 
00200 
00201 {
00202         register int    nwords;                 /* number of words seen */
00203         char            *cmd_args[MAXWORDS+1];  /* array of ptrs to args */
00204         char            *lp;
00205         int             retval;
00206 
00207         lp = bu_malloc(strlen(ilp)+1, "rt_do_cmd lp");
00208         strcpy(lp, ilp);
00209 
00210         nwords = rt_split_cmd( cmd_args, MAXWORDS, lp );
00211         if( nwords <= 0 )
00212                 return(0);      /* No command to process */
00213 
00214 
00215         for( ; tp->ct_cmd != (char *)0; tp++ )  {
00216                 if( cmd_args[0][0] != tp->ct_cmd[0] ||
00217                                 /* the length of "n" is not significant, just needs to be big enough */
00218                     strncmp( cmd_args[0], tp->ct_cmd, MAXWORDS ) != 0 )
00219                         continue;
00220                 if( (nwords >= tp->ct_min) && (nwords <= tp->ct_max) ) {
00221                     retval = tp->ct_func( nwords, cmd_args );
00222                     bu_free(lp, "rt_do_cmd lp");
00223                     return retval;
00224                 }
00225                 bu_log("rt_do_cmd Usage: %s %s\n\t%s\n",
00226                         tp->ct_cmd, tp->ct_parms, tp->ct_comment );
00227                 bu_free(lp, "rt_do_cmd lp");
00228                 return(-1);             /* ERROR */
00229         }
00230         bu_log("rt_do_cmd(%s):  command not found\n", cmd_args[0]);
00231         bu_free(lp, "rt_do_cmd lp");
00232         return(-1);                     /* ERROR */
00233 }
00234 
00235 /*
00236  * Local Variables:
00237  * mode: C
00238  * tab-width: 8
00239  * c-basic-offset: 4
00240  * indent-tabs-mode: t
00241  * End:
00242  * ex: shiftwidth=4 tabstop=8
00243  */

Generated on Mon Sep 18 01:24:47 2006 for BRL-CAD by  doxygen 1.4.6