Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/build/jam_src/search.c @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 5.5 KB
Line 
1/*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/*  This file is ALSO:
8 *  Copyright 2001-2004 David Abrahams.
9 *  Distributed under the Boost Software License, Version 1.0.
10 *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11 */
12
13# include "jam.h"
14# include "lists.h"
15# include "search.h"
16# include "timestamp.h"
17# include "pathsys.h"
18# include "variable.h"
19# include "newstr.h"
20# include "compile.h"
21# include "strings.h"
22# include "hash.h"
23# include <string.h>
24
25typedef struct _binding {
26    char* binding;
27    char* target;
28} BINDING;
29
30static struct hash *explicit_bindings = 0;
31
32void call_bind_rule(
33    char* target_,
34    char* boundname_ )
35{
36    LIST* bind_rule = var_get( "BINDRULE" );
37    if( bind_rule )
38    {
39        /* No guarantee that target is an allocated string, so be on the
40         * safe side */
41        char* target = copystr( target_ );
42       
43        /* Likewise, don't rely on implementation details of newstr.c: allocate
44         * a copy of boundname */
45        char* boundname = copystr( boundname_ );
46        if( boundname && target )
47        {
48            /* Prepare the argument list */
49            FRAME frame[1];
50            frame_init( frame );
51                   
52            /* First argument is the target name */
53            lol_add( frame->args, list_new( L0, target ) );
54                   
55            lol_add( frame->args, list_new( L0, boundname ) );
56            if( lol_get( frame->args, 1 ) )
57                evaluate_rule( bind_rule->string, frame );
58           
59            /* Clean up */
60            frame_free( frame );
61        }
62        else
63        {
64            if( boundname )
65                freestr( boundname );
66            if( target )
67                freestr( target );
68        }
69    }
70}
71
72/*
73 * search.c - find a target along $(SEARCH) or $(LOCATE)
74 * First, check if LOCATE is set. If so, use it to determine
75 * the location of target and return, regardless of whether anything
76 * exists on that location.
77 *
78 * Second, examine all directories in SEARCH. If there's file already
79 * or there's another target with the same name which was placed
80 * to this location via LOCATE setting, stop and return the location.
81 * In case of previous target, return it's name via the third argument.
82 *
83 * This bevahiour allow to handle dependency on generated files. If
84 * caller does not expect that target is generated, 0 can be passed as
85 * the third argument.
86 */
87
88char *
89search( 
90    char *target,
91    time_t *time,
92    char **another_target
93)
94{
95        PATHNAME f[1];
96    LIST    *varlist;
97    string    buf[1];
98    int     found = 0;
99    /* Will be set to 1 if target location is specified via LOCATE. */
100    int     explicitly_located = 0;
101    char    *boundname = 0;
102
103    if( another_target )
104        *another_target = 0;
105
106    if (! explicit_bindings )
107        explicit_bindings = hashinit( sizeof(BINDING), 
108                                     "explicitly specified locations");
109
110    string_new( buf );
111    /* Parse the filename */
112
113        path_parse( target, f );
114
115    f->f_grist.ptr = 0;
116    f->f_grist.len = 0;
117
118    if( varlist = var_get( "LOCATE" ) )
119      {
120        f->f_root.ptr = varlist->string;
121        f->f_root.len = strlen( varlist->string );
122
123            path_build( f, buf, 1 );
124
125        if( DEBUG_SEARCH )
126            printf( "locate %s: %s\n", target, buf->value );
127
128        explicitly_located = 1;
129
130        timestamp( buf->value, time );
131        found = 1;
132    }
133    else if( varlist = var_get( "SEARCH" ) )
134    {
135        while( varlist )
136        {
137            BINDING b, *ba = &b;
138
139            f->f_root.ptr = varlist->string;
140            f->f_root.len = strlen( varlist->string );
141
142            string_truncate( buf, 0 );
143            path_build( f, buf, 1 );
144
145            if( DEBUG_SEARCH )
146                printf( "search %s: %s\n", target, buf->value );
147
148            timestamp( buf->value, time );
149
150            b.binding = buf->value;
151           
152            if( hashcheck( explicit_bindings, (HASHDATA**)&ba ) )
153            {
154                if( DEBUG_SEARCH )
155                    printf(" search %s: found explicitly located target %s\n", 
156                           target, ba->target);
157                if( another_target )
158                    *another_target = ba->target;
159                found = 1;
160                break;               
161            }
162            else if( *time )
163            {
164                found = 1;
165                break;
166            }
167
168            varlist = list_next( varlist );
169        }
170    }
171
172    if (!found)
173    {
174        /* Look for the obvious */
175        /* This is a questionable move.  Should we look in the */
176        /* obvious place if SEARCH is set? */
177
178        f->f_root.ptr = 0;
179        f->f_root.len = 0;
180
181        string_truncate( buf, 0 );
182        path_build( f, buf, 1 );
183
184        if( DEBUG_SEARCH )
185            printf( "search %s: %s\n", target, buf->value );
186
187        timestamp( buf->value, time );
188    }
189
190    boundname = newstr( buf->value );
191    string_free( buf );
192
193    if (explicitly_located)
194    {
195        BINDING b, *ba = &b;
196        b.binding = boundname;
197        b.target = target;
198        /* CONSIDER: we probably should issue a warning is another file
199           is explicitly bound to the same location. This might break
200           compatibility, though. */
201        hashenter(explicit_bindings, (HASHDATA**)&ba);
202    }
203       
204    /* prepare a call to BINDRULE if the variable is set */
205    call_bind_rule( target, boundname );
206
207    return boundname;
208}
Note: See TracBrowser for help on using the repository browser.