db_match.c

Go to the documentation of this file.
00001 /*                      D B _ M A T C H . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1994-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 dbio */
00023 
00024 /*@{*/
00025 /** @file db_match.c
00026  *
00027  * Functions -
00028  *      db_regexp_match         Determine if a string matches a regexp pattern
00029  *      db_regexp_match_all     Return a vls filled with all names matching
00030  *                              the given pattern
00031  *      db_update_nref          Updates the d_nref fields of each member of
00032  *                              the directory in the given database.
00033  *
00034  *  Author -
00035  *      Michael John Muuss
00036  *      Glenn Durfee
00037  *
00038  *  Source -
00039  *      The U. S. Army Research Laboratory
00040  *      Aberdeen Proving Ground, Maryland  21005-5068  USA
00041  */
00042 
00043 #ifndef lint
00044 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db_match.c,v 14.12 2006/09/16 02:04:24 lbutler Exp $ (ARL)";
00045 #endif
00046 
00047 #include "common.h"
00048 
00049 
00050 
00051 #include <stdio.h>
00052 
00053 #include "machine.h"
00054 #include "vmath.h"
00055 #include "db.h"
00056 #include "raytrace.h"
00057 #include "rtgeom.h"
00058 
00059 #include "./debug.h"
00060 
00061 /**
00062  *                      D B _ R E G E X P _ M A T C H
00063  *
00064  *      If string matches pattern, return 1, else return 0
00065  *
00066  *      special characters:
00067  *              *       Matches any string including the null string.
00068  *              ?       Matches any single character.
00069  *              [...]   Matches any one of the characters enclosed.
00070  *              -       May be used inside brackets to specify range
00071  *                      (i.e. str[1-58] matches str1, str2, ... str5, str8)
00072  *              \       Escapes special characters.
00073  */
00074 int
00075 db_regexp_match(register const char *pattern, register const char *string)
00076 {
00077         do {
00078                 switch( *pattern ) {
00079                 case '*':
00080                         /* match any string including null string */
00081                         ++pattern;
00082                         do {
00083                                 if( db_regexp_match( pattern, string ) )
00084                                         return( 1 );
00085                         } while( *string++ != '\0' );
00086                         return( 0 );
00087                 case '?':
00088                         /* match any character  */
00089                         if( *string == '\0' )
00090                                 return( 0 );
00091                         break;
00092                 case '[':
00093                         /* try to match one of the characters in brackets */
00094                         ++pattern;
00095                         if( *pattern == '\0' )
00096                                 return( 0 );
00097                         while( *pattern != *string ) {
00098                                 if( pattern[0] == '-' && pattern[-1] != '\\')
00099                                         if(     pattern[-1] <= *string &&
00100                                                 pattern[-1] != '[' &&
00101                                                 pattern[ 1] >= *string &&
00102                                                 pattern[ 1] != ']' )
00103                                                 break;
00104                                 ++pattern;
00105                                 if( *pattern == '\0' || *pattern == ']' )
00106                                         return( 0 );
00107                         }
00108                         /* skip to next character after closing bracket */
00109                         while( *pattern != '\0' && *pattern != ']' )
00110                                 ++pattern;
00111                         break;
00112                 case '\\':
00113                         /* escape special character */
00114                         ++pattern;
00115                         /* compare characters */
00116                         if( *pattern != *string )
00117                                 return( 0 );
00118                         break;
00119                 default:
00120                         /* compare characters */
00121                         if( *pattern != *string )
00122                                 return( 0 );
00123                 }
00124                 ++string;
00125         } while( *pattern++ != '\0' );
00126         return( 1 );
00127 }
00128 
00129 
00130 
00131 /**
00132  *                      D B _ R E G E X P _ M A T C H _ A L L
00133  *
00134  * Appends a list of all database matches to the given vls, or the pattern
00135  * itself if no matches are found.
00136  * Returns the number of matches.
00137  */
00138 
00139 int
00140 db_regexp_match_all(struct bu_vls *dest, struct db_i *dbip, const char *pattern)
00141 {
00142         register int i, num;
00143         register struct directory *dp;
00144 
00145         for( i = num = 0; i < RT_DBNHASH; i++ )  {
00146                 for( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw ){
00147                         if( !db_regexp_match( pattern, dp->d_namep ) )
00148                                 continue;
00149                         if( num == 0 )
00150                                 bu_vls_strcat( dest, dp->d_namep );
00151                         else {
00152                                 bu_vls_strcat( dest, " " );
00153                                 bu_vls_strcat( dest, dp->d_namep );
00154                         }
00155                         ++num;
00156                 }
00157         }
00158 
00159         return num;
00160 }
00161 
00162 
00163 HIDDEN void
00164 db_count_refs(struct db_i *dbip, struct rt_comb_internal *comb, union tree *comb_leaf, genptr_t dummy1, genptr_t dummy2, genptr_t dummy3)
00165 {
00166         struct directory        *dp;
00167 
00168         RT_CK_TREE( comb_leaf );
00169 
00170         if( (dp=db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_QUIET)) != DIR_NULL )
00171                 ++dp->d_nref;
00172 }
00173 
00174 
00175 /**
00176  *                      D B _ U P D A T E _ N R E F
00177  *
00178  * Updates the d_nref fields (which count the number of times a given entry
00179  * is referenced by a COMBination in the database).
00180  *
00181  */
00182 
00183 void
00184 db_update_nref( struct db_i *dbip, struct resource *resp )
00185 {
00186         register int                    i;
00187         register struct directory      *dp;
00188         struct rt_db_internal           intern;
00189         struct rt_comb_internal        *comb;
00190 
00191         RT_CK_DBI( dbip );
00192         RT_CK_RESOURCE(resp);
00193 
00194         /* First, clear any existing counts */
00195         for( i = 0; i < RT_DBNHASH; i++ )
00196                 for( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw )
00197                         dp->d_nref = 0;
00198 
00199         /* Examine all COMB nodes */
00200         for( i = 0; i < RT_DBNHASH; i++ )  {
00201                 for( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw ){
00202 
00203                         /* handle non-combination objects that reference other objects */
00204                         if( dp->d_major_type == DB5_MAJORTYPE_BRLCAD ) {
00205                                 struct directory *dp2;
00206 
00207                                 if( dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE ) {
00208                                         struct rt_extrude_internal *extr;
00209 
00210                                         if( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
00211                                                 continue;
00212                                         extr = (struct rt_extrude_internal *)intern.idb_ptr;
00213                                         RT_EXTRUDE_CK_MAGIC( extr );
00214                                         if( extr->sketch_name ) {
00215                                                 dp2 = db_lookup( dbip, extr->sketch_name, LOOKUP_QUIET );
00216                                                 if( dp2 != DIR_NULL ) {
00217                                                         dp2->d_nref++;
00218                                                 }
00219                                         }
00220                                         rt_db_free_internal( &intern, resp );
00221                                 } else if( dp->d_minor_type ==  DB5_MINORTYPE_BRLCAD_DSP ) {
00222                                         struct rt_dsp_internal *dsp;
00223 
00224                                         if( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
00225                                                 continue;
00226                                         dsp = (struct rt_dsp_internal *)intern.idb_ptr;
00227                                         RT_DSP_CK_MAGIC( dsp );
00228                                         if( dsp->dsp_datasrc == RT_DSP_SRC_OBJ && bu_vls_strlen( &dsp->dsp_name) > 0 ) {
00229                                                 dp2 = db_lookup( dbip, bu_vls_addr( &dsp->dsp_name ), LOOKUP_QUIET );
00230                                                 if( dp2 != DIR_NULL ) {
00231                                                         dp2->d_nref++;
00232                                                 }
00233                                         }
00234                                         rt_db_free_internal( &intern, resp );
00235                                 }
00236                         }
00237                         if( !(dp->d_flags & DIR_COMB) )
00238                                 continue;
00239                         if( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
00240                                 continue;
00241                         if( intern.idb_type != ID_COMBINATION )  {
00242                                 bu_log("NOTICE: %s was marked a combination, but isn't one?  Clearing flag\n",
00243                                         dp->d_namep);
00244                                 dp->d_flags &= ~DIR_COMB;
00245                                 rt_db_free_internal( &intern, resp );
00246                                 continue;
00247                         }
00248                         comb = (struct rt_comb_internal *)intern.idb_ptr;
00249                         db_tree_funcleaf( dbip, comb, comb->tree,
00250                                           db_count_refs, (genptr_t)NULL,
00251                                           (genptr_t)NULL, (genptr_t)NULL );
00252                         rt_db_free_internal( &intern, resp );
00253                 }
00254         }
00255 }
00256 
00257 /*@}*/
00258 /*
00259  * Local Variables:
00260  * mode: C
00261  * tab-width: 8
00262  * c-basic-offset: 4
00263  * indent-tabs-mode: t
00264  * End:
00265  * ex: shiftwidth=4 tabstop=8
00266  */

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