parse.c

Go to the documentation of this file.
00001 /*                         P A R S E . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1989-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 librt */
00023 /*@{*/
00024 /** @file ./librt/parse.c
00025  *  Routines to assign values to elements of arbitrary structures.
00026  *  The layout of a structure to be processed is described by
00027  *  a structure of type "structparse", giving element names, element
00028  *  formats, an offset from the beginning of the structure, and
00029  *  a pointer to an optional "hooked" function that is called whenever
00030  *  that structure element is changed.
00031  *
00032  *  Authors -
00033  *      Michael John Muuss
00034  *      Lee A. Butler
00035  *
00036  *  Source -
00037  *      SECAD/VLD Computing Consortium, Bldg 394
00038  *      The U. S. Army Ballistic Research Laboratory
00039  *      Aberdeen Proving Ground, Maryland  21005
00040  *
00041  */
00042 /*@}*/
00043 
00044 #ifndef lint
00045 static const char RCSparse[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/parse.c,v 14.10 2006/09/16 02:04:25 lbutler Exp $ (BRL)";
00046 #endif
00047 
00048 #include "common.h"
00049 
00050 
00051 
00052 #include <stdio.h>
00053 #include <ctype.h>
00054 #include <math.h>
00055 #ifdef HAVE_STRING_H
00056 # include <string.h>
00057 #else
00058 # include <strings.h>
00059 #endif
00060 
00061 #include "machine.h"
00062 #include "vmath.h"
00063 #include "bu.h"
00064 #include "raytrace.h"
00065 
00066 
00067 
00068 /*
00069  *                      B U _ M A T P R I N T
00070  *
00071  *      XXX Should this be here, or could it be with the matrix support?
00072  *      pretty-print a matrix
00073  */
00074 HIDDEN void
00075 bu_matprint(const char *name, register const matp_t mat)
00076 {
00077         int     delta = strlen(name)+2;
00078 
00079         /* indent the body of the matrix */
00080         bu_log_indent_delta(delta);
00081 
00082         bu_log(" %s=%.-12E %.-12E %.-12E %.-12E\n",
00083                 name, mat[0], mat[1], mat[2], mat[3]);
00084 
00085         bu_log("%.-12E %.-12E %.-12E %.-12E\n",
00086                 mat[4], mat[5], mat[6], mat[7]);
00087 
00088         bu_log("%.-12E %.-12E %.-12E %.-12E\n",
00089                 mat[8], mat[9], mat[10], mat[11]);
00090 
00091         bu_log_indent_delta(-delta);
00092 
00093         bu_log("%.-12E %.-12E %.-12E %.-12E\n",
00094                 mat[12], mat[13], mat[14], mat[15]);
00095 }
00096 
00097 
00098 /*
00099  *                      B U _ S T R U C T P R I N T
00100  */
00101 void
00102 bu_structprint(const char *title, const struct bu_structparse *parsetab, const char *base)
00103 
00104                                           /* structure description */
00105                                           /* base address of users structure */
00106 {
00107         register const struct bu_structparse    *sdp;
00108         register char                   *loc;
00109         register int                    lastoff = -1;
00110         struct bu_vls vls;
00111 
00112         bu_vls_init( &vls );
00113         bu_log( "%s\n", title );
00114         if (parsetab == (struct bu_structparse *)NULL) {
00115                 bu_log( "Null \"struct bu_structparse\" pointer\n");
00116                 return;
00117         }
00118         for( sdp = parsetab; sdp->sp_name != (char *)0; sdp++ )  {
00119 
00120                 /* Skip alternate keywords for same value */
00121                 if( lastoff == sdp->sp_offset )
00122                         continue;
00123                 lastoff = sdp->sp_offset;
00124 
00125 #if CRAY && !__STDC__
00126                 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
00127 #else
00128                 loc = (char *)(base + ((int)sdp->sp_offset));
00129 #endif
00130 
00131                 if (sdp->sp_fmt[0] == 'i' )  {
00132                         bu_structprint( sdp->sp_name,
00133                                 (struct bu_structparse *)sdp->sp_count,
00134                                 base );
00135                         continue;
00136                 }
00137 
00138                 if ( sdp->sp_fmt[0] != '%')  {
00139                         bu_log("bu_structprint:  %s: unknown format '%s'\n",
00140                                 sdp->sp_name, sdp->sp_fmt );
00141                         continue;
00142                 }
00143 #if 0
00144                 bu_vls_trunc( &vls, 0 );
00145                 bu_vls_item_print( &vls, sdp, base );
00146                 bu_log( " %s=%s\n", sdp->sp_name, bu_vls_addr(&vls) );
00147 #else
00148                 switch( sdp->sp_fmt[1] )  {
00149                 case 'c':
00150                 case 's':
00151                         if (sdp->sp_count < 1)
00152                                 break;
00153                         if (sdp->sp_count == 1)
00154                                 bu_log( " %s='%c'\n", sdp->sp_name, *loc);
00155                         else
00156                                 bu_log( " %s=\"%s\"\n", sdp->sp_name,
00157                                         (char *)loc );
00158                         break;
00159                 case 'S':
00160                         {
00161                                 int delta = strlen(sdp->sp_name)+2;
00162                                 register struct bu_vls *vls =
00163                                         (struct bu_vls *)loc;
00164 
00165                                 bu_log_indent_delta(delta);
00166                                 bu_log(" %s=(vls_magic)%d (vls_offset)%d (vls_len)%d (vls_max)%d\n",
00167                                         sdp->sp_name, vls->vls_magic,
00168                                         vls->vls_offset,
00169                                         vls->vls_len, vls->vls_max);
00170                                 bu_log_indent_delta(-delta);
00171                                 bu_log("\"%s\"\n", vls->vls_str+vls->vls_offset);
00172                         }
00173                         break;
00174                 case 'i':
00175                         {       register int i = sdp->sp_count;
00176                                 register short *sp = (short *)loc;
00177 
00178                                 bu_log( " %s=%hd", sdp->sp_name, *sp++ );
00179 
00180                                 while (--i > 0) bu_log( ",%d", *sp++ );
00181 
00182                                 bu_log("\n");
00183                         }
00184                         break;
00185                 case 'd':
00186                         {       register int i = sdp->sp_count;
00187                                 register int *dp = (int *)loc;
00188 
00189                                 bu_log( " %s=%d", sdp->sp_name, *dp++ );
00190 
00191                                 while (--i > 0) bu_log( ",%d", *dp++ );
00192 
00193                                 bu_log("\n");
00194                         }
00195                         break;
00196                 case 'f':
00197                         {       register int i = sdp->sp_count;
00198                                 register double *dp = (double *)loc;
00199 
00200                                 if (sdp->sp_count == ELEMENTS_PER_MAT) {
00201                                         bu_matprint(sdp->sp_name, (matp_t)dp);
00202                                 } else if (sdp->sp_count <= ELEMENTS_PER_VECT){
00203                                         bu_log( " %s=%.25G", sdp->sp_name, *dp++ );
00204 
00205                                         while (--i > 0)
00206                                                 bu_log( ",%.25G", *dp++ );
00207 
00208                                         bu_log("\n");
00209                                 }else  {
00210                                         int delta = strlen(sdp->sp_name)+2;
00211 
00212                                         bu_log_indent_delta(delta);
00213 
00214                                         bu_log( " %s=%.25G\n", sdp->sp_name, *dp++ );
00215 
00216                                         while (--i > 1)
00217                                                 bu_log( "%.25G\n", *dp++ );
00218 
00219                                         bu_log_indent_delta(-delta);
00220                                         bu_log( "%.25G\n", *dp );
00221                                 }
00222                         }
00223                         break;
00224                 case 'x':
00225                         {       register int i = sdp->sp_count;
00226                                 register int *dp = (int *)loc;
00227 
00228                                 bu_log( " %s=%08x", sdp->sp_name, *dp++ );
00229 
00230                                 while (--i > 0) bu_log( ",%08x", *dp++ );
00231 
00232                                 bu_log("\n");
00233                         }
00234                         break;
00235                 default:
00236                         bu_log( " bu_structprint: Unknown format: %s=%s??\n",
00237                                 sdp->sp_name, sdp->sp_fmt );
00238                         break;
00239                 }
00240 #endif
00241         }
00242         bu_vls_free(&vls);
00243 }
00244 
00245 
00246 /*
00247  *                      B U _ P A R S E _ D O U B L E
00248  *
00249  *  Parse an array of one or more doubles.
00250  *  Return value: 0 when successful
00251  *               <0 upon failure
00252  */
00253 HIDDEN int
00254 bu_parse_double(const char *str, long int count, double *loc)
00255 {
00256         long    i;
00257         int     dot_seen;
00258         const char      *numstart;
00259         double  tmp_double;
00260         char    buf[128];
00261         int     len;
00262 
00263         for (i=0 ; i < count && *str ; ++i){
00264                 numstart = str;
00265 
00266                 /* skip sign */
00267                 if (*str == '-' || *str == '+') str++;
00268 
00269                 /* skip matissa */
00270                 dot_seen = 0;
00271                 for ( ; *str ; str++ ) {
00272                         if (*str == '.' && !dot_seen) {
00273                                 dot_seen = 1;
00274                                 continue;
00275                         }
00276                         if (!isdigit(*str))
00277                                 break;
00278 
00279                 }
00280 
00281                 /* If no mantissa seen, then there is no float here */
00282                 if (str == (numstart + dot_seen) )
00283                         return -1;
00284 
00285                 /* there was a mantissa, so we may have an exponent */
00286                 if  (*str == 'E' || *str == 'e') {
00287                         str++;
00288 
00289                         /* skip exponent sign */
00290                         if (*str == '+' || *str == '-') str++;
00291 
00292                         while (isdigit(*str)) str++;
00293                 }
00294 
00295                 len = str - numstart;
00296                 if( len > sizeof(buf)-1 )  len = sizeof(buf)-1;
00297                 strncpy( buf, numstart, len );
00298                 buf[len] = '\0';
00299 
00300                 if( sscanf( buf, "%lf", &tmp_double ) != 1 )
00301                         return -1;
00302 
00303                 *loc++ = tmp_double;
00304 
00305                 /* skip the separator */
00306                 if (*str) str++;
00307         }
00308         return 0;
00309 }
00310 
00311 /*
00312  *                      B U _ S T R U C T _ L O O K U P
00313  *
00314  *  Returns -
00315  *      -2      parse error
00316  *      -1      not found
00317  *       0      entry found and processed
00318  */
00319 HIDDEN int
00320 bu_struct_lookup(register const struct bu_structparse *sdp, register const char *name, char *base, const char *value)
00321                                                 /* structure description */
00322                                                 /* struct member name */
00323                                                 /* begining of structure */
00324                                                 /* string containing value */
00325 {
00326         register char *loc;
00327         int i, retval = 0;
00328 
00329         for( ; sdp->sp_name != (char *)0; sdp++ )  {
00330 
00331                 if( strcmp( sdp->sp_name, name ) != 0   /* no name match */
00332                     && sdp->sp_fmt[0] != 'i' )          /* no include desc */
00333 
00334                     continue;
00335 
00336                 /* if we get this far, we've got a name match
00337                  * with a name in the structure description
00338                  */
00339 
00340 #if CRAY && !__STDC__
00341                 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
00342 #else
00343                 loc = (char *)(base + ((int)sdp->sp_offset));
00344 #endif
00345 
00346                 if (sdp->sp_fmt[0] == 'i') {
00347                         /* Indirect to another structure */
00348                         if( bu_struct_lookup(
00349                                 (struct bu_structparse *)sdp->sp_count,
00350                                 name, base, value )
00351                             == 0 )
00352                                 return(0);      /* found */
00353                         else
00354                                 continue;
00355                 }
00356                 if (sdp->sp_fmt[0] != '%') {
00357                         bu_log("bu_struct_lookup(%s): unknown format '%s'\n",
00358                                 name, sdp->sp_fmt );
00359                         return(-1);
00360                 }
00361 
00362                 switch( sdp->sp_fmt[1] )  {
00363                 case 'c':
00364                 case 's':
00365                         {       register int i, j;
00366 
00367                                 /* copy the string, converting escaped
00368                                  * double quotes to just double quotes
00369                                  */
00370                                 for(i=j=0 ;
00371                                     j < sdp->sp_count && value[i] != '\0' ;
00372                                     loc[j++] = value[i++])
00373                                         if (value[i] == '\\' &&
00374                                             value[i+1] == '"')
00375                                                 ++i;
00376 
00377                                 if (sdp->sp_count > 1)
00378                                         loc[sdp->sp_count-1] = '\0';
00379                         }
00380                         break;
00381                 case 'S':
00382                         {       struct bu_vls *vls = (struct bu_vls *)loc;
00383                                 bu_vls_init_if_uninit( vls );
00384                                 bu_vls_strcpy(vls, value);
00385                         }
00386                         break;
00387                 case 'i':
00388                         {       register short *ip = (short *)loc;
00389                                 register short tmpi;
00390                                 register const char *cp;
00391                                 for (i=0 ; i < sdp->sp_count && *value ; ++i){
00392                                         tmpi = atoi( value );
00393 
00394                                         cp = value;
00395                                         if (*cp && (*cp == '+' || *cp == '-'))
00396                                                 cp++;
00397 
00398                                         while (*cp && isdigit(*cp) )
00399                                                 cp++;
00400 
00401                                         /* make sure we actually had an
00402                                          * integer out there
00403                                          */
00404                                         if (cp == value ||
00405                                             (cp == value+1 &&
00406                                             (*value == '+' || *value == '-'))){
00407                                             retval = -2;
00408                                             break;
00409                                         } else {
00410                                                 *(ip++) = tmpi;
00411                                                 value = cp;
00412                                         }
00413                                         /* skip the separator */
00414                                         if (*value) value++;
00415                                 }
00416                         }
00417                         break;
00418                 case 'd':
00419                         {       register int *ip = (int *)loc;
00420                                 register int tmpi;
00421                                 register char const *cp;
00422                                 /* Special case:  '=!' toggles a boolean */
00423                                 if( *value == '!' )  {
00424                                         *ip = *ip ? 0 : 1;
00425                                         value++;
00426                                         break;
00427                                 }
00428                                 /* Normal case: an integer */
00429                                 for (i=0 ; i < sdp->sp_count && *value ; ++i){
00430                                         tmpi = atoi( value );
00431 
00432                                         cp = value;
00433                                         if (*cp && (*cp == '+' || *cp == '-'))
00434                                                 cp++;
00435 
00436                                         while (*cp && isdigit(*cp) )
00437                                                 cp++;
00438 
00439                                         /* make sure we actually had an
00440                                          * integer out there
00441                                          */
00442                                         if (cp == value ||
00443                                             (cp == value+1 &&
00444                                             (*value == '+' || *value == '-'))){
00445                                             retval = -2;
00446                                             break;
00447                                         } else {
00448                                                 *(ip++) = tmpi;
00449                                                 value = cp;
00450                                         }
00451                                         /* skip the separator */
00452                                         if (*value) value++;
00453                                 }
00454                         }
00455                         break;
00456                 case 'f':
00457                         retval = bu_parse_double(value, sdp->sp_count,
00458                                                  (double *)loc);
00459                         break;
00460                 default:
00461                         bu_log("bu_struct_lookup(%s): unknown format '%s'\n",
00462                                 name, sdp->sp_fmt );
00463                         return(-1);
00464                 }
00465                 if( sdp->sp_hook )  {
00466                         sdp->sp_hook( sdp, name, base, value );
00467                 }
00468                 return(retval);         /* OK or parse error */
00469         }
00470         return(-1);                     /* Not found */
00471 }
00472 
00473 /*
00474  *                      B U _ S T R U C T P A R S E
00475  *
00476  *      Parse the structure element description in the vls string "vls"
00477  *      according to the structure description in "parsetab"
00478  *
00479  *  Returns -
00480  *      <0      failure
00481  *       0      OK
00482  */
00483 int
00484 bu_structparse(const struct bu_vls *in_vls, const struct bu_structparse *desc, char *base)
00485                                                 /* string to parse through */
00486                                                 /* structure description */
00487                                                 /* base addr of users struct */
00488 {
00489         struct bu_vls   vls;
00490         register char *cp;
00491         char    *name;
00492         char    *value;
00493         int retval;
00494 
00495         BU_CK_VLS(in_vls);
00496         if (desc == (struct bu_structparse *)NULL) {
00497                 bu_log( "Null \"struct bu_structparse\" pointer\n");
00498                 return(-1);
00499         }
00500 
00501         /* Duplicate the input string.  This algorithm is destructive. */
00502         bu_vls_init( &vls );
00503         bu_vls_vlscat( &vls, in_vls );
00504         cp = bu_vls_addr( &vls );
00505 
00506         while( *cp )  {
00507                 /* NAME = VALUE white-space-separator */
00508 
00509                 /* skip any leading whitespace */
00510                 while( *cp != '\0' && isascii(*cp) && isspace(*cp) )
00511                         cp++;
00512 
00513                 /* Find equal sign */
00514                 name = cp;
00515                 while ( *cp != '\0' && *cp != '=' )
00516                         cp++;
00517 
00518                 if( *cp == '\0' )  {
00519                         if( name == cp ) break;
00520 
00521                         /* end of string in middle of arg */
00522                         bu_log("bu_structparse: name '%s' without '='\n",
00523                                 name );
00524                         bu_vls_free( &vls );
00525                         return(-2);
00526                 }
00527 
00528                 *cp++ = '\0';
00529 
00530                 /* Find end of value. */
00531                 if (*cp == '"') {
00532                         /* strings are double-quote (") delimited
00533                          * skip leading " & find terminating "
00534                          * while skipping escaped quotes (\")
00535                          */
00536                         for (value = ++cp ; *cp != '\0' ; ++cp)
00537                                 if (*cp == '"' &&
00538                                     (cp == value || *(cp-1) != '\\') )
00539                                         break;
00540 
00541                         if (*cp != '"') {
00542                                 bu_log("bu_structparse: name '%s'=\" without closing \"\n",
00543                                         name);
00544                                 bu_vls_free( &vls );
00545                                 return(-3);
00546                         }
00547                 } else {
00548                         /* non-strings are white-space delimited */
00549                         value = cp;
00550                         while( *cp != '\0' && isascii(*cp) && !isspace(*cp) )
00551                                 cp++;
00552                 }
00553 
00554                 if( *cp != '\0' )
00555                         *cp++ = '\0';
00556 
00557                 /* Lookup name in desc table and modify */
00558                 retval = bu_struct_lookup( desc, name, base, value );
00559                 if( retval == -1 ) {
00560                     bu_log("bu_structparse:  '%s=%s', element name not found in:\n",
00561                            name, value);
00562                     bu_structprint( "troublesome one", desc, base );
00563                 } else if( retval == -2 ) {
00564                     bu_vls_free( &vls );
00565                     return -2;
00566                 }
00567 
00568         }
00569         bu_vls_free( &vls );
00570         return(0);
00571 }
00572 
00573 
00574 HIDDEN void
00575 bu_vls_item_print_core(struct bu_vls *vp, const struct bu_structparse *sdp, const char *base, char sep_char)
00576 
00577                                      /* item description */
00578                                   /* base address of users structure */
00579                                   /* value separator */
00580 {
00581     register char *loc;
00582 
00583     if (sdp == (struct bu_structparse *)NULL) {
00584         bu_log( "Null \"struct bu_structparse\" pointer\n");
00585         return;
00586     }
00587 
00588 #if CRAY && !__STDC__
00589     loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
00590 #else
00591     loc = (char *)(base + ((int)sdp->sp_offset));
00592 #endif
00593 
00594     if (sdp->sp_fmt[0] == 'i' )  {
00595         bu_log( "Cannot print type 'i' yet!\n" );
00596         return;
00597     }
00598 
00599     if ( sdp->sp_fmt[0] != '%')  {
00600         bu_log("bu_vls_item_print:  %s: unknown format '%s'\n",
00601                sdp->sp_name, sdp->sp_fmt );
00602         return;
00603     }
00604 
00605     switch( sdp->sp_fmt[1] )  {
00606     case 'c':
00607     case 's':
00608         if (sdp->sp_count < 1)
00609             break;
00610         if (sdp->sp_count == 1)
00611             bu_vls_printf( vp, "%c", *loc );
00612         else
00613             bu_vls_printf( vp, "%s", (char *)loc );
00614         break;
00615     case 'S': {
00616         register struct bu_vls *vls = (struct bu_vls *)loc;
00617 
00618         bu_vls_vlscat( vp, vls ); }
00619         break;
00620     case 'i': {
00621         register int i = sdp->sp_count;
00622         register short *sp = (short *)loc;
00623 
00624         bu_vls_printf( vp, "%hd", *sp++ );
00625         while( --i > 0 ) bu_vls_printf( vp, "%c%hd", sep_char, *sp++ ); }
00626         break;
00627     case 'd': {
00628         register int i = sdp->sp_count;
00629         register int *dp = (int *)loc;
00630 
00631         bu_vls_printf( vp, "%d", *dp++ );
00632         while( --i > 0 ) bu_vls_printf( vp, "%c%d", sep_char, *dp++ ); }
00633         break;
00634     case 'f': {
00635         register int i = sdp->sp_count;
00636         register double *dp = (double *)loc;
00637 
00638         bu_vls_printf( vp, "%.25G", *dp++ );
00639         while( --i > 0 ) bu_vls_printf( vp, "%c%.25G", sep_char, *dp++ ); }
00640         break;
00641     case 'x': {
00642         register int i = sdp->sp_count;
00643         register int *dp = (int *)loc;
00644 
00645         bu_vls_printf( vp, "%08x", *dp++ );
00646         while( --i > 0 ) bu_vls_printf( vp, "%c%08x", sep_char, *dp++ );  }
00647         break;
00648     default:
00649         break;
00650     }
00651 }
00652 
00653 
00654 
00655 /*
00656  *                     B U _ V L S _ I T E M _ P R I N T
00657  *
00658  * Takes the single item pointed to by "sp", and prints its value into a
00659  * vls.
00660  */
00661 
00662 void
00663 bu_vls_item_print(struct bu_vls *vp, const struct bu_structparse *sdp, const char *base)
00664 
00665                                       /* item description */
00666                                   /* base address of users structure */
00667 {
00668     bu_vls_item_print_core( vp, sdp, base, ',' );
00669 }
00670 
00671 /*
00672  *    B U _ V L S _ I T E M _ P R I N T _ N C
00673  *
00674  *    A "no-commas" version of the bu_vls_item_print() routine.
00675  */
00676 
00677 void
00678 bu_vls_item_print_nc(struct bu_vls *vp, const struct bu_structparse *sdp, const char *base)
00679 
00680                                       /* item description */
00681                                   /* base address of users structure */
00682 {
00683     bu_vls_item_print_core( vp, sdp, base, ' ' );
00684 }
00685 
00686 /*                  B U _ V L S _ N A M E _ P R I N T
00687  *
00688  * A version of bu_vls_item_print that allows you to select by name.
00689  */
00690 
00691 int
00692 bu_vls_name_print(struct bu_vls *vp, const struct bu_structparse *parsetab, const char *name, const char *base)
00693 {
00694     register const struct bu_structparse *sdp;
00695 
00696     for( sdp = parsetab; sdp->sp_name != NULL; sdp++ )
00697         if( strcmp(sdp->sp_name, name) == 0 ) {
00698             bu_vls_item_print( vp, sdp, base );
00699             return 0;
00700         }
00701 
00702     return -1;
00703 }
00704 
00705 /*                  B U _ V L S _ N A M E _ P R I N T _ N C
00706  *
00707  * A "no-commas" version of bu_vls_name_print
00708  */
00709 
00710 int
00711 bu_vls_name_print_nc(struct bu_vls *vp, const struct bu_structparse *parsetab, const char *name, const char *base)
00712 {
00713     register const struct bu_structparse *sdp;
00714 
00715     for( sdp = parsetab; sdp->sp_name != NULL; sdp++ )
00716         if( strcmp(sdp->sp_name, name) == 0 ) {
00717             bu_vls_item_print_nc( vp, sdp, base );
00718             return 0;
00719         }
00720 
00721     return -1;
00722 }
00723 
00724 
00725 /*
00726  *                      B U _ V L S _ P R I N T _ D O U B L E
00727  */
00728 HIDDEN void
00729 bu_vls_print_double(struct bu_vls *vls, const char *name, register long int count, register const double *dp)
00730 {
00731         register int tmpi;
00732         register char *cp;
00733 
00734         bu_vls_extend(vls, strlen(name) + 3 + 32 * count);
00735 
00736         cp = vls->vls_str + vls->vls_offset + vls->vls_len;
00737         sprintf(cp, "%s%s=%.27G", (vls->vls_len?" ":""), name, *dp++);
00738         tmpi = strlen(cp);
00739         vls->vls_len += tmpi;
00740 
00741         while (--count > 0) {
00742                 cp += tmpi;
00743                 sprintf(cp, ",%.27G", *dp++);
00744                 tmpi = strlen(cp);
00745                 vls->vls_len += tmpi;
00746         }
00747 }
00748 
00749 /*
00750  *                      B U _ V L S _ S T R U C T P R I N T
00751  *
00752  *      This differs from bu_structprint in that this output is less readable
00753  *      by humans, but easier to parse with the computer.
00754  */
00755 void
00756 bu_vls_structprint(struct bu_vls *vls, register const struct bu_structparse *sdp, const char *base)
00757                                                 /* vls to print into */
00758                                                 /* structure description */
00759                                                 /* structure ponter */
00760 {
00761         register char                   *loc;
00762         register int                    lastoff = -1;
00763         register char                   *cp;
00764 
00765         BU_CK_VLS(vls);
00766 
00767         if (sdp == (struct bu_structparse *)NULL) {
00768                 bu_log( "Null \"struct bu_structparse\" pointer\n");
00769                 return;
00770         }
00771 
00772         for ( ; sdp->sp_name != (char*)NULL ; sdp++) {
00773                 /* Skip alternate keywords for same value */
00774 
00775                 if( lastoff == sdp->sp_offset )
00776                         continue;
00777                 lastoff = sdp->sp_offset;
00778 
00779 #if CRAY && !__STDC__
00780                 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
00781 #else
00782                 loc = (char *)(base + ((int)sdp->sp_offset));
00783 #endif
00784 
00785                 if (sdp->sp_fmt[0] == 'i')  {
00786                         struct bu_vls sub_str;
00787 
00788                         bu_vls_init(&sub_str);
00789                         bu_vls_structprint( &sub_str,
00790                                 (struct bu_structparse *)sdp->sp_count,
00791                                 base );
00792 
00793                         bu_vls_vlscat(vls, &sub_str);
00794                         bu_vls_free( &sub_str );
00795                         continue;
00796                 }
00797 
00798                 if ( sdp->sp_fmt[0] != '%' )  {
00799                         bu_log("bu_structprint:  %s: unknown format '%s'\n",
00800                                 sdp->sp_name, sdp->sp_fmt );
00801                         break;
00802                 }
00803 
00804                 switch( sdp->sp_fmt[1] )  {
00805                 case 'c':
00806                 case 's':
00807                         if (sdp->sp_count < 1)
00808                                 break;
00809                         if (sdp->sp_count == 1) {
00810                                 bu_vls_extend(vls, strlen(sdp->sp_name)+6);
00811                                 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
00812                                 if (*loc == '"')
00813                                         sprintf(cp, "%s%s=\"%s\"",
00814                                                 (vls->vls_len?" ":""),
00815                                                 sdp->sp_name, "\\\"");
00816                                 else
00817                                         sprintf(cp, "%s%s=\"%c\"",
00818                                                 (vls->vls_len?" ":""),
00819                                                 sdp->sp_name,
00820                                                 *loc);
00821                         } else {
00822                                 register char *p;
00823                                 register int count=0;
00824 
00825                                 /* count the quote characters */
00826                                 p = loc;
00827                                 while ((p=strchr(p, '"')) != (char *)NULL) {
00828                                         ++p;
00829                                         ++count;
00830                                 }
00831                                 bu_vls_extend(vls, strlen(sdp->sp_name)+
00832                                         strlen(loc)+5+count);
00833 
00834                                 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
00835                                 if (vls->vls_len) (void)strcat(cp, " ");
00836                                 (void)strcat(cp, sdp->sp_name);
00837                                 (void)strcat(cp, "=\"");
00838 
00839                                 /* copy the string, escaping all the internal
00840                                  * double quote (") characters
00841                                  */
00842                                 p = &cp[strlen(cp)];
00843                                 while (*loc) {
00844                                         if (*loc == '"') {
00845                                                 *p++ = '\\';
00846                                         }
00847                                         *p++ = *loc++;
00848                                 }
00849                                 *p++ = '"';
00850                                 *p = '\0';
00851                         }
00852                         vls->vls_len += strlen(cp);
00853                         break;
00854                 case 'S':
00855                         {       register struct bu_vls *vls_p =
00856                                         (struct bu_vls *)loc;
00857 
00858                                 bu_vls_extend(vls, bu_vls_strlen(vls_p) + 5 +
00859                                         strlen(sdp->sp_name) );
00860 
00861                                 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
00862                                 sprintf(cp, "%s%s=\"%s\"",
00863                                         (vls->vls_len?" ":""),
00864                                         sdp->sp_name,
00865                                         bu_vls_addr(vls_p) );
00866                                 vls->vls_len += strlen(cp);
00867                         }
00868                         break;
00869                 case 'i':
00870                         {       register int i = sdp->sp_count;
00871                                 register short *sp = (short *)loc;
00872                                 register int tmpi;
00873 
00874                                 bu_vls_extend(vls,
00875                                         64 * i + strlen(sdp->sp_name) + 3 );
00876 
00877                                 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
00878                                 sprintf(cp, "%s%s=%d",
00879                                                 (vls->vls_len?" ":""),
00880                                                  sdp->sp_name, *sp++);
00881                                 tmpi = strlen(cp);
00882                                 vls->vls_len += tmpi;
00883 
00884                                 while (--i > 0) {
00885                                         cp += tmpi;
00886                                         sprintf(cp, ",%d", *sp++);
00887                                         tmpi = strlen(cp);
00888                                         vls->vls_len += tmpi;
00889                                 }
00890                         }
00891                         break;
00892                 case 'd':
00893                         {       register int i = sdp->sp_count;
00894                                 register int *dp = (int *)loc;
00895                                 register int tmpi;
00896 
00897                                 bu_vls_extend(vls,
00898                                         64 * i + strlen(sdp->sp_name) + 3 );
00899 
00900                                 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
00901                                 sprintf(cp, "%s%s=%d",
00902                                         (vls->vls_len?" ":""),
00903                                         sdp->sp_name, *dp++);
00904                                 tmpi = strlen(cp);
00905                                 vls->vls_len += tmpi;
00906 
00907                                 while (--i > 0) {
00908                                         cp += tmpi;
00909                                         sprintf(cp, ",%d", *dp++);
00910                                         tmpi = strlen(cp);
00911                                         vls->vls_len += tmpi;
00912                                 }
00913                         }
00914                         break;
00915                 case 'f':
00916                         bu_vls_print_double(vls, sdp->sp_name, sdp->sp_count,
00917                                 (double *)loc);
00918                         break;
00919                 default:
00920                         bu_log( " %s=%s??\n", sdp->sp_name, sdp->sp_fmt );
00921                         abort();
00922                         break;
00923                 }
00924         }
00925 }
00926 
00927 /*
00928  * Local Variables:
00929  * mode: C
00930  * tab-width: 8
00931  * c-basic-offset: 4
00932  * indent-tabs-mode: t
00933  * End:
00934  * ex: shiftwidth=4 tabstop=8
00935  */

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