00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef lint
00042 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db_path.c,v 14.10 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 <math.h>
00051 #ifdef HAVE_STRING_H
00052 #include <string.h>
00053 #else
00054 #include <strings.h>
00055 #endif
00056
00057 #include "machine.h"
00058 #include "vmath.h"
00059 #include "raytrace.h"
00060
00061 #include "./debug.h"
00062
00063
00064
00065
00066 void
00067 db_full_path_init( struct db_full_path *pathp )
00068 {
00069 pathp->fp_len = 0;
00070 pathp->fp_maxlen = 0;
00071 pathp->fp_names = (struct directory **)NULL;
00072 pathp->magic = DB_FULL_PATH_MAGIC;
00073 }
00074
00075
00076
00077
00078 void
00079 db_add_node_to_full_path( struct db_full_path *pp, struct directory *dp )
00080 {
00081 RT_CK_FULL_PATH( pp );
00082
00083 if( pp->fp_maxlen <= 0 ) {
00084 pp->fp_maxlen = 32;
00085 pp->fp_names = (struct directory **)bu_malloc(
00086 pp->fp_maxlen * sizeof(struct directory *),
00087 "db_full_path array");
00088 } else if( pp->fp_len >= pp->fp_maxlen ) {
00089 pp->fp_maxlen *= 4;
00090 pp->fp_names = (struct directory **)rt_realloc(
00091 (char *)pp->fp_names,
00092 pp->fp_maxlen * sizeof(struct directory *),
00093 "enlarged db_full_path array");
00094 }
00095 pp->fp_names[pp->fp_len++] = dp;
00096 }
00097
00098
00099
00100
00101 void
00102 db_dup_full_path(register struct db_full_path *newp, register const struct db_full_path *oldp)
00103 {
00104 RT_CK_FULL_PATH(newp);
00105 RT_CK_FULL_PATH(oldp);
00106
00107 newp->fp_maxlen = oldp->fp_maxlen;
00108 newp->fp_len = oldp->fp_len;
00109 if( oldp->fp_len <= 0 ) {
00110 newp->fp_names = (struct directory **)0;
00111 return;
00112 }
00113 newp->fp_names = (struct directory **)bu_malloc(
00114 newp->fp_maxlen * sizeof(struct directory *),
00115 "db_full_path array (duplicate)" );
00116 bcopy( (char *)oldp->fp_names, (char *)newp->fp_names,
00117 newp->fp_len * sizeof(struct directory *) );
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127 void
00128 db_extend_full_path( struct db_full_path *pathp, int incr )
00129 {
00130 int newlen;
00131
00132 RT_CK_FULL_PATH(pathp);
00133
00134 if( pathp->fp_maxlen <= 0 ) {
00135 pathp->fp_len = 0;
00136 pathp->fp_maxlen = incr;
00137 pathp->fp_names = (struct directory **)bu_malloc(
00138 pathp->fp_maxlen * sizeof(struct directory *),
00139 "empty fp_names extension" );
00140 return;
00141 }
00142
00143 newlen = pathp->fp_len + incr;
00144 if( pathp->fp_maxlen < newlen ) {
00145 pathp->fp_maxlen = newlen+1;
00146 pathp->fp_names = (struct directory **)rt_realloc(
00147 (char *)pathp->fp_names,
00148 pathp->fp_maxlen * sizeof(struct directory *),
00149 "fp_names extension" );
00150 }
00151 }
00152
00153
00154
00155
00156 void
00157 db_append_full_path( struct db_full_path *dest, const struct db_full_path *src )
00158 {
00159 RT_CK_FULL_PATH(dest);
00160 RT_CK_FULL_PATH(src);
00161
00162 db_extend_full_path( dest, src->fp_len );
00163 bcopy( (char *)&src->fp_names[0],
00164 (char *)&dest->fp_names[dest->fp_len],
00165 src->fp_len * sizeof(struct directory *) );
00166 dest->fp_len += src->fp_len;
00167 }
00168
00169
00170
00171
00172
00173
00174 void
00175 db_dup_path_tail(register struct db_full_path *newp, register const struct db_full_path *oldp, int start)
00176 {
00177 RT_CK_FULL_PATH(newp);
00178 RT_CK_FULL_PATH(oldp);
00179
00180 if( start < 0 || start > oldp->fp_len-1 ) rt_bomb("db_dup_path_tail: start offset out of range\n");
00181
00182 newp->fp_maxlen = newp->fp_len = oldp->fp_len - start;
00183 if( newp->fp_len <= 0 ) {
00184 newp->fp_names = (struct directory **)0;
00185 return;
00186 }
00187 newp->fp_names = (struct directory **)bu_malloc(
00188 newp->fp_maxlen * sizeof(struct directory *),
00189 "db_full_path array (duplicate)" );
00190 bcopy( (char *)&oldp->fp_names[start], (char *)newp->fp_names,
00191 newp->fp_len * sizeof(struct directory *) );
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 char *
00201 db_path_to_string( const struct db_full_path *pp )
00202 {
00203 register char *cp;
00204 char *buf;
00205 int len;
00206 int i;
00207
00208 RT_CK_FULL_PATH( pp );
00209
00210 len = 3;
00211 for( i=pp->fp_len-1; i >= 0; i-- ) {
00212 if( pp->fp_names[i] )
00213 len += strlen( pp->fp_names[i]->d_namep ) + 1;
00214 else
00215 len += 16;
00216 }
00217
00218 buf = bu_malloc( len, "pathname string" );
00219 cp = buf;
00220
00221 for( i=0; i < pp->fp_len; i++ ) {
00222 *cp++ = '/';
00223 if( pp->fp_names[i] )
00224 strcpy( cp, pp->fp_names[i]->d_namep );
00225 else
00226 strcpy( cp, "**NULL**" );
00227 cp += strlen( cp );
00228 }
00229 *cp++ = '\0';
00230 return buf;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240 void
00241 db_path_to_vls( struct bu_vls *str, const struct db_full_path *pp )
00242 {
00243 register int i;
00244
00245 BU_CK_VLS(str);
00246 RT_CK_FULL_PATH( pp );
00247
00248 for( i=0; i < pp->fp_len; i++ ) {
00249 bu_vls_putc( str, '/' );
00250 if( pp->fp_names[i] )
00251 bu_vls_strcat( str, pp->fp_names[i]->d_namep );
00252 else
00253 bu_vls_strcat( str, "**NULL**" );
00254 }
00255 }
00256
00257
00258
00259
00260 void
00261 db_pr_full_path( const char *msg, const struct db_full_path *pathp )
00262 {
00263 char *sofar = db_path_to_string(pathp);
00264
00265 bu_log("%s %s\n", msg, sofar );
00266 bu_free(sofar, "path string");
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 int
00282 db_string_to_path(struct db_full_path *pp, const struct db_i *dbip, const char *str)
00283 {
00284 register char *cp;
00285 register char *slashp;
00286 struct directory *dp;
00287 char *copy;
00288 int nslash = 0;
00289 int ret = 0;
00290 int len;
00291
00292 RT_CK_DBI(dbip);
00293
00294
00295 while( *str == '/' ) str++;
00296 if( *str == '\0' ) {
00297
00298 db_full_path_init( pp );
00299 return 0;
00300 }
00301
00302 copy = bu_strdup( str );
00303
00304
00305 len = strlen( copy );
00306 if( copy[len-1] == '/' )
00307 copy[len-1] = '\0';
00308
00309 cp = copy;
00310 while( *cp ) {
00311 if( (slashp = strchr( cp, '/' )) == NULL ) break;
00312 nslash++;
00313 cp = slashp+1;
00314 }
00315
00316
00317 pp->magic = DB_FULL_PATH_MAGIC;
00318 pp->fp_maxlen = pp->fp_len = nslash+1;
00319 pp->fp_names = (struct directory **)bu_malloc(
00320 pp->fp_maxlen * sizeof(struct directory *),
00321 "db_string_to_path path array" );
00322
00323
00324
00325 cp = copy;
00326 nslash = 0;
00327 while( *cp ) {
00328 if( (slashp = strchr( cp, '/' )) == NULL ) {
00329
00330 slashp = cp + strlen(cp) - 1;
00331 } else {
00332 *slashp = '\0';
00333 }
00334 if( (dp = db_lookup( dbip, cp, LOOKUP_NOISY )) == DIR_NULL ) {
00335 bu_log("db_string_to_path() of '%s' failed on '%s'\n",
00336 str, cp );
00337 ret = -1;
00338
00339 }
00340 pp->fp_names[nslash++] = dp;
00341 cp = slashp+1;
00342 }
00343 BU_ASSERT_LONG( nslash, ==, pp->fp_len );
00344 bu_free( copy, "db_string_to_path() duplicate string");
00345 return ret;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 int
00361 db_argv_to_path(register struct db_full_path *pp, struct db_i *dbip, int argc, const char *const *argv)
00362 {
00363 struct directory *dp;
00364 int ret = 0;
00365 int i;
00366
00367 RT_CK_DBI(dbip);
00368
00369
00370 pp->magic = DB_FULL_PATH_MAGIC;
00371 pp->fp_maxlen = pp->fp_len = argc;
00372 pp->fp_names = (struct directory **)bu_malloc(
00373 pp->fp_maxlen * sizeof(struct directory *),
00374 "db_argv_to_path path array" );
00375
00376 for( i=0; i<argc; i++ ) {
00377 if( (dp = db_lookup( dbip, argv[i], LOOKUP_NOISY )) == DIR_NULL ) {
00378 bu_log("db_argv_to_path() failed on element %d='%s'\n",
00379 i, argv[i] );
00380 ret = -1;
00381
00382 }
00383 pp->fp_names[i] = dp;
00384 }
00385 return ret;
00386 }
00387
00388
00389
00390
00391
00392
00393
00394 void
00395 db_free_full_path(register struct db_full_path *pp)
00396 {
00397 RT_CK_FULL_PATH( pp );
00398
00399 if( pp->fp_maxlen > 0 ) {
00400 bu_free( (char *)pp->fp_names, "db_full_path array" );
00401 pp->fp_maxlen = pp->fp_len = 0;
00402 pp->fp_names = (struct directory **)0;
00403 }
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413 int
00414 db_identical_full_paths(
00415 const struct db_full_path *a,
00416 const struct db_full_path *b )
00417 {
00418 register int i;
00419
00420 RT_CK_FULL_PATH(a);
00421 RT_CK_FULL_PATH(b);
00422
00423 if( a->fp_len != b->fp_len ) return 0;
00424
00425 for( i = a->fp_len-1; i >= 0; i-- ) {
00426 if( a->fp_names[i] != b->fp_names[i] ) return 0;
00427 }
00428 return 1;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 int
00439 db_full_path_subset(
00440 const struct db_full_path *a,
00441 const struct db_full_path *b )
00442 {
00443 register int i;
00444
00445 RT_CK_FULL_PATH(a);
00446 RT_CK_FULL_PATH(b);
00447
00448 if( b->fp_len > a->fp_len ) return 0;
00449
00450 for( i=0; i < a->fp_len; i++ ) {
00451 register int j;
00452
00453 if( a->fp_names[i] != b->fp_names[0] ) continue;
00454
00455
00456 if( b->fp_len > a->fp_len - i ) return 0;
00457
00458
00459 for( j=1; j < b->fp_len; j++ ) {
00460 if( a->fp_names[i+j] != b->fp_names[j] ) goto step;
00461 }
00462
00463 return 1;
00464
00465 step: ;
00466 }
00467 return 0;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477 int
00478 db_full_path_search( const struct db_full_path *a, const struct directory *dp )
00479 {
00480 register int i;
00481
00482 RT_CK_FULL_PATH(a);
00483 RT_CK_DIR(dp);
00484
00485 for( i = a->fp_len-1; i >= 0; i-- ) {
00486 if( a->fp_names[i] == dp ) return 1;
00487 }
00488 return 0;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500