The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

search.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
00003  *
00004  * This file is part of Jam - see jam.c for Copyright information.
00005  */
00006 
00007 /*  This file is ALSO:
00008  *  (C) Copyright David Abrahams 2001. Permission to copy, use,
00009  *  modify, sell and distribute this software is granted provided this
00010  *  copyright notice appears in all copies. This software is provided
00011  *  "as is" without express or implied warranty, and with no claim as
00012  *  to its suitability for any purpose.
00013  */
00014 
00015 # include "jam.h"
00016 # include "lists.h"
00017 # include "search.h"
00018 # include "timestamp.h"
00019 # include "pathsys.h"
00020 # include "variable.h"
00021 # include "newstr.h"
00022 # include "compile.h"
00023 # include "strings.h"
00024 # include "hash.h"
00025 # include <string.h>
00026 
00027 typedef struct _binding {
00028     char* binding;
00029     char* target;
00030 } BINDING;
00031 
00032 static struct hash *explicit_bindings = 0;
00033 
00034 void call_bind_rule(
00035     char* target_,
00036     char* boundname_ )
00037 {
00038     LIST* bind_rule = var_get( "BINDRULE" );
00039     if( bind_rule )
00040     {
00041         /* No guarantee that target is an allocated string, so be on the
00042          * safe side */
00043         char* target = copystr( target_ );
00044         
00045         /* Likewise, don't rely on implementation details of newstr.c: allocate
00046          * a copy of boundname */
00047         char* boundname = copystr( boundname_ );
00048         if( boundname && target )
00049         {
00050             /* Prepare the argument list */
00051             FRAME frame[1];
00052             frame_init( frame );
00053                     
00054             /* First argument is the target name */
00055             lol_add( frame->args, list_new( L0, target ) );
00056                     
00057             lol_add( frame->args, list_new( L0, boundname ) );
00058             if( lol_get( frame->args, 1 ) )
00059                 evaluate_rule( bind_rule->string, frame );
00060             
00061             /* Clean up */
00062             frame_free( frame );
00063         }
00064         else
00065         {
00066             if( boundname )
00067                 freestr( boundname );
00068             if( target )
00069                 freestr( target );
00070         }
00071     }
00072 }
00073 
00074 /*
00075  * search.c - find a target along $(SEARCH) or $(LOCATE) 
00076  * First, check if LOCATE is set. If so, use it to determine
00077  * the location of target and return, regardless of whether anything
00078  * exists on that location.
00079  *
00080  * Second, examine all directories in SEARCH. If there's file already
00081  * or there's another target with the same name which was placed
00082  * to this location via LOCATE setting, stop and return the location. 
00083  * In case of previous target, return it's name via the third argument.
00084  *
00085  * This bevahiour allow to handle dependency on generated files. If
00086  * caller does not expect that target is generated, 0 can be passed as
00087  * the third argument.
00088  */
00089 
00090 char *
00091 search( 
00092     char *target,
00093     time_t *time,
00094     char **another_target
00095 )
00096 {
00097         PATHNAME f[1];
00098     LIST    *varlist;
00099     string    buf[1];
00100     int     found = 0;
00101     /* Will be set to 1 if target location is specified via LOCATE. */
00102     int     explicitly_located = 0;
00103     char    *boundname = 0;
00104 
00105     if( another_target )
00106         *another_target = 0;
00107 
00108     if (! explicit_bindings )
00109         explicit_bindings = hashinit( sizeof(BINDING), 
00110                                      "explicitly specified locations");
00111 
00112     string_new( buf );
00113     /* Parse the filename */
00114 
00115         path_parse( target, f );
00116 
00117     f->f_grist.ptr = 0;
00118     f->f_grist.len = 0;
00119 
00120     if( varlist = var_get( "LOCATE" ) )
00121       {
00122         f->f_root.ptr = varlist->string;
00123         f->f_root.len = strlen( varlist->string );
00124 
00125             path_build( f, buf, 1 );
00126 
00127         if( DEBUG_SEARCH )
00128             printf( "locate %s: %s\n", target, buf->value );
00129 
00130         explicitly_located = 1;
00131 
00132         timestamp( buf->value, time );
00133         found = 1;
00134     }
00135     else if( varlist = var_get( "SEARCH" ) )
00136     {
00137         while( varlist )
00138         {
00139             BINDING b, *ba = &b;
00140 
00141             f->f_root.ptr = varlist->string;
00142             f->f_root.len = strlen( varlist->string );
00143 
00144             string_truncate( buf, 0 );
00145             path_build( f, buf, 1 );
00146 
00147             if( DEBUG_SEARCH )
00148                 printf( "search %s: %s\n", target, buf->value );
00149 
00150             timestamp( buf->value, time );
00151 
00152             b.binding = buf->value;
00153             
00154             if( hashcheck( explicit_bindings, (HASHDATA**)&ba ) )
00155             {
00156                 if( DEBUG_SEARCH )
00157                     printf(" search %s: found explicitly located target %s\n", 
00158                            target, ba->target);
00159                 if( another_target )
00160                     *another_target = ba->target;
00161                 found = 1;
00162                 break;                
00163             }
00164             else if( *time )
00165             {
00166                 found = 1;
00167                 break;
00168             }
00169 
00170             varlist = list_next( varlist );
00171         }
00172     }
00173 
00174     if (!found)
00175     {
00176         /* Look for the obvious */
00177         /* This is a questionable move.  Should we look in the */
00178         /* obvious place if SEARCH is set? */
00179 
00180         f->f_root.ptr = 0;
00181         f->f_root.len = 0;
00182 
00183         string_truncate( buf, 0 );
00184         path_build( f, buf, 1 );
00185 
00186         if( DEBUG_SEARCH )
00187             printf( "search %s: %s\n", target, buf->value );
00188 
00189         timestamp( buf->value, time );
00190     }
00191 
00192     boundname = newstr( buf->value );
00193     string_free( buf );
00194 
00195     if (explicitly_located)
00196     {
00197         BINDING b, *ba = &b;
00198         b.binding = boundname;
00199         b.target = target;
00200         /* CONSIDER: we probably should issue a warning is another file
00201            is explicitly bound to the same location. This might break
00202            compatibility, though. */
00203         hashenter(explicit_bindings, (HASHDATA**)&ba);
00204     }
00205         
00206     /* prepare a call to BINDRULE if the variable is set */
00207     call_bind_rule( target, boundname );
00208 
00209     return boundname;
00210 }

Generated on Mon Nov 8 17:07:52 2004 for MPT by  doxygen 1.3.9.1