mirror of
https://github.com/boostorg/build.git
synced 2026-02-17 01:32:12 +00:00
Minor stylistic changes throughout Boost Jam sources. Mostly corrected indentation, removed trailing spaces and updated comments.
[SVN r48445]
This commit is contained in:
@@ -11,9 +11,9 @@ Packager: Rene Rivera <grafik@redshift-software.com>
|
||||
BuildRoot: /var/tmp/%{name}-%{version}.root
|
||||
|
||||
%description
|
||||
Boost Jam is a build tool based on FTJam, which in turn is based on
|
||||
Boost Jam is a build tool based on FTJam, which in turn is based on
|
||||
Perforce Jam. It contains significant improvements made to facilitate
|
||||
its use in the Boost Build System, but should be backward compatible
|
||||
its use in the Boost Build System, but should be backward compatible
|
||||
with Perforce Jam.
|
||||
|
||||
Authors:
|
||||
@@ -26,7 +26,7 @@ Copyright:
|
||||
+\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
||||
\+/
|
||||
License is hereby granted to use this software and distribute it
|
||||
freely, as long as this copyright notice is retained and modifications
|
||||
freely, as long as this copyright notice is retained and modifications
|
||||
are clearly marked.
|
||||
ALL WARRANTIES ARE HEREBY DISCLAIMED.
|
||||
|
||||
@@ -34,7 +34,7 @@ Also:
|
||||
Copyright 2001-2006 David Abrahams.
|
||||
Copyright 2002-2006 Rene Rivera.
|
||||
Copyright 2003-2006 Vladimir Prus.
|
||||
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
@@ -380,7 +380,7 @@ set BJAM_SOURCES=%BJAM_SOURCES% hdrmacro.c headers.c jam.c jambase.c jamgram.c l
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% newstr.c option.c output.c parse.c pathunix.c regexp.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% rules.c scan.c search.c subst.c timestamp.c variable.c modules.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% strings.c filesys.c builtins.c pwd.c class.c w32_getreg.c native.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% modules/set.c modules/path.c modules/regex.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% modules/set.c modules/path.c modules/regex.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% modules/property-set.c modules/sequence.c modules/order.c
|
||||
|
||||
set BJAM_UPDATE=
|
||||
|
||||
@@ -10,7 +10,7 @@ else if $(MAC) { rule .path { return ":$(<:J=\:)" ; } }
|
||||
else { rule .path { return "$(<:J=/)" ; } }
|
||||
if $(VMS) { . = "_" ; }
|
||||
else { . = "." ; }
|
||||
./ ?= "" ;
|
||||
./ ?= "" ;
|
||||
|
||||
# Info about what we are building.
|
||||
_VERSION_ = 3 1 17 ;
|
||||
@@ -341,13 +341,12 @@ toolset vmsdecc link .link : /EXECUTABLE= :
|
||||
toolset = [ MATCH --toolset=(.*) : $(ARGV) ] ;
|
||||
if ! $(toolset)
|
||||
{
|
||||
# For some reason, the following test does not catch
|
||||
# empty toolset.
|
||||
# For some reason, the following test does not catch empty toolset.
|
||||
ECHO "###" ;
|
||||
ECHO "###" No toolset specified. Please use --toolset option. ;
|
||||
ECHO "###" ;
|
||||
ECHO "###" Known toolsets are: $(toolsets:J=", ") ;
|
||||
EXIT "###" ;
|
||||
EXIT "###" ;
|
||||
}
|
||||
if ! $(toolset) in $(toolsets)
|
||||
{
|
||||
@@ -449,8 +448,8 @@ jam.source =
|
||||
lists.c make.c make1.c mem.c newstr.c
|
||||
option.c output.c parse.c regexp.c rules.c
|
||||
scan.c search.c subst.c w32_getreg.c
|
||||
timestamp.c variable.c modules.c strings.c filesys.c
|
||||
builtins.c pwd.c class.c native.c modules/set.c
|
||||
timestamp.c variable.c modules.c strings.c filesys.c
|
||||
builtins.c pwd.c class.c native.c modules/set.c
|
||||
modules/path.c modules/regex.c modules/property-set.c
|
||||
modules/sequence.c modules/order.c
|
||||
;
|
||||
@@ -461,7 +460,7 @@ if $(NT)
|
||||
else if $(OS2)
|
||||
{
|
||||
jam.source += execunix.c fileos2.c pathunix.c ;
|
||||
}
|
||||
}
|
||||
else if $(VMS)
|
||||
{
|
||||
jam.source += execvms.c filevms.c pathvms.c ;
|
||||
@@ -770,7 +769,7 @@ rule .jam
|
||||
{
|
||||
$(>).exe = [ .exe $(>) : $(jam.source) ] ;
|
||||
DEPENDS all : $($(>).exe) ;
|
||||
|
||||
|
||||
if $(debug)
|
||||
{
|
||||
$(<).exe = $(<:S=$($(>).exe:S)) ;
|
||||
@@ -929,14 +928,14 @@ rule .package ( dst-dir : src-files + )
|
||||
src-files-actual += $(src-path) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local pack = ;
|
||||
if $(NT) { pack = $(dst-dir).zip ; }
|
||||
if $(UNIX) { pack = $(dst-dir).tgz ; }
|
||||
|
||||
|
||||
DEPENDS dist : $(pack) ;
|
||||
DEPENDS $(pack) : $(dst-files) ;
|
||||
|
||||
|
||||
local dst-files-queue = $(dst-files) ;
|
||||
for local src-path in $(src-files-actual)
|
||||
{
|
||||
@@ -944,11 +943,11 @@ rule .package ( dst-dir : src-files + )
|
||||
dst-files-queue = $(dst-files-queue[2-]) ;
|
||||
DEPENDS $(dst-file) : $(src-path) $(dst-file:D) ;
|
||||
.mkdir $(dst-file:D) ;
|
||||
|
||||
|
||||
[COPY] $(dst-file) : $(src-path) ;
|
||||
.clean $(dst-file) ;
|
||||
}
|
||||
|
||||
|
||||
[PACK] $(pack) : $(dst-files) ;
|
||||
.clean $(pack) ;
|
||||
}
|
||||
|
||||
@@ -127,15 +127,15 @@ case $BOOST_JAM_TOOLSET in
|
||||
fi
|
||||
BOOST_JAM_CC="gcc -DNT"
|
||||
;;
|
||||
|
||||
|
||||
gcc)
|
||||
BOOST_JAM_CC=gcc
|
||||
;;
|
||||
|
||||
|
||||
darwin)
|
||||
BOOST_JAM_CC=cc
|
||||
;;
|
||||
|
||||
|
||||
intel-linux)
|
||||
if test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then
|
||||
BOOST_JAM_TOOLSET_ROOT=/opt/intel/cc/9.0/
|
||||
@@ -164,35 +164,35 @@ case $BOOST_JAM_TOOLSET in
|
||||
fi
|
||||
BOOST_JAM_CC=icc
|
||||
;;
|
||||
|
||||
|
||||
vacpp)
|
||||
BOOST_JAM_CC=xlc
|
||||
;;
|
||||
|
||||
|
||||
como)
|
||||
BOOST_JAM_CC="como --c"
|
||||
;;
|
||||
|
||||
|
||||
kcc)
|
||||
BOOST_JAM_CC=KCC
|
||||
;;
|
||||
|
||||
|
||||
kylix)
|
||||
BOOST_JAM_CC=bc++
|
||||
;;
|
||||
|
||||
|
||||
mipspro)
|
||||
BOOST_JAM_CC=cc
|
||||
;;
|
||||
|
||||
|
||||
pathscale)
|
||||
BOOST_JAM_CC=pathcc
|
||||
;;
|
||||
|
||||
|
||||
pgi)
|
||||
BOOST_JAM_CC=pgcc
|
||||
;;
|
||||
|
||||
|
||||
sun*)
|
||||
if test -z "${BOOST_JAM_TOOLSET_ROOT}" -a -r /opt/SUNWspro/bin/cc ; then
|
||||
BOOST_JAM_TOOLSET_ROOT=/opt/SUNWspro/
|
||||
@@ -203,15 +203,15 @@ case $BOOST_JAM_TOOLSET in
|
||||
fi
|
||||
BOOST_JAM_CC=cc
|
||||
;;
|
||||
|
||||
|
||||
tru64cxx)
|
||||
BOOST_JAM_CC=cc
|
||||
;;
|
||||
|
||||
|
||||
acc)
|
||||
BOOST_JAM_CC="cc -Ae"
|
||||
;;
|
||||
|
||||
|
||||
cc)
|
||||
if test -z "$CC" ; then CC=cc ; fi
|
||||
BOOST_JAM_CC=$CC
|
||||
@@ -219,11 +219,11 @@ case $BOOST_JAM_TOOLSET in
|
||||
BOOST_JAM_OPT_MKJAMBASE="$BOOST_JAM_OPT_MKJAMBASE $CFLAGS $LIBS"
|
||||
BOOST_JAM_OPT_YYACC="$BOOST_JAM_OPT_YYACC $CFLAGS $LIBS"
|
||||
;;
|
||||
|
||||
|
||||
qcc)
|
||||
BOOST_JAM_CC=qcc
|
||||
;;
|
||||
|
||||
|
||||
*)
|
||||
error_exit "Unknown toolset: $BOOST_JAM_TOOLSET"
|
||||
;;
|
||||
@@ -247,7 +247,7 @@ case $BOOST_JAM_TOOLSET in
|
||||
mingw)
|
||||
BJAM_SOURCES="${BJAM_SOURCES} execnt.c filent.c"
|
||||
;;
|
||||
|
||||
|
||||
*)
|
||||
BJAM_SOURCES="${BJAM_SOURCES} execunix.c fileunix.c"
|
||||
;;
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
$ ! Copyright 2002-2003 Rene Rivera, Johan Nilsson.
|
||||
$ ! Distributed under the Boost Software License, Version 1.0.
|
||||
$ ! (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
$ !
|
||||
$ !
|
||||
$ ! bootstrap build script for Jam
|
||||
$ !
|
||||
$ !
|
||||
$ SAY :== WRITE SYS$OUTPUT
|
||||
$ !
|
||||
$ !
|
||||
$ ON WARNING THEN CONTINUE
|
||||
$ !
|
||||
$ !
|
||||
$ IF "" .NES. F$SEARCH("[.bootstrap_vms]*.*")
|
||||
$ THEN
|
||||
$ SAY "Cleaning previous boostrap files..."
|
||||
$ !
|
||||
$ !
|
||||
$ SET FILE/PROTECTION=(S:RWED) [.bootstrap_vms]*.*;*
|
||||
$ DELETE [.bootstrap_vms]*.*;*
|
||||
$ ENDIF
|
||||
$ !
|
||||
$ !
|
||||
$ IF "" .NES. F$SEARCH("bootstrap_vms.dir")
|
||||
$ THEN
|
||||
$ SAY "Removing previous boostrap directory..."
|
||||
$ !
|
||||
$ !
|
||||
$ SET FILE/PROT=(S:RWED) bootstrap_vms.dir
|
||||
$ DELETE bootstrap_vms.dir;
|
||||
$ ENDIF
|
||||
$ !
|
||||
$ !
|
||||
$ SAY "Creating boostrap directory..."
|
||||
$ !
|
||||
$ !
|
||||
$ CREATE/DIR [.bootstrap_vms]
|
||||
$ !
|
||||
$ !
|
||||
$ SAY "Building bootstrap jam..."
|
||||
$ !
|
||||
$ !
|
||||
$ CC_FLAGS = "/DEFINE=VMS /STANDARD=VAXC /PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES "
|
||||
$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]builtins.obj builtins.c
|
||||
$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]command.obj command.c
|
||||
@@ -95,11 +95,11 @@ $ link -
|
||||
[.bootstrap_vms]subst.obj, -
|
||||
[.bootstrap_vms]timestamp.obj, -
|
||||
[.bootstrap_vms]variable.obj
|
||||
$ !
|
||||
$ !
|
||||
$ SAY "Cleaning any previous build..."
|
||||
$ !
|
||||
$ !
|
||||
$ MCR [.bootstrap_vms]jam0.exe -f build.jam --toolset=vmsdecc clean
|
||||
$ !
|
||||
$ !
|
||||
$ SAY "Building Boost.Jam..."
|
||||
$ !
|
||||
$ !
|
||||
$ MCR [.bootstrap_vms]jam0.exe -f build.jam --toolset=vmsdecc
|
||||
|
||||
@@ -31,16 +31,16 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* load_builtin() - define builtin rules
|
||||
* load_builtin() - define builtin rules
|
||||
*
|
||||
* Internal routines:
|
||||
*
|
||||
* builtin_depends() - DEPENDS/INCLUDES rule
|
||||
* builtin_echo() - ECHO rule
|
||||
* builtin_exit() - EXIT rule
|
||||
* builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
|
||||
* builtin_glob() - GLOB rule
|
||||
* builtin_match() - MATCH rule
|
||||
* builtin_depends() - DEPENDS/INCLUDES rule
|
||||
* builtin_echo() - ECHO rule
|
||||
* builtin_exit() - EXIT rule
|
||||
* builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
|
||||
* builtin_glob() - GLOB rule
|
||||
* builtin_match() - MATCH rule
|
||||
*
|
||||
* 01/10/01 (seiwald) - split from compile.c
|
||||
*/
|
||||
@@ -417,43 +417,45 @@ builtin_calc(
|
||||
|
||||
LIST *
|
||||
builtin_depends(
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
{
|
||||
LIST *targets = lol_get( frame->args, 0 );
|
||||
LIST *sources = lol_get( frame->args, 1 );
|
||||
LIST *l;
|
||||
LIST *targets = lol_get( frame->args, 0 );
|
||||
LIST *sources = lol_get( frame->args, 1 );
|
||||
LIST *l;
|
||||
|
||||
for( l = targets; l; l = list_next( l ) )
|
||||
{
|
||||
TARGET *t = bindtarget( l->string );
|
||||
for ( l = targets; l; l = list_next( l ) )
|
||||
{
|
||||
TARGET * t = bindtarget( l->string );
|
||||
|
||||
/* If doing INCLUDES, switch to the TARGET's include */
|
||||
/* TARGET, creating it if needed. The internal include */
|
||||
/* TARGET shares the name of its parent. */
|
||||
/* If doing INCLUDES, switch to the TARGET's include */
|
||||
/* TARGET, creating it if needed. The internal include */
|
||||
/* TARGET shares the name of its parent. */
|
||||
|
||||
if( parse->num )
|
||||
{
|
||||
if( !t->includes ) {
|
||||
if ( parse->num )
|
||||
{
|
||||
if ( !t->includes )
|
||||
{
|
||||
t->includes = copytarget( t );
|
||||
t->includes->original_target = t;
|
||||
}
|
||||
t = t->includes;
|
||||
}
|
||||
}
|
||||
|
||||
t->depends = targetlist( t->depends, sources );
|
||||
}
|
||||
t->depends = targetlist( t->depends, sources );
|
||||
}
|
||||
|
||||
/* Enter reverse links */
|
||||
for( l = sources; l; l = list_next( l ) )
|
||||
{
|
||||
TARGET *s = bindtarget( l->string );
|
||||
for ( l = sources; l; l = list_next( l ) )
|
||||
{
|
||||
TARGET * s = bindtarget( l->string );
|
||||
s->dependents = targetlist( s->dependents, targets );
|
||||
}
|
||||
|
||||
return L0;
|
||||
return L0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* builtin_rebuilds() - REBUILDS rule
|
||||
*
|
||||
@@ -464,22 +466,23 @@ builtin_depends(
|
||||
|
||||
LIST *
|
||||
builtin_rebuilds(
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
{
|
||||
LIST *targets = lol_get( frame->args, 0 );
|
||||
LIST *rebuilds = lol_get( frame->args, 1 );
|
||||
LIST *l;
|
||||
LIST *targets = lol_get( frame->args, 0 );
|
||||
LIST *rebuilds = lol_get( frame->args, 1 );
|
||||
LIST *l;
|
||||
|
||||
for( l = targets; l; l = list_next( l ) )
|
||||
{
|
||||
TARGET *t = bindtarget( l->string );
|
||||
t->rebuilds = targetlist( t->rebuilds, rebuilds );
|
||||
}
|
||||
for( l = targets; l; l = list_next( l ) )
|
||||
{
|
||||
TARGET *t = bindtarget( l->string );
|
||||
t->rebuilds = targetlist( t->rebuilds, rebuilds );
|
||||
}
|
||||
|
||||
return L0;
|
||||
return L0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* builtin_echo() - ECHO rule
|
||||
*
|
||||
@@ -489,15 +492,16 @@ builtin_rebuilds(
|
||||
|
||||
LIST *
|
||||
builtin_echo(
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
{
|
||||
list_print( lol_get( frame->args, 0 ) );
|
||||
printf( "\n" );
|
||||
list_print( lol_get( frame->args, 0 ) );
|
||||
printf( "\n" );
|
||||
fflush( stdout );
|
||||
return L0;
|
||||
return L0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* builtin_exit() - EXIT rule
|
||||
*
|
||||
@@ -532,15 +536,15 @@ builtin_exit(
|
||||
|
||||
LIST *
|
||||
builtin_flags(
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
{
|
||||
LIST *l = lol_get( frame->args, 0 );
|
||||
LIST *l = lol_get( frame->args, 0 );
|
||||
|
||||
for( ; l; l = list_next( l ) )
|
||||
bindtarget( l->string )->flags |= parse->num;
|
||||
for( ; l; l = list_next( l ) )
|
||||
bindtarget( l->string )->flags |= parse->num;
|
||||
|
||||
return L0;
|
||||
return L0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -832,23 +836,23 @@ builtin_glob_recursive(
|
||||
|
||||
LIST *
|
||||
builtin_match(
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
{
|
||||
LIST *l, *r;
|
||||
LIST *result = 0;
|
||||
LIST *l, *r;
|
||||
LIST *result = 0;
|
||||
|
||||
string buf[1];
|
||||
string_new(buf);
|
||||
|
||||
/* For each pattern */
|
||||
/* For each pattern */
|
||||
|
||||
for( l = lol_get( frame->args, 0 ); l; l = l->next )
|
||||
{
|
||||
for( l = lol_get( frame->args, 0 ); l; l = l->next )
|
||||
{
|
||||
/* Result is cached and intentionally never freed */
|
||||
regexp *re = regex_compile( l->string );
|
||||
regexp *re = regex_compile( l->string );
|
||||
|
||||
/* For each string to match against */
|
||||
/* For each string to match against */
|
||||
for( r = lol_get( frame->args, 1 ); r; r = r->next )
|
||||
{
|
||||
if( regexec( re, r->string ) )
|
||||
@@ -1170,7 +1174,7 @@ void backtrace_line( FRAME *frame )
|
||||
*/
|
||||
void backtrace( FRAME *frame )
|
||||
{
|
||||
if ( !frame ) return;
|
||||
if ( !frame ) return;
|
||||
while ( frame = frame->prev )
|
||||
{
|
||||
backtrace_line( frame );
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright Vladiir Prus 2003. Distributed under the Boost */
|
||||
/* Copyright Vladimir Prus 2003. Distributed under the Boost */
|
||||
/* Software License, Version 1.0. (See accompanying */
|
||||
/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
|
||||
|
||||
@@ -24,18 +24,19 @@ static void check_defined(LIST* class_names)
|
||||
}
|
||||
}
|
||||
|
||||
static char* class_module_name(char* declared_name)
|
||||
|
||||
static char * class_module_name( char * declared_name )
|
||||
{
|
||||
string name[1];
|
||||
char* result;
|
||||
|
||||
char * result;
|
||||
|
||||
string_new(name);
|
||||
string_append(name, "class@");
|
||||
string_append(name, declared_name);
|
||||
|
||||
result = newstr(name->value);
|
||||
string_free(name);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ static void import_base_rule(void* r_, void* d_)
|
||||
string_new(qualified_name);
|
||||
string_append(qualified_name, d->base_name);
|
||||
string_push_back(qualified_name, '.');
|
||||
string_append(qualified_name, r->name);
|
||||
string_append(qualified_name, r->name);
|
||||
|
||||
ir1 = import_rule(r, d->class_module, r->name);
|
||||
ir2 = import_rule(r, d->class_module, qualified_name->value);
|
||||
@@ -66,11 +67,11 @@ static void import_base_rule(void* r_, void* d_)
|
||||
ir1->exported = ir2->exported = r->exported;
|
||||
|
||||
/* If we're importing class method, localize it. */
|
||||
if (r->module == d->base_module
|
||||
if (r->module == d->base_module
|
||||
|| r->module->class_module && r->module->class_module == d->base_module) {
|
||||
ir1->module = ir2->module = d->class_module;
|
||||
ir1->module = ir2->module = d->class_module;
|
||||
}
|
||||
|
||||
|
||||
string_free(qualified_name);
|
||||
}
|
||||
|
||||
@@ -92,25 +93,28 @@ static void import_base_rules(module_t* class, char* base)
|
||||
import_module( imported_modules(base_module), class );
|
||||
}
|
||||
|
||||
char* make_class_module(LIST* xname, LIST* bases, FRAME* frame)
|
||||
|
||||
char * make_class_module( LIST * xname, LIST * bases, FRAME * frame )
|
||||
{
|
||||
char* name = class_module_name(xname->string);
|
||||
char** pp = &xname->string;
|
||||
module_t* class_module = 0;
|
||||
module_t* outer_module = frame->module;
|
||||
module_t* outer_module = frame->module;
|
||||
|
||||
if (!classes)
|
||||
if ( !classes )
|
||||
classes = hashinit(sizeof(char*), "classes");
|
||||
|
||||
|
||||
if (hashcheck(classes, (HASHDATA**)&pp)) {
|
||||
if ( hashcheck( classes, (HASHDATA**)&pp ) )
|
||||
{
|
||||
printf("Class %s already defined\n", xname->string);
|
||||
abort();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
hashenter(classes, (HASHDATA**)&pp);
|
||||
}
|
||||
check_defined(bases);
|
||||
|
||||
|
||||
class_module = bindmodule(name);
|
||||
|
||||
exit_module( outer_module );
|
||||
@@ -118,14 +122,12 @@ char* make_class_module(LIST* xname, LIST* bases, FRAME* frame)
|
||||
|
||||
var_set("__name__", xname, VAR_SET);
|
||||
var_set("__bases__", bases, VAR_SET);
|
||||
|
||||
|
||||
exit_module( class_module );
|
||||
enter_module( outer_module );
|
||||
|
||||
|
||||
for(; bases; bases = bases->next)
|
||||
import_base_rules(class_module, bases->string);
|
||||
|
||||
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
|
||||
CMD *
|
||||
cmd_new(
|
||||
RULE *rule,
|
||||
LIST *targets,
|
||||
LIST *sources,
|
||||
LIST *shell )
|
||||
RULE *rule,
|
||||
LIST *targets,
|
||||
LIST *sources,
|
||||
LIST *shell )
|
||||
{
|
||||
CMD *cmd = (CMD *)BJAM_MALLOC( sizeof( CMD ) );
|
||||
/* lift line-length limitation entirely when JAMSHELL is just "%" */
|
||||
@@ -54,14 +54,14 @@ cmd_new(
|
||||
do
|
||||
{
|
||||
BJAM_FREE(cmd->buf); /* free any buffer from previous iteration */
|
||||
|
||||
|
||||
cmd->buf = (char*)BJAM_MALLOC_ATOMIC(max_line + 1);
|
||||
|
||||
if (cmd->buf == 0)
|
||||
|
||||
if ( cmd->buf == 0 )
|
||||
break;
|
||||
|
||||
|
||||
allocated = var_string( rule->actions->command, cmd->buf, max_line, &cmd->args );
|
||||
|
||||
|
||||
max_line = max_line * 2;
|
||||
}
|
||||
while( allocated < 0 && max_line < INT_MAX / 2 );
|
||||
@@ -69,18 +69,18 @@ cmd_new(
|
||||
if ( !no_limit )
|
||||
{
|
||||
/* Bail if the result won't fit in MAXLINE */
|
||||
char *s = cmd->buf;
|
||||
char * s = cmd->buf;
|
||||
while ( *s )
|
||||
{
|
||||
size_t l = strcspn( s, "\n" );
|
||||
|
||||
|
||||
if ( l > MAXLINE )
|
||||
{
|
||||
/* We don't free targets/sources/shell if bailing. */
|
||||
cmd_free( cmd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
s += l;
|
||||
if ( *s )
|
||||
++s;
|
||||
@@ -97,8 +97,8 @@ cmd_new(
|
||||
void
|
||||
cmd_free( CMD *cmd )
|
||||
{
|
||||
lol_free( &cmd->args );
|
||||
list_free( cmd->shell );
|
||||
lol_free( &cmd->args );
|
||||
list_free( cmd->shell );
|
||||
BJAM_FREE( cmd->buf );
|
||||
BJAM_FREE( (char *)cmd );
|
||||
BJAM_FREE( (char *)cmd );
|
||||
}
|
||||
|
||||
@@ -12,23 +12,23 @@
|
||||
* sources; a CMD is what actually gets executed by the shell. The
|
||||
* differences are due to:
|
||||
*
|
||||
* ACTIONS must be combined if 'actions together' is given.
|
||||
* ACTIONS must be split if 'actions piecemeal' is given.
|
||||
* ACTIONS must have current sources omitted for 'actions updated'.
|
||||
* ACTIONS must be combined if 'actions together' is given.
|
||||
* ACTIONS must be split if 'actions piecemeal' is given.
|
||||
* ACTIONS must have current sources omitted for 'actions updated'.
|
||||
*
|
||||
* The CMD datatype holds a single command that is to be executed
|
||||
* against a target, and they can chain together to represent the
|
||||
* The CMD datatype holds a single command that is to be executed
|
||||
* against a target, and they can chain together to represent the
|
||||
* full collection of commands used to update a target.
|
||||
*
|
||||
* Structures:
|
||||
*
|
||||
* CMD - an action, ready to be formatted into a buffer and executed
|
||||
* CMD - an action, ready to be formatted into a buffer and executed
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* cmd_new() - return a new CMD or 0 if too many args
|
||||
* cmd_free() - delete CMD and its parts
|
||||
* cmd_next() - walk the CMD chain
|
||||
* cmd_new() - return a new CMD or 0 if too many args
|
||||
* cmd_free() - delete CMD and its parts
|
||||
* cmd_next() - walk the CMD chain
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -39,19 +39,19 @@ typedef struct _cmd CMD;
|
||||
|
||||
struct _cmd
|
||||
{
|
||||
CMD *next;
|
||||
CMD *tail; /* valid on in head */
|
||||
RULE *rule; /* rule->actions contains shell script */
|
||||
LIST *shell; /* $(SHELL) value */
|
||||
LOL args; /* LISTs for $(<), $(>) */
|
||||
char* buf; /* actual commands */
|
||||
CMD *next;
|
||||
CMD *tail; /* valid on in head */
|
||||
RULE *rule; /* rule->actions contains shell script */
|
||||
LIST *shell; /* $(SHELL) value */
|
||||
LOL args; /* LISTs for $(<), $(>) */
|
||||
char* buf; /* actual commands */
|
||||
} ;
|
||||
|
||||
CMD *cmd_new(
|
||||
RULE *rule, /* rule (referenced) */
|
||||
LIST *targets, /* $(<) (freed) */
|
||||
LIST *sources, /* $(>) (freed) */
|
||||
LIST *shell ); /* $(SHELL) (freed) */
|
||||
RULE *rule, /* rule (referenced) */
|
||||
LIST *targets, /* $(<) (freed) */
|
||||
LIST *sources, /* $(>) (freed) */
|
||||
LIST *shell ); /* $(SHELL) (freed) */
|
||||
|
||||
void cmd_free( CMD *cmd );
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -50,33 +50,33 @@ regexp* regex_compile( const char* pattern );
|
||||
|
||||
/* Flags for compile_set(), etc */
|
||||
|
||||
# define ASSIGN_SET 0x00 /* = assign variable */
|
||||
# define ASSIGN_APPEND 0x01 /* += append variable */
|
||||
# define ASSIGN_DEFAULT 0x02 /* set only if unset */
|
||||
# define ASSIGN_SET 0x00 /* = assign variable */
|
||||
# define ASSIGN_APPEND 0x01 /* += append variable */
|
||||
# define ASSIGN_DEFAULT 0x02 /* set only if unset */
|
||||
|
||||
/* Flags for compile_setexec() */
|
||||
|
||||
# define EXEC_UPDATED 0x01 /* executes updated */
|
||||
# define EXEC_TOGETHER 0x02 /* executes together */
|
||||
# define EXEC_IGNORE 0x04 /* executes ignore */
|
||||
# define EXEC_QUIETLY 0x08 /* executes quietly */
|
||||
# define EXEC_PIECEMEAL 0x10 /* executes piecemeal */
|
||||
# define EXEC_EXISTING 0x20 /* executes existing */
|
||||
# define EXEC_UPDATED 0x01 /* executes updated */
|
||||
# define EXEC_TOGETHER 0x02 /* executes together */
|
||||
# define EXEC_IGNORE 0x04 /* executes ignore */
|
||||
# define EXEC_QUIETLY 0x08 /* executes quietly */
|
||||
# define EXEC_PIECEMEAL 0x10 /* executes piecemeal */
|
||||
# define EXEC_EXISTING 0x20 /* executes existing */
|
||||
|
||||
/* Conditions for compile_if() */
|
||||
|
||||
# define EXPR_NOT 0 /* ! cond */
|
||||
# define EXPR_AND 1 /* cond && cond */
|
||||
# define EXPR_OR 2 /* cond || cond */
|
||||
# define EXPR_NOT 0 /* ! cond */
|
||||
# define EXPR_AND 1 /* cond && cond */
|
||||
# define EXPR_OR 2 /* cond || cond */
|
||||
|
||||
# define EXPR_EXISTS 3 /* arg */
|
||||
# define EXPR_EQUALS 4 /* arg = arg */
|
||||
# define EXPR_NOTEQ 5 /* arg != arg */
|
||||
# define EXPR_LESS 6 /* arg < arg */
|
||||
# define EXPR_LESSEQ 7 /* arg <= arg */
|
||||
# define EXPR_MORE 8 /* arg > arg */
|
||||
# define EXPR_MOREEQ 9 /* arg >= arg */
|
||||
# define EXPR_IN 10 /* arg in arg */
|
||||
# define EXPR_EXISTS 3 /* arg */
|
||||
# define EXPR_EQUALS 4 /* arg = arg */
|
||||
# define EXPR_NOTEQ 5 /* arg != arg */
|
||||
# define EXPR_LESS 6 /* arg < arg */
|
||||
# define EXPR_LESSEQ 7 /* arg <= arg */
|
||||
# define EXPR_MORE 8 /* arg > arg */
|
||||
# define EXPR_MOREEQ 9 /* arg >= arg */
|
||||
# define EXPR_IN 10 /* arg in arg */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -59,18 +59,16 @@ void profile_enter( char* rulename, profile_frame* frame )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void profile_memory( long mem )
|
||||
{
|
||||
if ( DEBUG_PROFILE )
|
||||
{
|
||||
if ( profile_stack && profile_stack->info )
|
||||
{
|
||||
profile_stack->info->memory += mem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void profile_exit(profile_frame* frame)
|
||||
|
||||
|
||||
void profile_exit( profile_frame * frame )
|
||||
{
|
||||
if ( DEBUG_PROFILE )
|
||||
{
|
||||
@@ -78,12 +76,12 @@ void profile_exit(profile_frame* frame)
|
||||
clock_t t = clock() - frame->entry_time - frame->overhead;
|
||||
/* If this rule is already present on the stack, don't add the time for
|
||||
this instance. */
|
||||
if (frame->info->stack_count == 1)
|
||||
if ( frame->info->stack_count == 1 )
|
||||
frame->info->cumulative += t;
|
||||
/* Net time does not depend on presense of the same rule in call stack. */
|
||||
frame->info->net += t - frame->subrules;
|
||||
|
||||
if (frame->caller)
|
||||
if ( frame->caller )
|
||||
{
|
||||
/* caller's cumulative time must account for this overhead */
|
||||
frame->caller->overhead += frame->overhead;
|
||||
@@ -95,9 +93,10 @@ void profile_exit(profile_frame* frame)
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_profile_entry(void* p_, void* ignored)
|
||||
|
||||
static void dump_profile_entry( void * p_, void * ignored )
|
||||
{
|
||||
profile_info* p = (profile_info*)p_;
|
||||
profile_info * p = (profile_info *)p_;
|
||||
unsigned long mem_each = (p->memory/(p->num_entries ? p->num_entries : 1));
|
||||
double cumulative = p->cumulative;
|
||||
double net = p->net;
|
||||
@@ -118,16 +117,17 @@ static void dump_profile_entry(void* p_, void* ignored)
|
||||
p->name);
|
||||
}
|
||||
|
||||
|
||||
void profile_dump()
|
||||
{
|
||||
if ( profile_hash )
|
||||
{
|
||||
printf("%10s %12s %12s %12s %10s %10s %s\n",
|
||||
printf( "%10s %12s %12s %12s %10s %10s %s\n",
|
||||
"--count--", "--gross--", "--net--", "--each--",
|
||||
"--mem--", "--each--",
|
||||
"--name--");
|
||||
"--name--" );
|
||||
hashenumerate( profile_hash, dump_profile_entry, 0 );
|
||||
dump_profile_entry(&profile_other,0);
|
||||
dump_profile_entry(&profile_total,(void*)1);
|
||||
dump_profile_entry( &profile_other, 0 );
|
||||
dump_profile_entry( &profile_total, (void *)1 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
* If $(JAMSHELL) is defined, uses that to formulate execvp().
|
||||
* The default is:
|
||||
*
|
||||
* /bin/sh -c %
|
||||
* /bin/sh -c %
|
||||
*
|
||||
* Each word must be an individual element in a jam variable value.
|
||||
*
|
||||
* In $(JAMSHELL), % expands to the command string and ! expands to
|
||||
* In $(JAMSHELL), % expands to the command string and ! expands to
|
||||
* the slot number (starting at 1) for multiprocess (-j) invocations.
|
||||
* If $(JAMSHELL) doesn't include a %, it is tacked on as the last
|
||||
* argument.
|
||||
@@ -29,11 +29,11 @@
|
||||
* Don't just set JAMSHELL to /bin/sh - it won't work!
|
||||
*
|
||||
* External routines:
|
||||
* execcmd() - launch an async command execution
|
||||
* execwait() - wait and drive at most one execution completion
|
||||
* execcmd() - launch an async command execution
|
||||
* execwait() - wait and drive at most one execution completion
|
||||
*
|
||||
* Internal routines:
|
||||
* onintr() - bump intr to note command interruption
|
||||
* onintr() - bump intr to note command interruption
|
||||
*
|
||||
* 04/08/94 (seiwald) - Coherent/386 support added.
|
||||
* 05/04/94 (seiwald) - async multiprocess interface
|
||||
@@ -44,16 +44,14 @@
|
||||
* execcmd() - launch an async command execution
|
||||
*/
|
||||
|
||||
void
|
||||
execcmd(
|
||||
char *string,
|
||||
void (*func)( void *closure, int status, timing_info*, char *, char * ),
|
||||
void *closure,
|
||||
LIST *shell )
|
||||
void execcmd(
|
||||
char *string,
|
||||
void (*func)( void *closure, int status, timing_info*, char *, char * ),
|
||||
void *closure,
|
||||
LIST *shell )
|
||||
{
|
||||
|
||||
printf( "%s", string );
|
||||
(*func)( closure, EXEC_CMD_OK );
|
||||
printf( "%s", string );
|
||||
(*func)( closure, EXEC_CMD_OK );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -63,7 +61,7 @@ execcmd(
|
||||
int
|
||||
execwait()
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif /* OS_MAC */
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
*
|
||||
* Each word must be an individual element in a jam variable value.
|
||||
*
|
||||
* In $(JAMSHELL), % expands to the command string and ! expands to
|
||||
* In $(JAMSHELL), % expands to the command string and ! expands to
|
||||
* the slot number (starting at 1) for multiprocess (-j) invocations.
|
||||
* If $(JAMSHELL) doesn't include a %, it is tacked on as the last
|
||||
* argument.
|
||||
@@ -96,7 +96,7 @@ static void read_output();
|
||||
static int try_kill_one();
|
||||
/* */
|
||||
static double creation_time(HANDLE);
|
||||
/* Recursive check if first process is parent (directly or indirectly) of
|
||||
/* Recursive check if first process is parent (directly or indirectly) of
|
||||
the second one. */
|
||||
static int is_parent_child(DWORD, DWORD);
|
||||
/* */
|
||||
@@ -142,7 +142,7 @@ static struct
|
||||
/* execution unit tests */
|
||||
void execnt_unit_test()
|
||||
{
|
||||
#if !defined(NDEBUG)
|
||||
#if !defined(NDEBUG)
|
||||
/* vc6 preprocessor is broken, so assert with these strings gets
|
||||
* confused. Use a table instead.
|
||||
*/
|
||||
@@ -178,18 +178,22 @@ void execnt_unit_test()
|
||||
/* Work around vc6 bug; it doesn't like escaped string
|
||||
* literals inside assert
|
||||
*/
|
||||
char** argv = string_to_args("\"g++\" -c -I\"Foobar\"");
|
||||
char const expected[] = "-c -I\"Foobar\"";
|
||||
|
||||
assert(!strcmp(argv[0], "g++"));
|
||||
assert(!strcmp(argv[1], expected));
|
||||
free_argv(argv);
|
||||
char * * argv = string_to_args(" \"g++\" -c -I\"Foobar\"" );
|
||||
char const expected[] = "-c -I\"Foobar\"";
|
||||
|
||||
assert( !strcmp( argv[0], "g++" ) );
|
||||
assert( !strcmp( argv[1], expected ) );
|
||||
free_argv( argv );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* execcmd() - launch an async command execution */
|
||||
void execcmd(
|
||||
|
||||
/*
|
||||
* execcmd() - launch an async command execution.
|
||||
*/
|
||||
|
||||
void execcmd(
|
||||
char *command,
|
||||
void (*func)( void *closure, int status, timing_info*, char *invoked_command, char *command_output),
|
||||
void *closure,
|
||||
@@ -203,7 +207,7 @@ void execcmd(
|
||||
char **argv = argv_static;
|
||||
char *p;
|
||||
char* command_orig = command;
|
||||
|
||||
|
||||
/* Check to see if we need to hack around the line-length limitation. */
|
||||
/* Look for a JAMSHELL setting of "%", indicating that the command
|
||||
* should be invoked directly */
|
||||
@@ -223,17 +227,17 @@ void execcmd(
|
||||
exit( EXITBAD );
|
||||
}
|
||||
|
||||
/* compute the name of a temp batch file, for possible use */
|
||||
/* Compute the name of a temp batch file, for possible use. */
|
||||
if( !cmdtab[ slot ].tempfile_bat )
|
||||
{
|
||||
const char *tempdir = path_tmpdir();
|
||||
DWORD procID = GetCurrentProcessId();
|
||||
|
||||
/* SVA - allocate 64 other just to be safe */
|
||||
|
||||
/* SVA - allocate 64 bytes extra just to be safe. */
|
||||
cmdtab[ slot ].tempfile_bat = BJAM_MALLOC_ATOMIC( strlen( tempdir ) + 64 );
|
||||
|
||||
|
||||
sprintf(
|
||||
cmdtab[ slot ].tempfile_bat, "%s\\jam%d-%02d.bat",
|
||||
cmdtab[ slot ].tempfile_bat, "%s\\jam%d-%02d.bat",
|
||||
tempdir, procID, slot );
|
||||
}
|
||||
|
||||
@@ -241,25 +245,26 @@ void execcmd(
|
||||
while( *(command+1) && isspace( *command ) )
|
||||
++command;
|
||||
|
||||
/* Write to .BAT file unless the line would be too long and it
|
||||
* meets the other spawnability criteria.
|
||||
/* Write to .BAT file unless the line would be too long and it meets the
|
||||
* other spawnability criteria.
|
||||
*/
|
||||
if( raw_cmd && can_spawn( command ) >= MAXLINE )
|
||||
{
|
||||
if( DEBUG_EXECCMD )
|
||||
printf("Executing raw command directly\n");
|
||||
printf("Executing raw command directly\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *f = 0;
|
||||
int tries = 0;
|
||||
raw_cmd = 0;
|
||||
|
||||
/* Write command to bat file. For some reason this open can
|
||||
fails intermitently. But doing some retries works. Most likely
|
||||
this is due to a previously existing file of the same name that
|
||||
happens to be opened by an active virus scanner. Pointed out,
|
||||
and fix by Bronek Kozicki. */
|
||||
|
||||
/* Write command to bat file. For some reason this open can fail
|
||||
* intermitently. But doing some retries works. Most likely this is due
|
||||
* to a previously existing file of the same name that happens to be
|
||||
* opened by an active virus scanner. Pointed out and fixed by Bronek
|
||||
* Kozicki.
|
||||
*/
|
||||
for (; !f && tries < 4; ++tries)
|
||||
{
|
||||
f = fopen( cmdtab[ slot ].tempfile_bat, "w" );
|
||||
@@ -274,7 +279,7 @@ void execcmd(
|
||||
fclose( f );
|
||||
|
||||
command = cmdtab[ slot ].tempfile_bat;
|
||||
|
||||
|
||||
if( DEBUG_EXECCMD )
|
||||
{
|
||||
if (shell)
|
||||
@@ -327,8 +332,8 @@ void execcmd(
|
||||
|
||||
if( !cmdsrunning++ )
|
||||
istat = signal( SIGINT, onintr );
|
||||
|
||||
/* Start the command */
|
||||
|
||||
/* Start the command. */
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa
|
||||
= { sizeof(SECURITY_ATTRIBUTES), 0, 0 };
|
||||
@@ -367,26 +372,26 @@ void execcmd(
|
||||
SetHandleInformation( cmdtab[ slot ].pipe_err[0], HANDLE_FLAG_INHERIT, 0 );
|
||||
}
|
||||
|
||||
/* hide the child window, if any */
|
||||
/* Hide the child window, if any. */
|
||||
si.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
|
||||
/* set the child outputs to the pipes */
|
||||
/* Set the child outputs to the pipes. */
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
si.hStdOutput = cmdtab[ slot ].pipe_out[1];
|
||||
if ( globs.pipe_action == 2 )
|
||||
{
|
||||
/* pipe stderr to the action error output */
|
||||
/* Pipe stderr to the action error output. */
|
||||
si.hStdError = cmdtab[ slot ].pipe_err[1];
|
||||
}
|
||||
else if ( globs.pipe_action == 1 )
|
||||
{
|
||||
/* pipe stderr to the console error output */
|
||||
/* Pipe stderr to the console error output. */
|
||||
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pipe stderr to the action merged output */
|
||||
/* Pipe stderr to the action merged output. */
|
||||
si.hStdError = cmdtab[ slot ].pipe_out[1];
|
||||
}
|
||||
|
||||
@@ -406,8 +411,8 @@ void execcmd(
|
||||
string_new( &cmdtab[ slot ].target );
|
||||
}
|
||||
string_copy( &cmdtab[ slot ].command, command_orig );
|
||||
|
||||
/* put together the comman we run */
|
||||
|
||||
/* Put together the command we run. */
|
||||
{
|
||||
char ** argp = argv;
|
||||
string_new(&cmd);
|
||||
@@ -418,64 +423,64 @@ void execcmd(
|
||||
string_append(&cmd,*(argp++));
|
||||
}
|
||||
}
|
||||
|
||||
/* create the output buffers */
|
||||
|
||||
/* Create output buffers. */
|
||||
string_new( &cmdtab[ slot ].buffer_out );
|
||||
string_new( &cmdtab[ slot ].buffer_err );
|
||||
|
||||
/* run the command, by creating a sub-process for it */
|
||||
/* Run the command by creating a sub-process for it. */
|
||||
if (
|
||||
! CreateProcess(
|
||||
NULL, /* application name */
|
||||
cmd.value, /* command line */
|
||||
NULL, /* process attributes */
|
||||
NULL, /* thread attributes */
|
||||
TRUE, /* inherit handles */
|
||||
CREATE_NEW_PROCESS_GROUP, /* create flags */
|
||||
NULL, /* env vars, null inherits env */
|
||||
NULL, /* current dir, null is our current dir */
|
||||
&si, /* startup info */
|
||||
&cmdtab[ slot ].pi /* the child process info, if created */
|
||||
NULL , /* application name */
|
||||
cmd.value , /* command line */
|
||||
NULL , /* process attributes */
|
||||
NULL , /* thread attributes */
|
||||
TRUE , /* inherit handles */
|
||||
CREATE_NEW_PROCESS_GROUP, /* create flags */
|
||||
NULL , /* env vars, null inherits env */
|
||||
NULL , /* current dir, null is our */
|
||||
/* current dir */
|
||||
&si , /* startup info */
|
||||
&cmdtab[ slot ].pi /* child process info, if created */
|
||||
)
|
||||
)
|
||||
{
|
||||
perror( "CreateProcess" );
|
||||
exit( EXITBAD );
|
||||
}
|
||||
|
||||
/* clean up temporary stuff */
|
||||
|
||||
/* Clean up temporary stuff. */
|
||||
string_free(&cmd);
|
||||
}
|
||||
|
||||
/* Wait until we're under the limit of concurrent commands. */
|
||||
/* Don't trust globs.jobs alone. */
|
||||
|
||||
while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )
|
||||
/* Wait until we are under the limit of concurrent commands. Do not trust
|
||||
* globs.jobs alone.
|
||||
*/
|
||||
while( ( cmdsrunning >= MAXJOBS ) || ( cmdsrunning >= globs.jobs ) )
|
||||
if( !execwait() )
|
||||
break;
|
||||
|
||||
|
||||
if (argv != argv_static)
|
||||
{
|
||||
free_argv(argv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* execwait()
|
||||
- wait and drive at most one execution completion
|
||||
* wait and drive at most one execution completion
|
||||
* waits for one command to complete, while processing the io
|
||||
for all ongoing commands.
|
||||
|
||||
Returns 0 if called when there were no more commands being executed or 1
|
||||
otherwise.
|
||||
*/
|
||||
int execwait()
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
/* Handle naive make1() which doesn't know if cmds are running. */
|
||||
|
||||
/* Handle naive make1() which does not know if cmds are running. */
|
||||
if( !cmdsrunning )
|
||||
return 0;
|
||||
|
||||
|
||||
/* wait for a command to complete, while snarfing up any output */
|
||||
do
|
||||
{
|
||||
@@ -489,13 +494,13 @@ int execwait()
|
||||
if ( i < 0 ) i = try_kill_one();
|
||||
}
|
||||
while ( i < 0 );
|
||||
|
||||
/* we have a command... process it */
|
||||
|
||||
/* We have a command... process it. */
|
||||
--cmdsrunning;
|
||||
{
|
||||
timing_info time;
|
||||
int rstat;
|
||||
|
||||
|
||||
/* the time data for the command */
|
||||
record_times(cmdtab[i].pi.hProcess, &time);
|
||||
|
||||
@@ -536,7 +541,7 @@ int execwait()
|
||||
&time,
|
||||
cmdtab[i].command.value,
|
||||
cmdtab[i].buffer_out.value );
|
||||
|
||||
|
||||
/* clean up the command data, process, etc. */
|
||||
string_free(&cmdtab[i].action); string_new(&cmdtab[i].action);
|
||||
string_free(&cmdtab[i].target); string_new(&cmdtab[i].target);
|
||||
@@ -556,6 +561,7 @@ int execwait()
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
static void free_argv( char** args )
|
||||
@@ -566,7 +572,7 @@ static void free_argv( char** args )
|
||||
|
||||
/* For more details on Windows cmd.exe shell command-line length limitations see
|
||||
* the following MSDN article:
|
||||
*
|
||||
*
|
||||
* http://support.microsoft.com/default.aspx?scid=kb;en-us;830473
|
||||
*/
|
||||
int maxline()
|
||||
@@ -574,7 +580,7 @@ int maxline()
|
||||
OSVERSIONINFO os_info;
|
||||
os_info.dwOSVersionInfoSize = sizeof(os_info);
|
||||
GetVersionEx(&os_info);
|
||||
|
||||
|
||||
if (os_info.dwMajorVersion >= 5) return 8191; /* XP > */
|
||||
if (os_info.dwMajorVersion == 4) return 2047; /* NT 4.x */
|
||||
return 996; /* NT 3.5.1 */
|
||||
@@ -602,7 +608,7 @@ static char** string_to_args( const char* string )
|
||||
/* drop leading and trailing whitespace if any */
|
||||
while (isspace(*string))
|
||||
++string;
|
||||
|
||||
|
||||
src_len = strlen( string );
|
||||
while ( src_len > 0 && isspace( string[src_len - 1] ) )
|
||||
--src_len;
|
||||
@@ -624,7 +630,7 @@ static char** string_to_args( const char* string )
|
||||
BJAM_FREE( line );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Strip quotes from the first command-line argument and find
|
||||
* where it ends. Quotes are illegal in Win32 pathnames, so we
|
||||
* don't need to worry about preserving escaped quotes here.
|
||||
@@ -644,31 +650,32 @@ static char** string_to_args( const char* string )
|
||||
*dst++ = 0;
|
||||
argv[0] = line;
|
||||
|
||||
/* skip whitespace in src */
|
||||
/* Skip whitespace in src. */
|
||||
while (isspace(*src))
|
||||
++src;
|
||||
|
||||
argv[1] = dst;
|
||||
|
||||
/* Copy the rest of the arguments verbatim */
|
||||
|
||||
/* Copy the rest of the arguments verbatim. */
|
||||
src_len -= src - string;
|
||||
|
||||
/* Use strncat because it appends a trailing nul */
|
||||
/* Use strncat because it appends a trailing nul. */
|
||||
*dst = 0;
|
||||
strncat(dst, src, src_len);
|
||||
|
||||
argv[2] = 0;
|
||||
|
||||
|
||||
return argv;
|
||||
}
|
||||
|
||||
|
||||
static void onintr( int disp )
|
||||
{
|
||||
intr++;
|
||||
printf( "...interrupted\n" );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* can_spawn() - If the command is suitable for execution via spawnvp,
|
||||
* return a number >= the number of characters it would occupy on the
|
||||
@@ -676,15 +683,15 @@ static void onintr( int disp )
|
||||
*/
|
||||
long can_spawn(char* command)
|
||||
{
|
||||
char *p;
|
||||
|
||||
char * p;
|
||||
|
||||
char inquote = 0;
|
||||
|
||||
/* Move to the first non-whitespace */
|
||||
command += strspn( command, " \t" );
|
||||
|
||||
p = command;
|
||||
|
||||
|
||||
/* Look for newlines and unquoted i/o redirection */
|
||||
do
|
||||
{
|
||||
@@ -702,7 +709,7 @@ long can_spawn(char* command)
|
||||
if (*p)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
if (p > command && p[-1] != '\\')
|
||||
@@ -712,10 +719,10 @@ long can_spawn(char* command)
|
||||
else if (inquote == 0)
|
||||
inquote = *p;
|
||||
}
|
||||
|
||||
|
||||
++p;
|
||||
break;
|
||||
|
||||
|
||||
case '<':
|
||||
case '>':
|
||||
case '|':
|
||||
@@ -798,11 +805,11 @@ static time_t filetime_dt(FILETIME t_utc)
|
||||
return ceil(filetime_seconds(t_utc)-time_diff);
|
||||
}
|
||||
|
||||
|
||||
static void record_times(HANDLE process, timing_info* time)
|
||||
{
|
||||
FILETIME creation, exit, kernel, user;
|
||||
|
||||
if (GetProcessTimes(process, &creation, &exit, &kernel, &user))
|
||||
if ( GetProcessTimes( process, &creation, &exit, &kernel, &user ) )
|
||||
{
|
||||
time->system = filetime_seconds(kernel);
|
||||
time->user = filetime_seconds(user);
|
||||
@@ -811,10 +818,12 @@ static void record_times(HANDLE process, timing_info* time)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define IO_BUFFER_SIZE (16*1024)
|
||||
|
||||
static char ioBuffer[IO_BUFFER_SIZE+1];
|
||||
|
||||
|
||||
static void read_pipe(
|
||||
HANDLE in, /* the pipe to read from */
|
||||
string * out
|
||||
@@ -822,7 +831,7 @@ static void read_pipe(
|
||||
{
|
||||
DWORD bytesInBuffer = 0;
|
||||
DWORD bytesAvailable = 0;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
/* check if we have any data to read */
|
||||
@@ -830,7 +839,7 @@ static void read_pipe(
|
||||
{
|
||||
bytesAvailable = 0;
|
||||
}
|
||||
|
||||
|
||||
/* read in the available data */
|
||||
if ( bytesAvailable > 0 )
|
||||
{
|
||||
@@ -879,7 +888,7 @@ static void read_pipe(
|
||||
static void read_output()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for ( i = 0; i < globs.jobs && i < MAXJOBS; ++i )
|
||||
{
|
||||
/* read stdout data */
|
||||
@@ -933,7 +942,7 @@ static int try_kill_one()
|
||||
if ( globs.timeout > 0 )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for ( i = 0; i < globs.jobs; ++i )
|
||||
{
|
||||
double t = running_time(cmdtab[i].pi.hProcess);
|
||||
@@ -1041,7 +1050,7 @@ static void kill_process_tree(DWORD pid, HANDLE process)
|
||||
pid = get_process_id(process);
|
||||
}
|
||||
process_snapshot_h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
|
||||
|
||||
|
||||
if (INVALID_HANDLE_VALUE != process_snapshot_h)
|
||||
{
|
||||
BOOL ok = TRUE;
|
||||
@@ -1079,61 +1088,65 @@ static double creation_time(HANDLE process)
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* Recursive check if first process is parent (directly or indirectly) of
|
||||
the second one. Both processes are passed as process ids, not handles.
|
||||
Special return value 2 means that the second process is smss.exe and its
|
||||
parent process is System (first argument is ignored) */
|
||||
static int is_parent_child(DWORD parent, DWORD child)
|
||||
|
||||
/* Recursive check if first process is parent (directly or indirectly) of the
|
||||
* second one. Both processes are passed as process ids, not handles. Special
|
||||
* return value 2 means that the second process is smss.exe and its parent
|
||||
* process is System (first argument is ignored).
|
||||
*/
|
||||
|
||||
static int is_parent_child( DWORD parent, DWORD child )
|
||||
{
|
||||
HANDLE process_snapshot_h = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (!child)
|
||||
if ( !child )
|
||||
return 0;
|
||||
if (parent == child)
|
||||
if ( parent == child )
|
||||
return 1;
|
||||
|
||||
process_snapshot_h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
|
||||
if (INVALID_HANDLE_VALUE != process_snapshot_h)
|
||||
process_snapshot_h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
|
||||
if ( INVALID_HANDLE_VALUE != process_snapshot_h )
|
||||
{
|
||||
BOOL ok = TRUE;
|
||||
PROCESSENTRY32 pinfo;
|
||||
pinfo.dwSize = sizeof(PROCESSENTRY32);
|
||||
for (
|
||||
ok = Process32First(process_snapshot_h, &pinfo);
|
||||
ok == TRUE;
|
||||
ok = Process32First(process_snapshot_h, &pinfo);
|
||||
ok == TRUE;
|
||||
ok = Process32Next(process_snapshot_h, &pinfo) )
|
||||
{
|
||||
if (pinfo.th32ProcessID == child)
|
||||
{
|
||||
/*
|
||||
Unfortunately, process ids are not really unique. There might
|
||||
be spurious "parent and child" relationship match between
|
||||
two non-related processes if real parent process of a given
|
||||
process has exited (while child process kept running as an
|
||||
"orphan") and the process id of such parent process has been
|
||||
reused by internals of the operating system when creating
|
||||
another process. Thus additional check is needed - process
|
||||
creation time. This check may fail (ie. return 0) for system
|
||||
processes due to insufficient privileges, and that's OK. */
|
||||
/* Unfortunately, process ids are not really unique. There might
|
||||
* be spurious "parent and child" relationship match between two
|
||||
* non-related processes if real parent process of a given
|
||||
* process has exited (while child process kept running as an
|
||||
* "orphan") and the process id of such parent process has been
|
||||
* reused by internals of the operating system when creating
|
||||
* another process.
|
||||
*
|
||||
* Thus additional check is needed - process creation time. This
|
||||
* check may fail (i.e. return 0) for system processes due to
|
||||
* insufficient privileges, and that is OK.
|
||||
*/
|
||||
double tchild = 0.0;
|
||||
double tparent = 0.0;
|
||||
HANDLE hchild = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pinfo.th32ProcessID);
|
||||
|
||||
CloseHandle(process_snapshot_h);
|
||||
HANDLE hchild = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pinfo.th32ProcessID );
|
||||
CloseHandle( process_snapshot_h );
|
||||
|
||||
/* csrss.exe may display message box like following:
|
||||
xyz.exe - Unable To Locate Component
|
||||
This application has failed to start because
|
||||
boost_foo-bar.dll was not found. Re-installing the
|
||||
This application has failed to start because
|
||||
boost_foo-bar.dll was not found. Re-installing the
|
||||
application may fix the problem
|
||||
This actually happens when starting test process that depends
|
||||
on a dynamic library which failed to build. We want to
|
||||
on a dynamic library which failed to build. We want to
|
||||
automatically close these message boxes even though csrss.exe
|
||||
is not our child process. We may depend on the fact that (in
|
||||
all current versions of Windows) csrss.exe is directly
|
||||
all current versions of Windows) csrss.exe is directly
|
||||
child of smss.exe process, which in turn is directly child of
|
||||
System process, which always has process id == 4 .
|
||||
This check must be performed before comparison of process
|
||||
This check must be performed before comparison of process
|
||||
creation time */
|
||||
if (stricmp(pinfo.szExeFile, "csrss.exe") == 0
|
||||
&& is_parent_child(parent, pinfo.th32ParentProcessID) == 2)
|
||||
@@ -1153,7 +1166,7 @@ static int is_parent_child(DWORD parent, DWORD child)
|
||||
{
|
||||
tchild = creation_time(hchild);
|
||||
tparent = creation_time(hparent);
|
||||
|
||||
|
||||
CloseHandle(hparent);
|
||||
}
|
||||
CloseHandle(hchild);
|
||||
@@ -1194,14 +1207,14 @@ BOOL CALLBACK close_alert_window_enum(HWND hwnd, LPARAM lParam)
|
||||
|
||||
if (!GetClassNameA(hwnd, buf, sizeof(buf)))
|
||||
return TRUE; /* failed to read class name; presume it's not a dialog */
|
||||
|
||||
|
||||
if (strcmp(buf, "#32770") != 0)
|
||||
return TRUE; /* not a dialog */
|
||||
|
||||
/* GetWindowThreadProcessId returns 0 on error, otherwise thread id
|
||||
of window message pump thread */
|
||||
tid = GetWindowThreadProcessId(hwnd, &pid);
|
||||
|
||||
|
||||
if (tid && is_parent_child(p.pid, pid))
|
||||
{
|
||||
/* ask really nice */
|
||||
@@ -1212,7 +1225,7 @@ BOOL CALLBACK close_alert_window_enum(HWND hwnd, LPARAM lParam)
|
||||
PostThreadMessageA(tid, WM_QUIT, 0, 0);
|
||||
WaitForSingleObject(p.h, 300);
|
||||
}
|
||||
|
||||
|
||||
/* done, we do not want to check any other window now */
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1220,17 +1233,19 @@ BOOL CALLBACK close_alert_window_enum(HWND hwnd, LPARAM lParam)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void close_alert(HANDLE process)
|
||||
|
||||
static void close_alert( HANDLE process )
|
||||
{
|
||||
DWORD pid = get_process_id(process);
|
||||
/* If process already exited or we just cannot get its process id, do not
|
||||
go any further */
|
||||
if (pid)
|
||||
/* If process already exited or we just cannot get its process id, do not go
|
||||
* go any further.
|
||||
*/
|
||||
if ( pid )
|
||||
{
|
||||
PROCESS_HANDLE_ID p;
|
||||
p.h = process;
|
||||
p.pid = pid;
|
||||
EnumWindows(&close_alert_window_enum, (LPARAM) &p);
|
||||
p.pid = pid;
|
||||
EnumWindows( &close_alert_window_enum, (LPARAM)&p );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
* If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp().
|
||||
* The default is:
|
||||
*
|
||||
* /bin/sh -c % [ on UNIX/AmigaOS ]
|
||||
* cmd.exe /c % [ on OS2/WinNT ]
|
||||
* /bin/sh -c % [ on UNIX/AmigaOS ]
|
||||
* cmd.exe /c % [ on OS2/WinNT ]
|
||||
*
|
||||
* Each word must be an individual element in a jam variable value.
|
||||
*
|
||||
* In $(JAMSHELL), % expands to the command string and ! expands to
|
||||
* In $(JAMSHELL), % expands to the command string and ! expands to
|
||||
* the slot number (starting at 1) for multiprocess (-j) invocations.
|
||||
* If $(JAMSHELL) doesn't include a %, it is tacked on as the last
|
||||
* argument.
|
||||
@@ -52,11 +52,11 @@
|
||||
* Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work!
|
||||
*
|
||||
* External routines:
|
||||
* execcmd() - launch an async command execution
|
||||
* execwait() - wait and drive at most one execution completion
|
||||
* execcmd() - launch an async command execution
|
||||
* execwait() - wait and drive at most one execution completion
|
||||
*
|
||||
* Internal routines:
|
||||
* onintr() - bump intr to note command interruption
|
||||
* onintr() - bump intr to note command interruption
|
||||
*
|
||||
* 04/08/94 (seiwald) - Coherent/386 support added.
|
||||
* 05/04/94 (seiwald) - async multiprocess interface
|
||||
@@ -76,7 +76,7 @@ static struct tms old_time;
|
||||
|
||||
static struct
|
||||
{
|
||||
int pid; /* on win32, a real process handle */
|
||||
int pid; /* on win32, a real process handle */
|
||||
int fd[2]; /* file descriptors for stdout and stderr */
|
||||
FILE *stream[2]; /* child's stdout (0) and stderr (1) file stream */
|
||||
clock_t start_time; /* start time of child process */
|
||||
@@ -99,8 +99,8 @@ static struct
|
||||
void
|
||||
onintr( int disp )
|
||||
{
|
||||
intr++;
|
||||
printf( "...interrupted\n" );
|
||||
intr++;
|
||||
printf( "...interrupted\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -108,70 +108,70 @@ onintr( int disp )
|
||||
*/
|
||||
|
||||
void
|
||||
execcmd(
|
||||
char *string,
|
||||
void (*func)( void *closure, int status, timing_info*, char *, char * ),
|
||||
void *closure,
|
||||
LIST *shell,
|
||||
execcmd(
|
||||
char *string,
|
||||
void (*func)( void *closure, int status, timing_info*, char *, char * ),
|
||||
void *closure,
|
||||
LIST *shell,
|
||||
char *action,
|
||||
char *target )
|
||||
{
|
||||
static int initialized = 0;
|
||||
int out[2], err[2];
|
||||
int slot, len;
|
||||
char *argv[ MAXARGC + 1 ]; /* +1 for NULL */
|
||||
int slot, len;
|
||||
char *argv[ MAXARGC + 1 ]; /* +1 for NULL */
|
||||
|
||||
/* Find a slot in the running commands table for this one. */
|
||||
/* Find a slot in the running commands table for this one. */
|
||||
|
||||
for( slot = 0; slot < MAXJOBS; slot++ )
|
||||
if( !cmdtab[ slot ].pid )
|
||||
break;
|
||||
for( slot = 0; slot < MAXJOBS; slot++ )
|
||||
if( !cmdtab[ slot ].pid )
|
||||
break;
|
||||
|
||||
if( slot == MAXJOBS )
|
||||
{
|
||||
printf( "no slots for child!\n" );
|
||||
exit( EXITBAD );
|
||||
}
|
||||
if( slot == MAXJOBS )
|
||||
{
|
||||
printf( "no slots for child!\n" );
|
||||
exit( EXITBAD );
|
||||
}
|
||||
|
||||
/* Forumulate argv */
|
||||
/* If shell was defined, be prepared for % and ! subs. */
|
||||
/* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */
|
||||
/* Forumulate argv */
|
||||
/* If shell was defined, be prepared for % and ! subs. */
|
||||
/* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */
|
||||
|
||||
if( shell )
|
||||
{
|
||||
int i;
|
||||
char jobno[4];
|
||||
int gotpercent = 0;
|
||||
if( shell )
|
||||
{
|
||||
int i;
|
||||
char jobno[4];
|
||||
int gotpercent = 0;
|
||||
|
||||
sprintf( jobno, "%d", slot + 1 );
|
||||
sprintf( jobno, "%d", slot + 1 );
|
||||
|
||||
for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) )
|
||||
{
|
||||
switch( shell->string[0] )
|
||||
{
|
||||
case '%': argv[i] = string; gotpercent++; break;
|
||||
case '!': argv[i] = jobno; break;
|
||||
default: argv[i] = shell->string;
|
||||
}
|
||||
if( DEBUG_EXECCMD )
|
||||
printf( "argv[%d] = '%s'\n", i, argv[i] );
|
||||
}
|
||||
for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) )
|
||||
{
|
||||
switch( shell->string[0] )
|
||||
{
|
||||
case '%': argv[i] = string; gotpercent++; break;
|
||||
case '!': argv[i] = jobno; break;
|
||||
default: argv[i] = shell->string;
|
||||
}
|
||||
if( DEBUG_EXECCMD )
|
||||
printf( "argv[%d] = '%s'\n", i, argv[i] );
|
||||
}
|
||||
|
||||
if( !gotpercent )
|
||||
argv[i++] = string;
|
||||
if( !gotpercent )
|
||||
argv[i++] = string;
|
||||
|
||||
argv[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
argv[0] = "/bin/sh";
|
||||
argv[1] = "-c";
|
||||
argv[2] = string;
|
||||
argv[3] = 0;
|
||||
}
|
||||
argv[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
argv[0] = "/bin/sh";
|
||||
argv[1] = "-c";
|
||||
argv[2] = string;
|
||||
argv[3] = 0;
|
||||
}
|
||||
|
||||
/* increment jobs running */
|
||||
++cmdsrunning;
|
||||
/* increment jobs running */
|
||||
++cmdsrunning;
|
||||
|
||||
/* save off actual command string */
|
||||
cmdtab[ slot ].command = BJAM_MALLOC_ATOMIC(strlen(string)+1);
|
||||
@@ -197,24 +197,24 @@ execcmd(
|
||||
fcntl(err[0], F_SETFL, O_NONBLOCK);
|
||||
fcntl(err[1], F_SETFL, O_NONBLOCK);
|
||||
|
||||
/* Start the command */
|
||||
/* Start the command */
|
||||
|
||||
cmdtab[ slot ].start_dt = time(0);
|
||||
|
||||
if (0 < globs.timeout) {
|
||||
/*
|
||||
* handle hung processes by manually tracking elapsed
|
||||
/*
|
||||
* handle hung processes by manually tracking elapsed
|
||||
* time and signal process when time limit expires
|
||||
*/
|
||||
struct tms buf;
|
||||
cmdtab[ slot ].start_time = times(&buf);
|
||||
|
||||
/* make a global, only do this once */
|
||||
if (tps == 0) tps = sysconf(_SC_CLK_TCK);
|
||||
if (tps == 0) tps = sysconf(_SC_CLK_TCK);
|
||||
}
|
||||
|
||||
if ((cmdtab[slot].pid = vfork()) == 0)
|
||||
{
|
||||
if ((cmdtab[slot].pid = vfork()) == 0)
|
||||
{
|
||||
int pid = getpid();
|
||||
|
||||
close(out[0]);
|
||||
@@ -251,20 +251,20 @@ execcmd(
|
||||
_exit(127);
|
||||
}
|
||||
else if( cmdtab[slot].pid == -1 )
|
||||
{
|
||||
perror( "vfork" );
|
||||
exit( EXITBAD );
|
||||
}
|
||||
{
|
||||
perror( "vfork" );
|
||||
exit( EXITBAD );
|
||||
}
|
||||
|
||||
setpgid(cmdtab[slot].pid, cmdtab[slot].pid);
|
||||
|
||||
/* close write end of pipes */
|
||||
close(out[1]);
|
||||
close(err[1]);
|
||||
close(out[1]);
|
||||
close(err[1]);
|
||||
|
||||
/* child writes stdout to out[1], parent reads from out[0] */
|
||||
cmdtab[slot].fd[OUT] = out[0];
|
||||
cmdtab[slot].stream[OUT] = fdopen(cmdtab[slot].fd[OUT], "rb");
|
||||
cmdtab[slot].fd[OUT] = out[0];
|
||||
cmdtab[slot].stream[OUT] = fdopen(cmdtab[slot].fd[OUT], "rb");
|
||||
if (cmdtab[slot].stream[OUT] == NULL) {
|
||||
perror( "fdopen" );
|
||||
exit( EXITBAD );
|
||||
@@ -277,8 +277,8 @@ execcmd(
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdtab[slot].fd[ERR] = err[0];
|
||||
cmdtab[slot].stream[ERR] = fdopen(cmdtab[slot].fd[ERR], "rb");
|
||||
cmdtab[slot].fd[ERR] = err[0];
|
||||
cmdtab[slot].stream[ERR] = fdopen(cmdtab[slot].fd[ERR], "rb");
|
||||
if (cmdtab[slot].stream[ERR] == NULL) {
|
||||
perror( "fdopen" );
|
||||
exit( EXITBAD );
|
||||
@@ -290,7 +290,7 @@ execcmd(
|
||||
if (action && target)
|
||||
{
|
||||
len = strlen(action) + 1;
|
||||
if (cmdtab[slot].action_length < len)
|
||||
if (cmdtab[slot].action_length < len)
|
||||
{
|
||||
BJAM_FREE(cmdtab[ slot ].action);
|
||||
cmdtab[ slot ].action = BJAM_MALLOC_ATOMIC(len);
|
||||
@@ -298,7 +298,7 @@ execcmd(
|
||||
}
|
||||
strcpy(cmdtab[ slot ].action, action);
|
||||
len = strlen(target) + 1;
|
||||
if (cmdtab[slot].target_length < len)
|
||||
if (cmdtab[slot].target_length < len)
|
||||
{
|
||||
BJAM_FREE(cmdtab[ slot ].target);
|
||||
cmdtab[ slot ].target = BJAM_MALLOC_ATOMIC(len);
|
||||
@@ -316,13 +316,13 @@ execcmd(
|
||||
cmdtab[ slot ].target_length = 0;
|
||||
}
|
||||
|
||||
/* Save the operation for execwait() to find. */
|
||||
/* Save the operation for execwait() to find. */
|
||||
|
||||
cmdtab[ slot ].func = func;
|
||||
cmdtab[ slot ].closure = closure;
|
||||
cmdtab[ slot ].func = func;
|
||||
cmdtab[ slot ].closure = closure;
|
||||
|
||||
/* Wait until we're under the limit of concurrent commands. */
|
||||
/* Don't trust globs.jobs alone. */
|
||||
/* Wait until we're under the limit of concurrent commands. */
|
||||
/* Don't trust globs.jobs alone. */
|
||||
|
||||
while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )
|
||||
if( !execwait() )
|
||||
@@ -333,10 +333,10 @@ execcmd(
|
||||
*
|
||||
* i is index into cmdtab
|
||||
*
|
||||
* s (stream) indexes
|
||||
* s (stream) indexes
|
||||
*
|
||||
* cmdtab[i].stream[s]
|
||||
* cmdtab[i].buffer[s] and
|
||||
* cmdtab[i].stream[s]
|
||||
* cmdtab[i].buffer[s] and
|
||||
* cmdtab[i].fd[s]
|
||||
*/
|
||||
|
||||
@@ -374,7 +374,7 @@ void close_streams(int i, int s)
|
||||
/* close the stream and pipe descriptor */
|
||||
fclose(cmdtab[i].stream[s]);
|
||||
cmdtab[i].stream[s] = 0;
|
||||
|
||||
|
||||
close(cmdtab[i].fd[s]);
|
||||
cmdtab[i].fd[s] = 0;
|
||||
}
|
||||
@@ -487,9 +487,9 @@ execwait()
|
||||
cmdtab[i].pid = 0;
|
||||
|
||||
/* set reason for exit if not timed out */
|
||||
if (WIFEXITED(status))
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
if (0 == WEXITSTATUS(status))
|
||||
if (0 == WEXITSTATUS(status))
|
||||
cmdtab[i].exit_reason = EXIT_OK;
|
||||
else
|
||||
cmdtab[i].exit_reason = EXIT_FAIL;
|
||||
@@ -506,7 +506,7 @@ execwait()
|
||||
time_info.user = (double)(new_time.tms_cutime - old_time.tms_cutime) / CLOCKS_PER_SEC;
|
||||
time_info.start = cmdtab[i].start_dt;
|
||||
time_info.end = time(0);
|
||||
|
||||
|
||||
old_time = new_time;
|
||||
|
||||
/* Drive the completion */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 1993, 1995 Christopher Seiwald.
|
||||
*
|
||||
* This file is part of Jam - see jam.c for Copyright information.
|
||||
@@ -24,14 +24,14 @@
|
||||
*
|
||||
* The approach is this:
|
||||
*
|
||||
* If the command is a single line, and shorter than WRTLEN (what we
|
||||
* believe to be the maximum line length), we just system() it.
|
||||
* If the command is a single line, and shorter than WRTLEN (what we
|
||||
* believe to be the maximum line length), we just system() it.
|
||||
*
|
||||
* If the command is multi-line, or longer than WRTLEN, we write the
|
||||
* command block to a temp file, splitting long lines (using "-" at
|
||||
* the end of the line to indicate contiuation), and then source that
|
||||
* temp file. We use special logic to make sure we don't continue in
|
||||
* the middle of a quoted string.
|
||||
* If the command is multi-line, or longer than WRTLEN, we write the
|
||||
* command block to a temp file, splitting long lines (using "-" at
|
||||
* the end of the line to indicate contiuation), and then source that
|
||||
* temp file. We use special logic to make sure we don't continue in
|
||||
* the middle of a quoted string.
|
||||
*
|
||||
* 05/04/94 (seiwald) - async multiprocess interface; noop on VMS
|
||||
* 12/20/96 (seiwald) - rewritten to handle multi-line commands well
|
||||
@@ -40,130 +40,130 @@
|
||||
|
||||
#define WRTLEN 240
|
||||
|
||||
#define MIN( a, b ) ((a) < (b) ? (a) : (b))
|
||||
#define MIN( a, b ) ((a) < (b) ? (a) : (b))
|
||||
|
||||
/* 1 for the @ and 4 for the .com */
|
||||
|
||||
char tempnambuf[ L_tmpnam + 1 + 4 ] = {0};
|
||||
|
||||
void
|
||||
execcmd(
|
||||
char *string,
|
||||
execcmd(
|
||||
char *string,
|
||||
void (*func)( void *closure, int status, timing_info*, char *, char * ),
|
||||
void *closure,
|
||||
LIST *shell,
|
||||
void *closure,
|
||||
LIST *shell,
|
||||
char *rule_name,
|
||||
char *target )
|
||||
{
|
||||
char *s, *e, *p;
|
||||
int rstat = EXEC_CMD_OK;
|
||||
int status;
|
||||
char *s, *e, *p;
|
||||
int rstat = EXEC_CMD_OK;
|
||||
int status;
|
||||
|
||||
/* See if string is more than one line */
|
||||
/* discounting leading/trailing white space */
|
||||
/* See if string is more than one line */
|
||||
/* discounting leading/trailing white space */
|
||||
|
||||
for( s = string; *s && isspace( *s ); s++ )
|
||||
;
|
||||
for( s = string; *s && isspace( *s ); s++ )
|
||||
;
|
||||
|
||||
e = p = strchr( s, '\n' );
|
||||
e = p = strchr( s, '\n' );
|
||||
|
||||
while( p && isspace( *p ) )
|
||||
++p;
|
||||
while( p && isspace( *p ) )
|
||||
++p;
|
||||
|
||||
/* If multi line or long, write to com file. */
|
||||
/* Otherwise, exec directly. */
|
||||
/* If multi line or long, write to com file. */
|
||||
/* Otherwise, exec directly. */
|
||||
|
||||
if( p && *p || e - s > WRTLEN )
|
||||
{
|
||||
FILE *f;
|
||||
if( p && *p || e - s > WRTLEN )
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
/* Create temp file invocation "@sys$scratch:tempfile.com" */
|
||||
/* Create temp file invocation "@sys$scratch:tempfile.com" */
|
||||
|
||||
if( !*tempnambuf )
|
||||
{
|
||||
tempnambuf[0] = '@';
|
||||
(void)tmpnam( tempnambuf + 1 );
|
||||
strcat( tempnambuf, ".com" );
|
||||
}
|
||||
|
||||
/* Open tempfile */
|
||||
if( !*tempnambuf )
|
||||
{
|
||||
tempnambuf[0] = '@';
|
||||
(void)tmpnam( tempnambuf + 1 );
|
||||
strcat( tempnambuf, ".com" );
|
||||
}
|
||||
|
||||
if( !( f = fopen( tempnambuf + 1, "w" ) ) )
|
||||
{
|
||||
printf( "can't open command file\n" );
|
||||
(*func)( closure, EXEC_CMD_FAIL );
|
||||
return;
|
||||
}
|
||||
/* Open tempfile */
|
||||
|
||||
/* For each line of the string */
|
||||
if( !( f = fopen( tempnambuf + 1, "w" ) ) )
|
||||
{
|
||||
printf( "can't open command file\n" );
|
||||
(*func)( closure, EXEC_CMD_FAIL );
|
||||
return;
|
||||
}
|
||||
|
||||
while( *string )
|
||||
{
|
||||
char *s = strchr( string, '\n' );
|
||||
int len = s ? s + 1 - string : strlen( string );
|
||||
/* For each line of the string */
|
||||
|
||||
fputc( '$', f );
|
||||
while( *string )
|
||||
{
|
||||
char *s = strchr( string, '\n' );
|
||||
int len = s ? s + 1 - string : strlen( string );
|
||||
|
||||
/* For each chunk of a line that needs to be split */
|
||||
fputc( '$', f );
|
||||
|
||||
while( len > 0 )
|
||||
{
|
||||
char *q = string;
|
||||
char *qe = string + MIN( len, WRTLEN );
|
||||
char *qq = q;
|
||||
int quote = 0;
|
||||
/* For each chunk of a line that needs to be split */
|
||||
|
||||
/* Look for matching "'s */
|
||||
while( len > 0 )
|
||||
{
|
||||
char *q = string;
|
||||
char *qe = string + MIN( len, WRTLEN );
|
||||
char *qq = q;
|
||||
int quote = 0;
|
||||
|
||||
for( ; q < qe; q++ )
|
||||
if( *q == '"' && ( quote = !quote ) )
|
||||
qq = q;
|
||||
/* Look for matching "'s */
|
||||
|
||||
/* Back up to opening quote, if in one */
|
||||
for( ; q < qe; q++ )
|
||||
if( *q == '"' && ( quote = !quote ) )
|
||||
qq = q;
|
||||
|
||||
if( quote )
|
||||
q = qq;
|
||||
/* Back up to opening quote, if in one */
|
||||
|
||||
fwrite( string, ( q - string ), 1, f );
|
||||
if( quote )
|
||||
q = qq;
|
||||
|
||||
len -= ( q - string );
|
||||
string = q;
|
||||
fwrite( string, ( q - string ), 1, f );
|
||||
|
||||
if( len )
|
||||
{
|
||||
fputc( '-', f );
|
||||
fputc( '\n', f );
|
||||
}
|
||||
}
|
||||
}
|
||||
len -= ( q - string );
|
||||
string = q;
|
||||
|
||||
fclose( f );
|
||||
if( len )
|
||||
{
|
||||
fputc( '-', f );
|
||||
fputc( '\n', f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status = system( tempnambuf ) & 0x07;
|
||||
fclose( f );
|
||||
|
||||
unlink( tempnambuf + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Execute single line command */
|
||||
/* Strip trailing newline before execing */
|
||||
if( e ) *e = 0;
|
||||
status = system( s ) & 0x07;
|
||||
}
|
||||
status = system( tempnambuf ) & 0x07;
|
||||
|
||||
/* Fail for error or fatal error */
|
||||
/* OK on OK, warning, or info exit */
|
||||
unlink( tempnambuf + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Execute single line command */
|
||||
/* Strip trailing newline before execing */
|
||||
if( e ) *e = 0;
|
||||
status = system( s ) & 0x07;
|
||||
}
|
||||
|
||||
if( status == 2 || status == 4 )
|
||||
rstat = EXEC_CMD_FAIL;
|
||||
/* Fail for error or fatal error */
|
||||
/* OK on OK, warning, or info exit */
|
||||
|
||||
(*func)( closure, rstat );
|
||||
if( status == 2 || status == 4 )
|
||||
rstat = EXEC_CMD_FAIL;
|
||||
|
||||
(*func)( closure, rstat );
|
||||
}
|
||||
|
||||
int
|
||||
execwait()
|
||||
|
||||
int execwait()
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif /* VMS */
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* var_expand() - variable-expand input string into list of strings
|
||||
* var_expand() - variable-expand input string into list of strings
|
||||
*
|
||||
* Internal routines:
|
||||
*
|
||||
* var_edit_parse() - parse : modifiers into PATHNAME structure
|
||||
* var_edit_file() - copy input target name to output, modifying filename
|
||||
* var_edit_shift() - do upshift/downshift mods
|
||||
* var_edit_parse() - parse : modifiers into PATHNAME structure
|
||||
* var_edit_file() - copy input target name to output, modifying filename
|
||||
* var_edit_shift() - do upshift/downshift mods
|
||||
*
|
||||
* 01/25/94 (seiwald) - $(X)$(UNDEF) was expanding like plain $(X)
|
||||
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
|
||||
@@ -38,29 +38,29 @@
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
PATHNAME f; /* :GDBSMR -- pieces */
|
||||
char parent; /* :P -- go to parent directory */
|
||||
char filemods; /* one of the above applied */
|
||||
char downshift; /* :L -- downshift result */
|
||||
char upshift; /* :U -- upshift result */
|
||||
PATHNAME f; /* :GDBSMR -- pieces */
|
||||
char parent; /* :P -- go to parent directory */
|
||||
char filemods; /* one of the above applied */
|
||||
char downshift; /* :L -- downshift result */
|
||||
char upshift; /* :U -- upshift result */
|
||||
char to_slashes; /* :T -- convert "\" to "/" */
|
||||
char to_windows; /* :W -- convert cygwin to native paths */
|
||||
PATHPART empty; /* :E -- default for empties */
|
||||
PATHPART join; /* :J -- join list with char */
|
||||
PATHPART empty; /* :E -- default for empties */
|
||||
PATHPART join; /* :J -- join list with char */
|
||||
} VAR_EDITS ;
|
||||
|
||||
static void var_edit_parse( char *mods, VAR_EDITS *edits );
|
||||
static void var_edit_file( char *in, string *out, VAR_EDITS *edits );
|
||||
static void var_edit_shift( string *out, VAR_EDITS *edits );
|
||||
|
||||
# define MAGIC_COLON '\001'
|
||||
# define MAGIC_LEFT '\002'
|
||||
# define MAGIC_RIGHT '\003'
|
||||
# define MAGIC_COLON '\001'
|
||||
# define MAGIC_LEFT '\002'
|
||||
# define MAGIC_RIGHT '\003'
|
||||
|
||||
/*
|
||||
* var_expand() - variable-expand input string into list of strings
|
||||
*
|
||||
* Would just copy input to output, performing variable expansion,
|
||||
* Would just copy input to output, performing variable expansion,
|
||||
* except that since variables can contain multiple values the result
|
||||
* of variable expansion may contain multiple values (a list). Properly
|
||||
* performs "product" operations that occur in "$(var1)xxx$(var2)" or
|
||||
@@ -70,12 +70,12 @@ static void var_edit_shift( string *out, VAR_EDITS *edits );
|
||||
*/
|
||||
|
||||
LIST *
|
||||
var_expand(
|
||||
LIST *l,
|
||||
char *in,
|
||||
char *end,
|
||||
LOL *lol,
|
||||
int cancopyin )
|
||||
var_expand(
|
||||
LIST *l,
|
||||
char *in,
|
||||
char *end,
|
||||
LOL *lol,
|
||||
int cancopyin )
|
||||
{
|
||||
char out_buf[ MAXSYM ];
|
||||
string buf[1];
|
||||
@@ -83,7 +83,7 @@ var_expand(
|
||||
size_t prefix_length;
|
||||
char *out;
|
||||
char *inp = in;
|
||||
char *ov; /* for temp copy of variable in outbuf */
|
||||
char *ov; /* for temp copy of variable in outbuf */
|
||||
int depth;
|
||||
|
||||
if( DEBUG_VAREXP )
|
||||
@@ -100,7 +100,7 @@ var_expand(
|
||||
|
||||
case '>':
|
||||
return list_copy( l, lol_get( lol, 1 ) );
|
||||
|
||||
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
@@ -113,9 +113,9 @@ var_expand(
|
||||
return list_copy( l, lol_get( lol, in[2]-'1' ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Expand @() files, to single item plus accompanying file. */
|
||||
|
||||
|
||||
if ( in[0] == '@' && in[1] == '(' && *(end-1) == ')' )
|
||||
{
|
||||
/* We try the expansion until it fits within the propspective output buffer. */
|
||||
@@ -144,8 +144,8 @@ var_expand(
|
||||
|
||||
/* Just try simple copy of in to out. */
|
||||
|
||||
while( in < end )
|
||||
if( *in++ == '$' && *in == '(' )
|
||||
while ( in < end )
|
||||
if ( *in++ == '$' && *in == '(' )
|
||||
goto expand;
|
||||
|
||||
/* No variables expanded - just add copy of input string to list. */
|
||||
@@ -154,7 +154,7 @@ var_expand(
|
||||
/* item, we can use the copystr() to put it on the new list. */
|
||||
/* Otherwise, we use the slower newstr(). */
|
||||
|
||||
if( cancopyin )
|
||||
if( cancopyin )
|
||||
{
|
||||
return list_new( l, copystr( inp ) );
|
||||
}
|
||||
@@ -239,7 +239,7 @@ expand:
|
||||
* out_buf out ov
|
||||
*
|
||||
* Later we will overwrite 'variable' in out_buf, but we'll be
|
||||
* done with it by then. 'variable' may be a multi-element list,
|
||||
* done with it by then. 'variable' may be a multi-element list,
|
||||
* so may each value for '$(variable element)', and so may 'remainder'.
|
||||
* Thus we produce a product of three lists.
|
||||
*/
|
||||
@@ -339,7 +339,7 @@ expand:
|
||||
}
|
||||
|
||||
/* First, compute the index of the last element. */
|
||||
sub2 = atoi(s);
|
||||
sub2 = atoi(s);
|
||||
s++;
|
||||
while ( isdigit( *s ) ) s++;
|
||||
|
||||
@@ -353,7 +353,7 @@ expand:
|
||||
** introducing a modifier is a syntax error.
|
||||
*/
|
||||
|
||||
s++;
|
||||
s++;
|
||||
if (*s && *s != MAGIC_COLON)
|
||||
sub2 = 0;
|
||||
|
||||
@@ -361,14 +361,14 @@ expand:
|
||||
}
|
||||
|
||||
/* Get variable value, specially handling $(<), $(>), $(n) */
|
||||
|
||||
|
||||
if( varname[0] == '<' && !varname[1] )
|
||||
value = lol_get( lol, 0 );
|
||||
else if( varname[0] == '>' && !varname[1] )
|
||||
value = lol_get( lol, 1 );
|
||||
else if( varname[0] >= '1' && varname[0] <= '9' && !varname[1] )
|
||||
value = lol_get( lol, varname[0] - '1' );
|
||||
else
|
||||
else
|
||||
value = var_get( varname );
|
||||
|
||||
/* Handle negitive indexes: part two. */
|
||||
@@ -444,7 +444,7 @@ expand:
|
||||
/* keep appending them (with the join value) */
|
||||
/* rather than creating separate LIST elements. */
|
||||
|
||||
if( colon && edits.join.ptr &&
|
||||
if( colon && edits.join.ptr &&
|
||||
( list_next( value ) || list_next( vars ) ) )
|
||||
{
|
||||
string_append( out1, edits.join.ptr );
|
||||
@@ -511,160 +511,160 @@ expand:
|
||||
* var_edit_parse() - parse : modifiers into PATHNAME structure
|
||||
*
|
||||
* The : modifiers in a $(varname:modifier) currently support replacing
|
||||
* or omitting elements of a filename, and so they are parsed into a
|
||||
* or omitting elements of a filename, and so they are parsed into a
|
||||
* PATHNAME structure (which contains pointers into the original string).
|
||||
*
|
||||
* Modifiers of the form "X=value" replace the component X with
|
||||
* the given value. Modifiers without the "=value" cause everything
|
||||
* the given value. Modifiers without the "=value" cause everything
|
||||
* but the component X to be omitted. X is one of:
|
||||
*
|
||||
* G <grist>
|
||||
* D directory name
|
||||
* B base name
|
||||
* S .suffix
|
||||
* M (member)
|
||||
* R root directory - prepended to whole path
|
||||
* G <grist>
|
||||
* D directory name
|
||||
* B base name
|
||||
* S .suffix
|
||||
* M (member)
|
||||
* R root directory - prepended to whole path
|
||||
*
|
||||
* This routine sets:
|
||||
*
|
||||
* f->f_xxx.ptr = 0
|
||||
* f->f_xxx.len = 0
|
||||
* -> leave the original component xxx
|
||||
* f->f_xxx.ptr = 0
|
||||
* f->f_xxx.len = 0
|
||||
* -> leave the original component xxx
|
||||
*
|
||||
* f->f_xxx.ptr = string
|
||||
* f->f_xxx.len = strlen( string )
|
||||
* -> replace component xxx with string
|
||||
* f->f_xxx.ptr = string
|
||||
* f->f_xxx.len = strlen( string )
|
||||
* -> replace component xxx with string
|
||||
*
|
||||
* f->f_xxx.ptr = ""
|
||||
* f->f_xxx.len = 0
|
||||
* -> omit component xxx
|
||||
* f->f_xxx.ptr = ""
|
||||
* f->f_xxx.len = 0
|
||||
* -> omit component xxx
|
||||
*
|
||||
* var_edit_file() below and path_build() obligingly follow this convention.
|
||||
*/
|
||||
|
||||
static void
|
||||
var_edit_parse(
|
||||
char *mods,
|
||||
VAR_EDITS *edits )
|
||||
char *mods,
|
||||
VAR_EDITS *edits )
|
||||
{
|
||||
int havezeroed = 0;
|
||||
memset( (char *)edits, 0, sizeof( *edits ) );
|
||||
int havezeroed = 0;
|
||||
memset( (char *)edits, 0, sizeof( *edits ) );
|
||||
|
||||
while( *mods )
|
||||
{
|
||||
char *p;
|
||||
PATHPART *fp;
|
||||
while( *mods )
|
||||
{
|
||||
char *p;
|
||||
PATHPART *fp;
|
||||
|
||||
switch( *mods++ )
|
||||
{
|
||||
case 'L': edits->downshift = 1; continue;
|
||||
case 'U': edits->upshift = 1; continue;
|
||||
case 'P': edits->parent = edits->filemods = 1; continue;
|
||||
case 'E': fp = &edits->empty; goto strval;
|
||||
case 'J': fp = &edits->join; goto strval;
|
||||
case 'G': fp = &edits->f.f_grist; goto fileval;
|
||||
case 'R': fp = &edits->f.f_root; goto fileval;
|
||||
case 'D': fp = &edits->f.f_dir; goto fileval;
|
||||
case 'B': fp = &edits->f.f_base; goto fileval;
|
||||
case 'S': fp = &edits->f.f_suffix; goto fileval;
|
||||
case 'M': fp = &edits->f.f_member; goto fileval;
|
||||
switch( *mods++ )
|
||||
{
|
||||
case 'L': edits->downshift = 1; continue;
|
||||
case 'U': edits->upshift = 1; continue;
|
||||
case 'P': edits->parent = edits->filemods = 1; continue;
|
||||
case 'E': fp = &edits->empty; goto strval;
|
||||
case 'J': fp = &edits->join; goto strval;
|
||||
case 'G': fp = &edits->f.f_grist; goto fileval;
|
||||
case 'R': fp = &edits->f.f_root; goto fileval;
|
||||
case 'D': fp = &edits->f.f_dir; goto fileval;
|
||||
case 'B': fp = &edits->f.f_base; goto fileval;
|
||||
case 'S': fp = &edits->f.f_suffix; goto fileval;
|
||||
case 'M': fp = &edits->f.f_member; goto fileval;
|
||||
case 'T': edits->to_slashes = 1; continue;
|
||||
case 'W': edits->to_windows = 1; continue;
|
||||
|
||||
default: return; /* should complain, but so what... */
|
||||
}
|
||||
default: return; /* should complain, but so what... */
|
||||
}
|
||||
|
||||
fileval:
|
||||
fileval:
|
||||
|
||||
/* Handle :CHARS, where each char (without a following =) */
|
||||
/* selects a particular file path element. On the first such */
|
||||
/* char, we deselect all others (by setting ptr = "", len = 0) */
|
||||
/* and for each char we select that element (by setting ptr = 0) */
|
||||
/* Handle :CHARS, where each char (without a following =) */
|
||||
/* selects a particular file path element. On the first such */
|
||||
/* char, we deselect all others (by setting ptr = "", len = 0) */
|
||||
/* and for each char we select that element (by setting ptr = 0) */
|
||||
|
||||
edits->filemods = 1;
|
||||
edits->filemods = 1;
|
||||
|
||||
if( *mods != '=' )
|
||||
{
|
||||
int i;
|
||||
if( *mods != '=' )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !havezeroed++ )
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
edits->f.part[ i ].len = 0;
|
||||
edits->f.part[ i ].ptr = "";
|
||||
}
|
||||
if( !havezeroed++ )
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
edits->f.part[ i ].len = 0;
|
||||
edits->f.part[ i ].ptr = "";
|
||||
}
|
||||
|
||||
fp->ptr = 0;
|
||||
continue;
|
||||
}
|
||||
fp->ptr = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
strval:
|
||||
strval:
|
||||
|
||||
/* Handle :X=value, or :X */
|
||||
/* Handle :X=value, or :X */
|
||||
|
||||
if( *mods != '=' )
|
||||
{
|
||||
fp->ptr = "";
|
||||
fp->len = 0;
|
||||
}
|
||||
else if( p = strchr( mods, MAGIC_COLON ) )
|
||||
{
|
||||
*p = 0;
|
||||
fp->ptr = ++mods;
|
||||
fp->len = p - mods;
|
||||
mods = p + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fp->ptr = ++mods;
|
||||
fp->len = strlen( mods );
|
||||
mods += fp->len;
|
||||
}
|
||||
}
|
||||
if( *mods != '=' )
|
||||
{
|
||||
fp->ptr = "";
|
||||
fp->len = 0;
|
||||
}
|
||||
else if( p = strchr( mods, MAGIC_COLON ) )
|
||||
{
|
||||
*p = 0;
|
||||
fp->ptr = ++mods;
|
||||
fp->len = p - mods;
|
||||
mods = p + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fp->ptr = ++mods;
|
||||
fp->len = strlen( mods );
|
||||
mods += fp->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* var_edit_file() - copy input target name to output, modifying filename
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
var_edit_file(
|
||||
char *in,
|
||||
string *out,
|
||||
VAR_EDITS *edits )
|
||||
var_edit_file(
|
||||
char *in,
|
||||
string *out,
|
||||
VAR_EDITS *edits )
|
||||
{
|
||||
PATHNAME pathname;
|
||||
PATHNAME pathname;
|
||||
|
||||
/* Parse apart original filename, putting parts into "pathname" */
|
||||
/* Parse apart original filename, putting parts into "pathname" */
|
||||
|
||||
path_parse( in, &pathname );
|
||||
path_parse( in, &pathname );
|
||||
|
||||
/* Replace any pathname with edits->f */
|
||||
/* Replace any pathname with edits->f */
|
||||
|
||||
if( edits->f.f_grist.ptr )
|
||||
pathname.f_grist = edits->f.f_grist;
|
||||
if( edits->f.f_grist.ptr )
|
||||
pathname.f_grist = edits->f.f_grist;
|
||||
|
||||
if( edits->f.f_root.ptr )
|
||||
pathname.f_root = edits->f.f_root;
|
||||
if( edits->f.f_root.ptr )
|
||||
pathname.f_root = edits->f.f_root;
|
||||
|
||||
if( edits->f.f_dir.ptr )
|
||||
pathname.f_dir = edits->f.f_dir;
|
||||
if( edits->f.f_dir.ptr )
|
||||
pathname.f_dir = edits->f.f_dir;
|
||||
|
||||
if( edits->f.f_base.ptr )
|
||||
pathname.f_base = edits->f.f_base;
|
||||
if( edits->f.f_base.ptr )
|
||||
pathname.f_base = edits->f.f_base;
|
||||
|
||||
if( edits->f.f_suffix.ptr )
|
||||
pathname.f_suffix = edits->f.f_suffix;
|
||||
if( edits->f.f_suffix.ptr )
|
||||
pathname.f_suffix = edits->f.f_suffix;
|
||||
|
||||
if( edits->f.f_member.ptr )
|
||||
pathname.f_member = edits->f.f_member;
|
||||
if( edits->f.f_member.ptr )
|
||||
pathname.f_member = edits->f.f_member;
|
||||
|
||||
/* If requested, modify pathname to point to parent */
|
||||
/* If requested, modify pathname to point to parent */
|
||||
|
||||
if( edits->parent )
|
||||
path_parent( &pathname );
|
||||
if( edits->parent )
|
||||
path_parent( &pathname );
|
||||
|
||||
/* Put filename back together */
|
||||
/* Put filename back together */
|
||||
|
||||
path_build( &pathname, out, 0 );
|
||||
}
|
||||
@@ -674,11 +674,11 @@ var_edit_file(
|
||||
*/
|
||||
|
||||
static void
|
||||
var_edit_shift(
|
||||
string *out,
|
||||
VAR_EDITS *edits )
|
||||
var_edit_shift(
|
||||
string *out,
|
||||
VAR_EDITS *edits )
|
||||
{
|
||||
/* Handle upshifting, downshifting and slash translation now */
|
||||
/* Handle upshifting, downshifting and slash translation now */
|
||||
|
||||
char *p;
|
||||
for ( p = out->value; *p; ++p)
|
||||
@@ -690,7 +690,7 @@ var_edit_shift(
|
||||
else if ( edits->downshift )
|
||||
{
|
||||
*p = tolower( *p );
|
||||
}
|
||||
}
|
||||
if ( edits->to_slashes )
|
||||
{
|
||||
if ( *p == '\\')
|
||||
@@ -720,14 +720,14 @@ void var_expand_unit_test()
|
||||
char axyb[] = "a$(xy)b";
|
||||
char azb[] = "a$($(z))b";
|
||||
char path[] = "$(p:W)";
|
||||
|
||||
|
||||
# ifdef OS_CYGWIN
|
||||
char cygpath[256];
|
||||
cygwin_conv_to_posix_path("c:\\foo\\bar", cygpath);
|
||||
# else
|
||||
char cygpath[] = "/cygdrive/c/foo/bar";
|
||||
# endif
|
||||
|
||||
|
||||
lol_init(lol);
|
||||
var_set("xy", list_new( list_new( L0, newstr( "x" ) ), newstr( "y" ) ), VAR_SET );
|
||||
var_set("z", list_new( L0, newstr( "xy" ) ), VAR_SET );
|
||||
@@ -738,7 +738,7 @@ void var_expand_unit_test()
|
||||
assert( !strcmp( e2->string, l2->string ) );
|
||||
assert(l2 == 0 && e2 == 0);
|
||||
list_free(l);
|
||||
|
||||
|
||||
l = var_expand( 0, azb, azb + sizeof(azb) - 1, lol, 0 );
|
||||
for ( l2 = l, e2 = expected; l2 && e2; l2 = list_next(l2), e2 = list_next(e2) )
|
||||
assert( !strcmp( e2->string, l2->string ) );
|
||||
@@ -753,15 +753,15 @@ void var_expand_unit_test()
|
||||
/* This has been reported to be the case if cygwin has been installed to C:\ */
|
||||
/* as opposed to C:\cygwin */
|
||||
/* Since case of the drive letter will not matter, we allow for both. */
|
||||
assert( 0 == strcmp( l->string, "c:\\foo\\bar" )
|
||||
assert( 0 == strcmp( l->string, "c:\\foo\\bar" )
|
||||
|| 0 == strcmp( l->string, "C:\\foo\\bar") );
|
||||
# else
|
||||
# else
|
||||
assert( !strcmp( l->string, cygpath ) );
|
||||
# endif
|
||||
# endif
|
||||
list_free(l);
|
||||
|
||||
list_free(expected);
|
||||
|
||||
|
||||
lol_free(lol);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
|
||||
#include "lists.h"
|
||||
|
||||
LIST *var_expand( LIST *l, char *in, char *end, LOL *lol, int cancopyin );
|
||||
LIST *var_expand( LIST *l, char *in, char *end, LOL *lol, int cancopyin );
|
||||
void var_expand_unit_test();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of Jam - see jam.c for Copyright information.
|
||||
*/
|
||||
|
||||
|
||||
/* This file is ALSO:
|
||||
* Copyright 2001-2004 David Abrahams.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -26,9 +26,9 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
*
|
||||
* File_dirscan() and file_archscan() call back a caller provided function
|
||||
* for each file found. A flag to this callback function lets file_dirscan()
|
||||
@@ -45,23 +45,21 @@
|
||||
|
||||
void CopyC2PStr(const char * cstr, StringPtr pstr)
|
||||
{
|
||||
int len;
|
||||
|
||||
for (len = 0; *cstr && len<255; pstr[++len] = *cstr++)
|
||||
;
|
||||
|
||||
pstr[0] = len;
|
||||
int len;
|
||||
for ( len = 0; *cstr && len < 255; pstr[++len] = *cstr++ );
|
||||
pstr[0] = len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* file_dirscan() - scan a directory for files
|
||||
*/
|
||||
|
||||
void
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
PATHNAME f;
|
||||
string filename[1];
|
||||
@@ -69,10 +67,10 @@ file_dirscan(
|
||||
|
||||
FSSpec spec;
|
||||
WDPBRec vol;
|
||||
Str63 volName;
|
||||
Str63 volName;
|
||||
CInfoPBRec lastInfo;
|
||||
int index = 1;
|
||||
|
||||
|
||||
/* First enter directory itself */
|
||||
|
||||
memset( (char *)&f, '\0', sizeof( f ) );
|
||||
@@ -82,30 +80,30 @@ file_dirscan(
|
||||
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "scan directory %s\n", dir );
|
||||
|
||||
|
||||
/* Special case ":" - enter it */
|
||||
|
||||
if( f.f_dir.len == 1 && f.f_dir.ptr[0] == ':' )
|
||||
(*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
|
||||
(*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
|
||||
|
||||
/* Now enter contents of directory */
|
||||
|
||||
vol.ioNamePtr = volName;
|
||||
|
||||
|
||||
if( PBHGetVolSync( &vol ) )
|
||||
return;
|
||||
|
||||
CopyC2PStr( dir, fullPath );
|
||||
|
||||
|
||||
if( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) )
|
||||
return;
|
||||
|
||||
lastInfo.dirInfo.ioVRefNum = spec.vRefNum;
|
||||
lastInfo.dirInfo.ioDrDirID = spec.parID;
|
||||
lastInfo.dirInfo.ioNamePtr = spec.name;
|
||||
lastInfo.dirInfo.ioFDirIndex = 0;
|
||||
lastInfo.dirInfo.ioACUser = 0;
|
||||
|
||||
|
||||
lastInfo.dirInfo.ioVRefNum = spec.vRefNum;
|
||||
lastInfo.dirInfo.ioDrDirID = spec.parID;
|
||||
lastInfo.dirInfo.ioNamePtr = spec.name;
|
||||
lastInfo.dirInfo.ioFDirIndex = 0;
|
||||
lastInfo.dirInfo.ioACUser = 0;
|
||||
|
||||
if( PBGetCatInfoSync(&lastInfo) )
|
||||
return;
|
||||
|
||||
@@ -113,20 +111,20 @@ file_dirscan(
|
||||
return;
|
||||
|
||||
// ioDrDirID must be reset each time.
|
||||
|
||||
|
||||
spec.parID = lastInfo.dirInfo.ioDrDirID;
|
||||
|
||||
string_new( filename );
|
||||
for( ;; )
|
||||
{
|
||||
lastInfo.dirInfo.ioVRefNum = spec.vRefNum;
|
||||
lastInfo.dirInfo.ioDrDirID = spec.parID;
|
||||
lastInfo.dirInfo.ioNamePtr = fullPath;
|
||||
lastInfo.dirInfo.ioVRefNum = spec.vRefNum;
|
||||
lastInfo.dirInfo.ioDrDirID = spec.parID;
|
||||
lastInfo.dirInfo.ioNamePtr = fullPath;
|
||||
lastInfo.dirInfo.ioFDirIndex = index++;
|
||||
|
||||
|
||||
if( PBGetCatInfoSync(&lastInfo) )
|
||||
return;
|
||||
|
||||
|
||||
f.f_base.ptr = (char *)fullPath + 1;
|
||||
f.f_base.len = *fullPath;
|
||||
|
||||
@@ -142,31 +140,32 @@ file_dirscan(
|
||||
*/
|
||||
|
||||
int
|
||||
file_time(
|
||||
char *filename,
|
||||
time_t *time )
|
||||
file_time(
|
||||
char *filename,
|
||||
time_t *time )
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct stat statbuf;
|
||||
|
||||
if( stat( filename, &statbuf ) < 0 )
|
||||
return -1;
|
||||
if( stat( filename, &statbuf ) < 0 )
|
||||
return -1;
|
||||
|
||||
*time = statbuf.st_mtime;
|
||||
|
||||
return 0;
|
||||
*time = statbuf.st_mtime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int file_is_file(char* filename)
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct stat statbuf;
|
||||
|
||||
if( stat( filename, &statbuf ) < 0 )
|
||||
return -1;
|
||||
if( stat( filename, &statbuf ) < 0 )
|
||||
return -1;
|
||||
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
if ( S_ISREG( statbuf.st_mode ) )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,9 +175,9 @@ int file_is_file(char* filename)
|
||||
|
||||
void
|
||||
file_archscan(
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
# include <dir.h>
|
||||
# include <dos.h>
|
||||
# endif
|
||||
# undef FILENAME /* cpp namespace collision */
|
||||
# undef FILENAME /* cpp namespace collision */
|
||||
# define _finddata_t ffblk
|
||||
# endif
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
*
|
||||
* File_dirscan() and file_archscan() call back a caller provided function
|
||||
* for each file found. A flag to this callback function lets file_dirscan()
|
||||
@@ -58,12 +58,12 @@
|
||||
|
||||
void
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
PROFILE_ENTER(FILE_DIRSCAN);
|
||||
|
||||
|
||||
file_info_t * d = 0;
|
||||
|
||||
dir = short_path_to_long_path( dir );
|
||||
@@ -71,7 +71,7 @@ file_dirscan(
|
||||
/* First enter directory itself */
|
||||
|
||||
d = file_query( dir );
|
||||
|
||||
|
||||
if ( ! d || ! d->is_dir )
|
||||
{
|
||||
PROFILE_EXIT(FILE_DIRSCAN);
|
||||
@@ -90,7 +90,7 @@ file_dirscan(
|
||||
int d_length = strlen( d->name );
|
||||
|
||||
memset( (char *)&f, '\0', sizeof( f ) );
|
||||
|
||||
|
||||
f.f_dir.ptr = d->name;
|
||||
f.f_dir.len = d_length;
|
||||
|
||||
@@ -128,7 +128,7 @@ file_dirscan(
|
||||
while( !ret )
|
||||
{
|
||||
file_info_t * ff = 0;
|
||||
|
||||
|
||||
f.f_base.ptr = finfo->ff_name;
|
||||
f.f_base.len = strlen( finfo->ff_name );
|
||||
|
||||
@@ -179,7 +179,7 @@ file_dirscan(
|
||||
# endif
|
||||
string_free( filename );
|
||||
string_free( filespec );
|
||||
|
||||
|
||||
d->files = files;
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ file_dirscan(
|
||||
files = list_next( files );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROFILE_EXIT(FILE_DIRSCAN);
|
||||
}
|
||||
|
||||
@@ -231,8 +231,8 @@ file_info_t * file_query( char * filename )
|
||||
|
||||
int
|
||||
file_time(
|
||||
char *filename,
|
||||
time_t *time )
|
||||
char *filename,
|
||||
time_t *time )
|
||||
{
|
||||
file_info_t * ff = file_query( filename );
|
||||
if ( !ff ) return -1;
|
||||
@@ -254,19 +254,19 @@ int file_is_file(char* filename)
|
||||
|
||||
/* Straight from SunOS */
|
||||
|
||||
#define ARMAG "!<arch>\n"
|
||||
#define SARMAG 8
|
||||
#define ARMAG "!<arch>\n"
|
||||
#define SARMAG 8
|
||||
|
||||
#define ARFMAG "`\n"
|
||||
#define ARFMAG "`\n"
|
||||
|
||||
struct ar_hdr {
|
||||
char ar_name[16];
|
||||
char ar_date[12];
|
||||
char ar_uid[6];
|
||||
char ar_gid[6];
|
||||
char ar_mode[8];
|
||||
char ar_size[10];
|
||||
char ar_fmag[2];
|
||||
char ar_name[16];
|
||||
char ar_date[12];
|
||||
char ar_uid[6];
|
||||
char ar_gid[6];
|
||||
char ar_mode[8];
|
||||
char ar_size[10];
|
||||
char ar_fmag[2];
|
||||
};
|
||||
|
||||
# define SARFMAG 2
|
||||
@@ -274,98 +274,98 @@ struct ar_hdr {
|
||||
|
||||
void
|
||||
file_archscan(
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
struct ar_hdr ar_hdr;
|
||||
char *string_table = 0;
|
||||
char buf[ MAXJPATH ];
|
||||
long offset;
|
||||
int fd;
|
||||
struct ar_hdr ar_hdr;
|
||||
char *string_table = 0;
|
||||
char buf[ MAXJPATH ];
|
||||
long offset;
|
||||
int fd;
|
||||
|
||||
if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 )
|
||||
return;
|
||||
if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 )
|
||||
return;
|
||||
|
||||
if( read( fd, buf, SARMAG ) != SARMAG ||
|
||||
strncmp( ARMAG, buf, SARMAG ) )
|
||||
{
|
||||
close( fd );
|
||||
return;
|
||||
}
|
||||
if( read( fd, buf, SARMAG ) != SARMAG ||
|
||||
strncmp( ARMAG, buf, SARMAG ) )
|
||||
{
|
||||
close( fd );
|
||||
return;
|
||||
}
|
||||
|
||||
offset = SARMAG;
|
||||
offset = SARMAG;
|
||||
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "scan archive %s\n", archive );
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "scan archive %s\n", archive );
|
||||
|
||||
while( read( fd, &ar_hdr, SARHDR ) == SARHDR &&
|
||||
!memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) )
|
||||
{
|
||||
long lar_date;
|
||||
long lar_size;
|
||||
char *name = 0;
|
||||
char *endname;
|
||||
char *c;
|
||||
while( read( fd, &ar_hdr, SARHDR ) == SARHDR &&
|
||||
!memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) )
|
||||
{
|
||||
long lar_date;
|
||||
long lar_size;
|
||||
char *name = 0;
|
||||
char *endname;
|
||||
char *c;
|
||||
|
||||
sscanf( ar_hdr.ar_date, "%ld", &lar_date );
|
||||
sscanf( ar_hdr.ar_size, "%ld", &lar_size );
|
||||
sscanf( ar_hdr.ar_date, "%ld", &lar_date );
|
||||
sscanf( ar_hdr.ar_size, "%ld", &lar_size );
|
||||
|
||||
lar_size = ( lar_size + 1 ) & ~1;
|
||||
lar_size = ( lar_size + 1 ) & ~1;
|
||||
|
||||
if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' )
|
||||
{
|
||||
/* this is the "string table" entry of the symbol table,
|
||||
** which holds strings of filenames that are longer than
|
||||
** 15 characters (ie. don't fit into a ar_name
|
||||
*/
|
||||
if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' )
|
||||
{
|
||||
/* this is the "string table" entry of the symbol table,
|
||||
** which holds strings of filenames that are longer than
|
||||
** 15 characters (ie. don't fit into a ar_name
|
||||
*/
|
||||
|
||||
string_table = BJAM_MALLOC_ATOMIC(lar_size+1);
|
||||
if (read(fd, string_table, lar_size) != lar_size)
|
||||
printf("error reading string table\n");
|
||||
string_table[lar_size] = '\0';
|
||||
offset += SARHDR + lar_size;
|
||||
continue;
|
||||
}
|
||||
else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ')
|
||||
{
|
||||
/* Long filenames are recognized by "/nnnn" where nnnn is
|
||||
** the offset of the string in the string table represented
|
||||
** in ASCII decimals.
|
||||
*/
|
||||
string_table = BJAM_MALLOC_ATOMIC(lar_size+1);
|
||||
if (read(fd, string_table, lar_size) != lar_size)
|
||||
printf("error reading string table\n");
|
||||
string_table[lar_size] = '\0';
|
||||
offset += SARHDR + lar_size;
|
||||
continue;
|
||||
}
|
||||
else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ')
|
||||
{
|
||||
/* Long filenames are recognized by "/nnnn" where nnnn is
|
||||
** the offset of the string in the string table represented
|
||||
** in ASCII decimals.
|
||||
*/
|
||||
|
||||
name = string_table + atoi( ar_hdr.ar_name + 1 );
|
||||
for ( endname = name; *endname && *endname != '\n'; ++endname) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* normal name */
|
||||
name = ar_hdr.ar_name;
|
||||
endname = name + sizeof( ar_hdr.ar_name );
|
||||
}
|
||||
name = string_table + atoi( ar_hdr.ar_name + 1 );
|
||||
for ( endname = name; *endname && *endname != '\n'; ++endname) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* normal name */
|
||||
name = ar_hdr.ar_name;
|
||||
endname = name + sizeof( ar_hdr.ar_name );
|
||||
}
|
||||
|
||||
/* strip trailing white-space, slashes, and backslashes */
|
||||
/* strip trailing white-space, slashes, and backslashes */
|
||||
|
||||
while( endname-- > name )
|
||||
if( !isspace(*endname) && *endname != '\\' && *endname != '/' )
|
||||
break;
|
||||
*++endname = 0;
|
||||
while( endname-- > name )
|
||||
if( !isspace(*endname) && *endname != '\\' && *endname != '/' )
|
||||
break;
|
||||
*++endname = 0;
|
||||
|
||||
/* strip leading directory names, an NT specialty */
|
||||
/* strip leading directory names, an NT specialty */
|
||||
|
||||
if( c = strrchr( name, '/' ) )
|
||||
name = c + 1;
|
||||
if( c = strrchr( name, '\\' ) )
|
||||
name = c + 1;
|
||||
if( c = strrchr( name, '/' ) )
|
||||
name = c + 1;
|
||||
if( c = strrchr( name, '\\' ) )
|
||||
name = c + 1;
|
||||
|
||||
sprintf( buf, "%s(%.*s)", archive, endname - name, name );
|
||||
(*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
|
||||
sprintf( buf, "%s(%.*s)", archive, endname - name, name );
|
||||
(*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
|
||||
|
||||
offset += SARHDR + lar_size;
|
||||
lseek( fd, offset, 0 );
|
||||
}
|
||||
offset += SARHDR + lar_size;
|
||||
lseek( fd, offset, 0 );
|
||||
}
|
||||
|
||||
close( fd );
|
||||
close( fd );
|
||||
}
|
||||
|
||||
# endif /* NT */
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
*
|
||||
* File_dirscan() and file_archscan() call back a caller provided function
|
||||
* for each file found. A flag to this callback function lets file_dirscan()
|
||||
@@ -45,10 +45,10 @@
|
||||
*/
|
||||
|
||||
void
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
PATHNAME f;
|
||||
string filespec[1];
|
||||
@@ -69,9 +69,9 @@ file_dirscan(
|
||||
string_copy( filespec, dir );
|
||||
|
||||
if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
|
||||
(*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
|
||||
(*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
|
||||
else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' )
|
||||
(*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
|
||||
(*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
|
||||
else
|
||||
string_push_back( filespec, '/' );
|
||||
|
||||
@@ -92,7 +92,6 @@ file_dirscan(
|
||||
string_new( filename );
|
||||
do
|
||||
{
|
||||
|
||||
f.f_base.ptr = finfo->name;
|
||||
f.f_base.len = strlen( finfo->name );
|
||||
|
||||
@@ -111,27 +110,27 @@ file_dirscan(
|
||||
|
||||
int
|
||||
file_time(
|
||||
char *filename,
|
||||
time_t *time )
|
||||
char *filename,
|
||||
time_t *time )
|
||||
{
|
||||
/* This is called on OS2, not NT. */
|
||||
/* NT fills in the time in the dirscan. */
|
||||
/* This is called on OS2, not NT. */
|
||||
/* NT fills in the time in the dirscan. */
|
||||
|
||||
struct stat statbuf;
|
||||
struct stat statbuf;
|
||||
|
||||
if( stat( filename, &statbuf ) < 0 )
|
||||
return -1;
|
||||
if( stat( filename, &statbuf ) < 0 )
|
||||
return -1;
|
||||
|
||||
*time = statbuf.st_mtime;
|
||||
*time = statbuf.st_mtime;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
file_archscan(
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -12,16 +12,16 @@ file_build1(
|
||||
{
|
||||
if( DEBUG_SEARCH )
|
||||
{
|
||||
printf("build file: ");
|
||||
if( f->f_root.len )
|
||||
printf("build file: ");
|
||||
if( f->f_root.len )
|
||||
printf( "root = '%.*s' ", f->f_root.len, f->f_root.ptr );
|
||||
if( f->f_dir.len )
|
||||
if( f->f_dir.len )
|
||||
printf( "dir = '%.*s' ", f->f_dir.len, f->f_dir.ptr );
|
||||
if( f->f_base.len )
|
||||
if( f->f_base.len )
|
||||
printf( "base = '%.*s' ", f->f_base.len, f->f_base.ptr );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
/* Start with the grist. If the current grist isn't */
|
||||
/* surrounded by <>'s, add them. */
|
||||
|
||||
@@ -41,10 +41,10 @@ static struct hash * filecache_hash = 0;
|
||||
file_info_t * file_info(char * filename)
|
||||
{
|
||||
file_info_t finfo_, *finfo = &finfo_;
|
||||
|
||||
|
||||
if ( !filecache_hash )
|
||||
filecache_hash = hashinit( sizeof( file_info_t ), "file_info" );
|
||||
|
||||
|
||||
finfo->name = filename;
|
||||
if ( hashenter( filecache_hash, (HASHDATA**)&finfo ) )
|
||||
{
|
||||
@@ -56,7 +56,7 @@ file_info_t * file_info(char * filename)
|
||||
finfo->time = 0;
|
||||
finfo->files = 0;
|
||||
}
|
||||
|
||||
|
||||
return finfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* filesys.h - OS specific file routines
|
||||
* filesys.h - OS specific file routines
|
||||
*/
|
||||
|
||||
#ifndef FILESYS_DWA20011025_H
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
# if defined( OS_SEQUENT ) || \
|
||||
defined( OS_DGUX ) || \
|
||||
defined( OS_SCO ) || \
|
||||
defined( OS_ISC )
|
||||
defined( OS_ISC )
|
||||
# define PORTAR 1
|
||||
# endif
|
||||
|
||||
@@ -46,10 +46,10 @@
|
||||
/* need unistd for rhapsody's proper lseek */
|
||||
# include <sys/dir.h>
|
||||
# include <unistd.h>
|
||||
# define STRUCT_DIRENT struct direct
|
||||
# define STRUCT_DIRENT struct direct
|
||||
# else
|
||||
# include <dirent.h>
|
||||
# define STRUCT_DIRENT struct dirent
|
||||
# define STRUCT_DIRENT struct dirent
|
||||
# endif
|
||||
|
||||
# ifdef OS_COHERENT
|
||||
@@ -58,21 +58,21 @@
|
||||
# endif
|
||||
|
||||
# if defined( OS_MVS ) || \
|
||||
defined( OS_INTERIX )
|
||||
defined( OS_INTERIX )
|
||||
|
||||
#define ARMAG "!<arch>\n"
|
||||
#define SARMAG 8
|
||||
#define ARFMAG "`\n"
|
||||
#define ARMAG "!<arch>\n"
|
||||
#define SARMAG 8
|
||||
#define ARFMAG "`\n"
|
||||
|
||||
struct ar_hdr /* archive file member header - printable ascii */
|
||||
struct ar_hdr /* archive file member header - printable ascii */
|
||||
{
|
||||
char ar_name[16]; /* file member name - `/' terminated */
|
||||
char ar_date[12]; /* file member date - decimal */
|
||||
char ar_uid[6]; /* file member user id - decimal */
|
||||
char ar_gid[6]; /* file member group id - decimal */
|
||||
char ar_mode[8]; /* file member mode - octal */
|
||||
char ar_size[10]; /* file member size - decimal */
|
||||
char ar_fmag[2]; /* ARFMAG - string to end header */
|
||||
char ar_name[16]; /* file member name - `/' terminated */
|
||||
char ar_date[12]; /* file member date - decimal */
|
||||
char ar_uid[6]; /* file member user id - decimal */
|
||||
char ar_gid[6]; /* file member group id - decimal */
|
||||
char ar_mode[8]; /* file member mode - octal */
|
||||
char ar_size[10]; /* file member size - decimal */
|
||||
char ar_fmag[2]; /* ARFMAG - string to end header */
|
||||
};
|
||||
|
||||
# define HAVE_AR
|
||||
@@ -90,21 +90,21 @@ struct ar_hdr /* archive file member header - printable ascii */
|
||||
# ifdef OS_AIX
|
||||
/* Define those for AIX to get the definitions for both the small and the
|
||||
* big variant of the archive file format. */
|
||||
# define __AR_SMALL__
|
||||
# define __AR_BIG__
|
||||
# define __AR_SMALL__
|
||||
# define __AR_BIG__
|
||||
# endif
|
||||
|
||||
# include <ar.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*
|
||||
* fileunix.c - manipulate file names and scan directories on UNIX/AmigaOS
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
*
|
||||
* File_dirscan() and file_archscan() call back a caller provided function
|
||||
* for each file found. A flag to this callback function lets file_dirscan()
|
||||
@@ -124,17 +124,17 @@ struct ar_hdr /* archive file member header - printable ascii */
|
||||
*/
|
||||
|
||||
void
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
PROFILE_ENTER(FILE_DIRSCAN);
|
||||
|
||||
|
||||
file_info_t * d = 0;
|
||||
|
||||
d = file_query( dir );
|
||||
|
||||
|
||||
if ( ! d || ! d->is_dir )
|
||||
{
|
||||
PROFILE_EXIT(FILE_DIRSCAN);
|
||||
@@ -173,7 +173,7 @@ file_dirscan(
|
||||
while( dirent = readdir( dd ) )
|
||||
{
|
||||
file_info_t * ff = 0;
|
||||
|
||||
|
||||
# ifdef old_sinix
|
||||
/* Broken structure definition on sinix. */
|
||||
f.f_base.ptr = dirent->d_name - 2;
|
||||
@@ -191,7 +191,7 @@ file_dirscan(
|
||||
string_free( filename );
|
||||
|
||||
closedir( dd );
|
||||
|
||||
|
||||
d->files = files;
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ file_dirscan(
|
||||
files = list_next( files );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROFILE_EXIT(FILE_DIRSCAN);
|
||||
}
|
||||
|
||||
@@ -241,8 +241,8 @@ file_info_t * file_query( char * filename )
|
||||
|
||||
int
|
||||
file_time(
|
||||
char *filename,
|
||||
time_t *time )
|
||||
char *filename,
|
||||
time_t *time )
|
||||
{
|
||||
file_info_t * ff = file_query( filename );
|
||||
if ( !ff ) return -1;
|
||||
@@ -262,109 +262,109 @@ int file_is_file(char* filename)
|
||||
* file_archscan() - scan an archive for files
|
||||
*/
|
||||
|
||||
# ifndef AIAMAG /* God-fearing UNIX */
|
||||
# ifndef AIAMAG /* God-fearing UNIX */
|
||||
|
||||
# define SARFMAG 2
|
||||
# define SARHDR sizeof( struct ar_hdr )
|
||||
|
||||
void
|
||||
file_archscan(
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
# ifndef NO_AR
|
||||
struct ar_hdr ar_hdr;
|
||||
char buf[ MAXJPATH ];
|
||||
long offset;
|
||||
char *string_table = 0;
|
||||
int fd;
|
||||
struct ar_hdr ar_hdr;
|
||||
char buf[ MAXJPATH ];
|
||||
long offset;
|
||||
char *string_table = 0;
|
||||
int fd;
|
||||
|
||||
if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 )
|
||||
return;
|
||||
if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 )
|
||||
return;
|
||||
|
||||
if( read( fd, buf, SARMAG ) != SARMAG ||
|
||||
strncmp( ARMAG, buf, SARMAG ) )
|
||||
{
|
||||
close( fd );
|
||||
return;
|
||||
}
|
||||
if( read( fd, buf, SARMAG ) != SARMAG ||
|
||||
strncmp( ARMAG, buf, SARMAG ) )
|
||||
{
|
||||
close( fd );
|
||||
return;
|
||||
}
|
||||
|
||||
offset = SARMAG;
|
||||
offset = SARMAG;
|
||||
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "scan archive %s\n", archive );
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "scan archive %s\n", archive );
|
||||
|
||||
while( read( fd, &ar_hdr, SARHDR ) == SARHDR
|
||||
&& ! ( memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG )
|
||||
while( read( fd, &ar_hdr, SARHDR ) == SARHDR
|
||||
&& ! ( memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG )
|
||||
#ifdef ARFZMAG
|
||||
/* OSF also has a compressed format */
|
||||
&& memcmp( ar_hdr.ar_fmag, ARFZMAG, SARFMAG )
|
||||
/* OSF also has a compressed format */
|
||||
&& memcmp( ar_hdr.ar_fmag, ARFZMAG, SARFMAG )
|
||||
#endif
|
||||
) )
|
||||
{
|
||||
char lar_name_[257];
|
||||
) )
|
||||
{
|
||||
char lar_name_[257];
|
||||
char* lar_name = lar_name_ + 1;
|
||||
long lar_date;
|
||||
long lar_size;
|
||||
long lar_offset;
|
||||
char *c;
|
||||
char *src, *dest;
|
||||
long lar_date;
|
||||
long lar_size;
|
||||
long lar_offset;
|
||||
char *c;
|
||||
char *src, *dest;
|
||||
|
||||
strncpy( lar_name, ar_hdr.ar_name, sizeof(ar_hdr.ar_name) );
|
||||
strncpy( lar_name, ar_hdr.ar_name, sizeof(ar_hdr.ar_name) );
|
||||
|
||||
sscanf( ar_hdr.ar_date, "%ld", &lar_date );
|
||||
sscanf( ar_hdr.ar_size, "%ld", &lar_size );
|
||||
sscanf( ar_hdr.ar_date, "%ld", &lar_date );
|
||||
sscanf( ar_hdr.ar_size, "%ld", &lar_size );
|
||||
|
||||
if (ar_hdr.ar_name[0] == '/')
|
||||
{
|
||||
if (ar_hdr.ar_name[1] == '/')
|
||||
{
|
||||
/* this is the "string table" entry of the symbol table,
|
||||
** which holds strings of filenames that are longer than
|
||||
** 15 characters (ie. don't fit into a ar_name
|
||||
*/
|
||||
if (ar_hdr.ar_name[0] == '/')
|
||||
{
|
||||
if (ar_hdr.ar_name[1] == '/')
|
||||
{
|
||||
/* this is the "string table" entry of the symbol table,
|
||||
** which holds strings of filenames that are longer than
|
||||
** 15 characters (ie. don't fit into a ar_name
|
||||
*/
|
||||
|
||||
string_table = (char *)BJAM_MALLOC_ATOMIC(lar_size);
|
||||
lseek(fd, offset + SARHDR, 0);
|
||||
if (read(fd, string_table, lar_size) != lar_size)
|
||||
printf("error reading string table\n");
|
||||
}
|
||||
else if (string_table && ar_hdr.ar_name[1] != ' ')
|
||||
{
|
||||
/* Long filenames are recognized by "/nnnn" where nnnn is
|
||||
** the offset of the string in the string table represented
|
||||
** in ASCII decimals.
|
||||
*/
|
||||
dest = lar_name;
|
||||
lar_offset = atoi(lar_name + 1);
|
||||
src = &string_table[lar_offset];
|
||||
while (*src != '/')
|
||||
*dest++ = *src++;
|
||||
*dest = '/';
|
||||
}
|
||||
}
|
||||
string_table = (char *)BJAM_MALLOC_ATOMIC(lar_size);
|
||||
lseek(fd, offset + SARHDR, 0);
|
||||
if (read(fd, string_table, lar_size) != lar_size)
|
||||
printf("error reading string table\n");
|
||||
}
|
||||
else if (string_table && ar_hdr.ar_name[1] != ' ')
|
||||
{
|
||||
/* Long filenames are recognized by "/nnnn" where nnnn is
|
||||
** the offset of the string in the string table represented
|
||||
** in ASCII decimals.
|
||||
*/
|
||||
dest = lar_name;
|
||||
lar_offset = atoi(lar_name + 1);
|
||||
src = &string_table[lar_offset];
|
||||
while (*src != '/')
|
||||
*dest++ = *src++;
|
||||
*dest = '/';
|
||||
}
|
||||
}
|
||||
|
||||
c = lar_name - 1;
|
||||
while( *++c != ' ' && *c != '/' )
|
||||
;
|
||||
*c = '\0';
|
||||
c = lar_name - 1;
|
||||
while( *++c != ' ' && *c != '/' )
|
||||
;
|
||||
*c = '\0';
|
||||
|
||||
if ( DEBUG_BINDSCAN )
|
||||
printf( "archive name %s found\n", lar_name );
|
||||
if ( DEBUG_BINDSCAN )
|
||||
printf( "archive name %s found\n", lar_name );
|
||||
|
||||
sprintf( buf, "%s(%s)", archive, lar_name );
|
||||
sprintf( buf, "%s(%s)", archive, lar_name );
|
||||
|
||||
(*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
|
||||
(*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
|
||||
|
||||
offset += SARHDR + ( ( lar_size + 1 ) & ~1 );
|
||||
lseek( fd, offset, 0 );
|
||||
}
|
||||
offset += SARHDR + ( ( lar_size + 1 ) & ~1 );
|
||||
lseek( fd, offset, 0 );
|
||||
}
|
||||
|
||||
if (string_table)
|
||||
BJAM_FREE(string_table);
|
||||
if (string_table)
|
||||
BJAM_FREE(string_table);
|
||||
|
||||
close( fd );
|
||||
close( fd );
|
||||
|
||||
# endif /* NO_AR */
|
||||
|
||||
@@ -389,24 +389,24 @@ static void file_archscan_small(
|
||||
return;
|
||||
|
||||
sscanf( fl_hdr.fl_fstmoff, "%ld", &offset );
|
||||
|
||||
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "scan archive %s\n", archive );
|
||||
|
||||
|
||||
while( offset > 0
|
||||
&& lseek( fd, offset, 0 ) >= 0
|
||||
&& read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) )
|
||||
{
|
||||
long lar_date;
|
||||
int lar_namlen;
|
||||
|
||||
|
||||
sscanf( ar_hdr.hdr.ar_namlen, "%d", &lar_namlen );
|
||||
sscanf( ar_hdr.hdr.ar_date, "%ld", &lar_date );
|
||||
sscanf( ar_hdr.hdr.ar_nxtmem, "%ld", &offset );
|
||||
|
||||
|
||||
if( !lar_namlen )
|
||||
continue;
|
||||
|
||||
|
||||
ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0';
|
||||
|
||||
sprintf( buf, "%s(%s)", archive, ar_hdr.hdr._ar_name.ar_name );
|
||||
@@ -471,7 +471,7 @@ void file_archscan(char *archive, scanback func, void *closure)
|
||||
|
||||
if(( fd = open(archive, O_RDONLY, 0)) < 0)
|
||||
return;
|
||||
|
||||
|
||||
if(read( fd, fl_magic, SAIAMAG) != SAIAMAG
|
||||
|| lseek(fd, 0, SEEK_SET) == -1)
|
||||
{
|
||||
@@ -491,7 +491,7 @@ void file_archscan(char *archive, scanback func, void *closure)
|
||||
file_archscan_big(fd, archive, func, closure);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
close( fd );
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
* file_dirscan() - scan a directory for files
|
||||
* file_time() - get timestamp of file, if not done by file_dirscan()
|
||||
* file_archscan() - scan an archive for files
|
||||
*
|
||||
* File_dirscan() and file_archscan() call back a caller provided function
|
||||
* for each file found. A flag to this callback function lets file_dirscan()
|
||||
@@ -53,45 +53,45 @@
|
||||
/* Supply missing prototypes for lbr$-routines*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int lbr$set_module(
|
||||
void **,
|
||||
unsigned long *,
|
||||
struct dsc$descriptor_s *,
|
||||
unsigned short *,
|
||||
void * );
|
||||
int lbr$set_module(
|
||||
void **,
|
||||
unsigned long *,
|
||||
struct dsc$descriptor_s *,
|
||||
unsigned short *,
|
||||
void * );
|
||||
|
||||
int lbr$open( void **,
|
||||
struct dsc$descriptor_s *,
|
||||
void *,
|
||||
void *,
|
||||
void *,
|
||||
void *,
|
||||
void * );
|
||||
struct dsc$descriptor_s *,
|
||||
void *,
|
||||
void *,
|
||||
void *,
|
||||
void *,
|
||||
void * );
|
||||
|
||||
int lbr$ini_control(
|
||||
void **,
|
||||
unsigned long *,
|
||||
unsigned long *,
|
||||
void * );
|
||||
void **,
|
||||
unsigned long *,
|
||||
unsigned long *,
|
||||
void * );
|
||||
|
||||
int lbr$get_index(
|
||||
void **,
|
||||
unsigned long *,
|
||||
int (*func)( struct dsc$descriptor_s *, unsigned long *),
|
||||
void * );
|
||||
void **,
|
||||
unsigned long *,
|
||||
int (*func)( struct dsc$descriptor_s *, unsigned long *),
|
||||
void * );
|
||||
|
||||
int lbr$close(
|
||||
void ** );
|
||||
void ** );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
static void
|
||||
file_cvttime(
|
||||
file_cvttime(
|
||||
unsigned int *curtime,
|
||||
time_t *unixtime )
|
||||
{
|
||||
@@ -108,10 +108,10 @@ file_cvttime(
|
||||
# define min( a,b ) ((a)<(b)?(a):(b))
|
||||
|
||||
void
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
file_dirscan(
|
||||
char *dir,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
|
||||
struct FAB xfab;
|
||||
@@ -129,8 +129,8 @@ file_dirscan(
|
||||
f.f_root.ptr = dir;
|
||||
f.f_root.len = strlen( dir );
|
||||
|
||||
/* get the input file specification
|
||||
*/
|
||||
/* get the input file specification
|
||||
*/
|
||||
xnam = cc$rms_nam;
|
||||
xnam.nam$l_esa = esa;
|
||||
xnam.nam$b_ess = sizeof( esa ) - 1;
|
||||
@@ -138,26 +138,26 @@ file_dirscan(
|
||||
xnam.nam$b_rss = min( sizeof( filename ) - 1, NAM$C_MAXRSS );
|
||||
|
||||
xab = cc$rms_xabdat; /* initialize extended attributes */
|
||||
xab.xab$b_cod = XAB$C_DAT; /* ask for date */
|
||||
xab.xab$b_cod = XAB$C_DAT; /* ask for date */
|
||||
xab.xab$l_nxt = NULL; /* terminate XAB chain */
|
||||
|
||||
xfab = cc$rms_fab;
|
||||
xfab.fab$l_dna = DEFAULT_FILE_SPECIFICATION;
|
||||
xfab.fab$b_dns = sizeof( DEFAULT_FILE_SPECIFICATION ) - 1;
|
||||
xfab.fab$l_fop = FAB$M_NAM;
|
||||
xfab.fab$l_fna = dir; /* address of file name */
|
||||
xfab.fab$b_fns = strlen( dir ); /* length of file name */
|
||||
xfab.fab$l_nam = &xnam; /* address of NAB block */
|
||||
xfab.fab$l_fna = dir; /* address of file name */
|
||||
xfab.fab$b_fns = strlen( dir ); /* length of file name */
|
||||
xfab.fab$l_nam = &xnam; /* address of NAB block */
|
||||
xfab.fab$l_xab = (char *)&xab; /* address of XAB block */
|
||||
|
||||
|
||||
status = sys$parse( &xfab );
|
||||
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "scan directory %s\n", dir );
|
||||
printf( "scan directory %s\n", dir );
|
||||
|
||||
if ( !( status & 1 ) )
|
||||
return;
|
||||
return;
|
||||
|
||||
|
||||
|
||||
@@ -165,84 +165,84 @@ file_dirscan(
|
||||
|
||||
if( !strcmp( dir, "[000000]" ) )
|
||||
{
|
||||
(*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ );
|
||||
(*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ );
|
||||
}
|
||||
|
||||
/* Add bogus directory for [] */
|
||||
|
||||
if( !strcmp( dir, "[]" ) )
|
||||
{
|
||||
(*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ );
|
||||
(*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ );
|
||||
(*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ );
|
||||
(*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ );
|
||||
}
|
||||
|
||||
string_new( filename2 );
|
||||
while ( (status = sys$search( &xfab )) & 1 )
|
||||
{
|
||||
char *s;
|
||||
time_t time;
|
||||
char *s;
|
||||
time_t time;
|
||||
|
||||
/* "I think that might work" - eml */
|
||||
/* "I think that might work" - eml */
|
||||
|
||||
sys$open( &xfab );
|
||||
sys$close( &xfab );
|
||||
sys$open( &xfab );
|
||||
sys$close( &xfab );
|
||||
|
||||
file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time );
|
||||
file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time );
|
||||
|
||||
filename[xnam.nam$b_rsl] = '\0';
|
||||
filename[xnam.nam$b_rsl] = '\0';
|
||||
|
||||
/* What we do with the name depends on the suffix: */
|
||||
/* .dir is a directory */
|
||||
/* .xxx is a file with a suffix */
|
||||
/* . is no suffix at all */
|
||||
/* What we do with the name depends on the suffix: */
|
||||
/* .dir is a directory */
|
||||
/* .xxx is a file with a suffix */
|
||||
/* . is no suffix at all */
|
||||
|
||||
if( xnam.nam$b_type == 4 && !strncmp( xnam.nam$l_type, ".DIR", 4 ) )
|
||||
{
|
||||
/* directory */
|
||||
sprintf( dirname, "[.%.*s]", xnam.nam$b_name, xnam.nam$l_name );
|
||||
f.f_dir.ptr = dirname;
|
||||
f.f_dir.len = strlen( dirname );
|
||||
f.f_base.ptr = 0;
|
||||
f.f_base.len = 0;
|
||||
f.f_suffix.ptr = 0;
|
||||
f.f_suffix.len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* normal file with a suffix */
|
||||
f.f_dir.ptr = 0;
|
||||
f.f_dir.len = 0;
|
||||
f.f_base.ptr = xnam.nam$l_name;
|
||||
f.f_base.len = xnam.nam$b_name;
|
||||
f.f_suffix.ptr = xnam.nam$l_type;
|
||||
f.f_suffix.len = xnam.nam$b_type;
|
||||
}
|
||||
if( xnam.nam$b_type == 4 && !strncmp( xnam.nam$l_type, ".DIR", 4 ) )
|
||||
{
|
||||
/* directory */
|
||||
sprintf( dirname, "[.%.*s]", xnam.nam$b_name, xnam.nam$l_name );
|
||||
f.f_dir.ptr = dirname;
|
||||
f.f_dir.len = strlen( dirname );
|
||||
f.f_base.ptr = 0;
|
||||
f.f_base.len = 0;
|
||||
f.f_suffix.ptr = 0;
|
||||
f.f_suffix.len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* normal file with a suffix */
|
||||
f.f_dir.ptr = 0;
|
||||
f.f_dir.len = 0;
|
||||
f.f_base.ptr = xnam.nam$l_name;
|
||||
f.f_base.len = xnam.nam$b_name;
|
||||
f.f_suffix.ptr = xnam.nam$l_type;
|
||||
f.f_suffix.len = xnam.nam$b_type;
|
||||
}
|
||||
|
||||
string_truncate( filename2, 0 );
|
||||
path_build( &f, filename2, 0 );
|
||||
path_build( &f, filename2, 0 );
|
||||
|
||||
/*
|
||||
if( DEBUG_SEARCH )
|
||||
printf("root '%s' base %.*s suf %.*s = %s\n",
|
||||
dir,
|
||||
xnam.nam$b_name, xnam.nam$l_name,
|
||||
xnam.nam$b_type, xnam.nam$l_type,
|
||||
filename2);
|
||||
*/
|
||||
/*
|
||||
if( DEBUG_SEARCH )
|
||||
printf("root '%s' base %.*s suf %.*s = %s\n",
|
||||
dir,
|
||||
xnam.nam$b_name, xnam.nam$l_name,
|
||||
xnam.nam$b_type, xnam.nam$l_type,
|
||||
filename2);
|
||||
*/
|
||||
|
||||
(*func)( closure, filename2->value, 1 /* time valid */, time );
|
||||
(*func)( closure, filename2->value, 1 /* time valid */, time );
|
||||
}
|
||||
string_free( filename2 );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
file_time(
|
||||
char *filename,
|
||||
time_t *time )
|
||||
char *filename,
|
||||
time_t *time )
|
||||
{
|
||||
/* This should never be called, as all files are */
|
||||
/* timestampped in file_dirscan() and file_archscan() */
|
||||
return -1;
|
||||
/* This should never be called, as all files are */
|
||||
/* timestampped in file_dirscan() and file_archscan() */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *VMS_archive = 0;
|
||||
@@ -251,12 +251,12 @@ static void *VMS_closure;
|
||||
static void *context;
|
||||
|
||||
static int
|
||||
file_archmember(
|
||||
file_archmember(
|
||||
struct dsc$descriptor_s *module,
|
||||
unsigned long *rfa )
|
||||
{
|
||||
static struct dsc$descriptor_s bufdsc =
|
||||
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
|
||||
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
|
||||
|
||||
struct mhddef *mhd;
|
||||
char filename[128];
|
||||
@@ -271,17 +271,17 @@ file_archmember(
|
||||
bufdsc.dsc$a_pointer = filename;
|
||||
bufdsc.dsc$w_length = sizeof( filename );
|
||||
status = lbr$set_module( &context, rfa, &bufdsc,
|
||||
&bufdsc.dsc$w_length, NULL );
|
||||
&bufdsc.dsc$w_length, NULL );
|
||||
|
||||
if ( !(status & 1) )
|
||||
return ( 1 );
|
||||
return ( 1 );
|
||||
|
||||
mhd = (struct mhddef *)filename;
|
||||
|
||||
file_cvttime( &mhd->mhd$l_datim, &library_date );
|
||||
|
||||
for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; i++, p++ )
|
||||
filename[i] = *p;
|
||||
filename[i] = *p;
|
||||
|
||||
filename[i] = '\0';
|
||||
|
||||
@@ -294,12 +294,12 @@ file_archmember(
|
||||
|
||||
void
|
||||
file_archscan(
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
char *archive,
|
||||
scanback func,
|
||||
void *closure )
|
||||
{
|
||||
static struct dsc$descriptor_s library =
|
||||
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
|
||||
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
|
||||
|
||||
unsigned long lfunc = LBR$C_READ;
|
||||
unsigned long typ = LBR$C_TYP_UNK;
|
||||
@@ -313,14 +313,14 @@ file_archscan(
|
||||
|
||||
status = lbr$ini_control( &context, &lfunc, &typ, NULL );
|
||||
if ( !( status & 1 ) )
|
||||
return;
|
||||
return;
|
||||
|
||||
library.dsc$a_pointer = archive;
|
||||
library.dsc$w_length = strlen( archive );
|
||||
|
||||
status = lbr$open( &context, &library, NULL, NULL, NULL, NULL, NULL );
|
||||
if ( !( status & 1 ) )
|
||||
return;
|
||||
return;
|
||||
|
||||
(void) lbr$get_index( &context, &index, file_archmember, NULL );
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2001-2004 David Abrahams.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2001-2004 David Abrahams.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1994 Christopher Seiwald. All rights reserved.
|
||||
* Copyright 1994 Christopher Seiwald. All rights reserved.
|
||||
*
|
||||
* This file is part of Jam - see jam.c for Copyright information.
|
||||
*/
|
||||
@@ -9,25 +9,25 @@
|
||||
*
|
||||
* Understands the following patterns:
|
||||
*
|
||||
* * any number of characters
|
||||
* ? any single character
|
||||
* [a-z] any single character in the range a-z
|
||||
* [^a-z] any single character not in the range a-z
|
||||
* \x match x
|
||||
*
|
||||
* * any number of characters
|
||||
* ? any single character
|
||||
* [a-z] any single character in the range a-z
|
||||
* [^a-z] any single character not in the range a-z
|
||||
* \x match x
|
||||
*
|
||||
* External functions:
|
||||
*
|
||||
* glob() - match a string against a simple pattern
|
||||
* glob() - match a string against a simple pattern
|
||||
*
|
||||
* Internal functions:
|
||||
*
|
||||
* globchars() - build a bitlist to check for character group match
|
||||
* globchars() - build a bitlist to check for character group match
|
||||
*/
|
||||
|
||||
# include "jam.h"
|
||||
|
||||
# define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) )
|
||||
# define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */
|
||||
# define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */
|
||||
|
||||
static void globchars( char *s, char *e, char *b );
|
||||
|
||||
@@ -37,121 +37,117 @@ static void globchars( char *s, char *e, char *b );
|
||||
|
||||
int
|
||||
glob(
|
||||
register char *c,
|
||||
register char *s )
|
||||
register char *c,
|
||||
register char *s )
|
||||
{
|
||||
char bitlist[ BITLISTSIZE ];
|
||||
char *here;
|
||||
char bitlist[ BITLISTSIZE ];
|
||||
char *here;
|
||||
|
||||
for( ;; )
|
||||
switch( *c++ )
|
||||
{
|
||||
case '\0':
|
||||
return *s ? -1 : 0;
|
||||
for( ;; )
|
||||
switch( *c++ )
|
||||
{
|
||||
case '\0':
|
||||
return *s ? -1 : 0;
|
||||
|
||||
case '?':
|
||||
if( !*s++ )
|
||||
return 1;
|
||||
break;
|
||||
case '?':
|
||||
if( !*s++ )
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
/* scan for matching ] */
|
||||
case '[':
|
||||
/* scan for matching ] */
|
||||
|
||||
here = c;
|
||||
do if( !*c++ )
|
||||
return 1;
|
||||
while( here == c || *c != ']' );
|
||||
c++;
|
||||
here = c;
|
||||
do if( !*c++ )
|
||||
return 1;
|
||||
while( here == c || *c != ']' );
|
||||
c++;
|
||||
|
||||
/* build character class bitlist */
|
||||
/* build character class bitlist */
|
||||
|
||||
globchars( here, c, bitlist );
|
||||
globchars( here, c, bitlist );
|
||||
|
||||
if( !CHECK_BIT( bitlist, *(unsigned char *)s ) )
|
||||
return 1;
|
||||
s++;
|
||||
break;
|
||||
if( !CHECK_BIT( bitlist, *(unsigned char *)s ) )
|
||||
return 1;
|
||||
s++;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
here = s;
|
||||
case '*':
|
||||
here = s;
|
||||
|
||||
while( *s )
|
||||
s++;
|
||||
while ( *s )
|
||||
s++;
|
||||
|
||||
/* Try to match the rest of the pattern in a recursive */
|
||||
/* call. If the match fails we'll back up chars, retrying. */
|
||||
/* Try to match the rest of the pattern in a recursive */
|
||||
/* call. If the match fails we'll back up chars, retrying. */
|
||||
|
||||
while( s != here )
|
||||
{
|
||||
int r;
|
||||
while( s != here )
|
||||
{
|
||||
int r;
|
||||
|
||||
/* A fast path for the last token in a pattern */
|
||||
/* A fast path for the last token in a pattern */
|
||||
|
||||
r = *c ? glob( c, s ) : *s ? -1 : 0;
|
||||
r = *c ? glob( c, s ) : *s ? -1 : 0;
|
||||
|
||||
if( !r )
|
||||
return 0;
|
||||
else if( r < 0 )
|
||||
return 1;
|
||||
if( !r )
|
||||
return 0;
|
||||
else if( r < 0 )
|
||||
return 1;
|
||||
|
||||
--s;
|
||||
}
|
||||
break;
|
||||
--s;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
/* Force literal match of next char. */
|
||||
case '\\':
|
||||
/* Force literal match of next char. */
|
||||
|
||||
if( !*c || *s++ != *c++ )
|
||||
return 1;
|
||||
break;
|
||||
if( !*c || *s++ != *c++ )
|
||||
return 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if( *s++ != c[-1] )
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if( *s++ != c[-1] )
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* globchars() - build a bitlist to check for character group match
|
||||
*/
|
||||
|
||||
static void
|
||||
globchars(
|
||||
char *s,
|
||||
char *e,
|
||||
char *b )
|
||||
static void globchars( char * s, char * e, char * b )
|
||||
{
|
||||
int neg = 0;
|
||||
int neg = 0;
|
||||
|
||||
memset( b, '\0', BITLISTSIZE );
|
||||
memset( b, '\0', BITLISTSIZE );
|
||||
|
||||
if( *s == '^')
|
||||
neg++, s++;
|
||||
if( *s == '^')
|
||||
neg++, s++;
|
||||
|
||||
while( s < e )
|
||||
{
|
||||
int c;
|
||||
while( s < e )
|
||||
{
|
||||
int c;
|
||||
|
||||
if( s+2 < e && s[1] == '-' )
|
||||
{
|
||||
for( c = s[0]; c <= s[2]; c++ )
|
||||
b[ c/8 ] |= (1<<(c%8));
|
||||
s += 3;
|
||||
} else {
|
||||
c = *s++;
|
||||
b[ c/8 ] |= (1<<(c%8));
|
||||
}
|
||||
}
|
||||
|
||||
if( neg )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < BITLISTSIZE; i++ )
|
||||
b[ i ] ^= 0377;
|
||||
}
|
||||
if( s+2 < e && s[1] == '-' )
|
||||
{
|
||||
for( c = s[0]; c <= s[2]; c++ )
|
||||
b[ c/8 ] |= (1<<(c%8));
|
||||
s += 3;
|
||||
} else {
|
||||
c = *s++;
|
||||
b[ c/8 ] |= (1<<(c%8));
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't include \0 in either $[chars] or $[^chars] */
|
||||
if ( neg )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < BITLISTSIZE; ++i )
|
||||
b[ i ] ^= 0377;
|
||||
}
|
||||
|
||||
b[0] &= 0376;
|
||||
/* Don't include \0 in either $[chars] or $[^chars] */
|
||||
|
||||
b[0] &= 0376;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
# include "compile.h"
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* hash.c - simple in-memory hashing routines
|
||||
/*
|
||||
* hash.c - simple in-memory hashing routines
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
@@ -29,63 +29,63 @@
|
||||
#define HASH_DEBUG_PROFILE 1
|
||||
/* */
|
||||
|
||||
char *hashsccssid="@(#)hash.c 1.14 () 6/20/88";
|
||||
char *hashsccssid="@(#)hash.c 1.14 () 6/20/88";
|
||||
|
||||
/* Header attached to all data items entered into a hash table. */
|
||||
|
||||
struct hashhdr {
|
||||
struct item *next;
|
||||
unsigned int keyval; /* for quick comparisons */
|
||||
struct item *next;
|
||||
unsigned int keyval; /* for quick comparisons */
|
||||
} ;
|
||||
|
||||
/* This structure overlays the one handed to hashenter(). */
|
||||
/* It's actual size is given to hashinit(). */
|
||||
|
||||
struct hashdata {
|
||||
char *key;
|
||||
/* rest of user data */
|
||||
char *key;
|
||||
/* rest of user data */
|
||||
} ;
|
||||
|
||||
typedef struct item {
|
||||
struct hashhdr hdr;
|
||||
struct hashdata data;
|
||||
struct hashhdr hdr;
|
||||
struct hashdata data;
|
||||
} ITEM ;
|
||||
|
||||
# define MAX_LISTS 32
|
||||
|
||||
struct hash
|
||||
struct hash
|
||||
{
|
||||
/*
|
||||
* the hash table, just an array of item pointers
|
||||
*/
|
||||
struct {
|
||||
int nel;
|
||||
ITEM **base;
|
||||
} tab;
|
||||
/*
|
||||
* the hash table, just an array of item pointers
|
||||
*/
|
||||
struct {
|
||||
int nel;
|
||||
ITEM **base;
|
||||
} tab;
|
||||
|
||||
int bloat; /* tab.nel / items.nel */
|
||||
int inel; /* initial number of elements */
|
||||
int bloat; /* tab.nel / items.nel */
|
||||
int inel; /* initial number of elements */
|
||||
|
||||
/*
|
||||
* the array of records, maintained by these routines
|
||||
* essentially a microallocator
|
||||
*/
|
||||
struct {
|
||||
int more; /* how many more ITEMs fit in lists[ list ] */
|
||||
/*
|
||||
* the array of records, maintained by these routines
|
||||
* essentially a microallocator
|
||||
*/
|
||||
struct {
|
||||
int more; /* how many more ITEMs fit in lists[ list ] */
|
||||
ITEM *free; /* free list of items */
|
||||
char *next; /* where to put more ITEMs in lists[ list ] */
|
||||
int datalen; /* length of records in this hash table */
|
||||
int size; /* sizeof( ITEM ) + aligned datalen */
|
||||
int nel; /* total ITEMs held by all lists[] */
|
||||
int list; /* index into lists[] */
|
||||
char *next; /* where to put more ITEMs in lists[ list ] */
|
||||
int datalen; /* length of records in this hash table */
|
||||
int size; /* sizeof( ITEM ) + aligned datalen */
|
||||
int nel; /* total ITEMs held by all lists[] */
|
||||
int list; /* index into lists[] */
|
||||
|
||||
struct {
|
||||
int nel; /* total ITEMs held by this list */
|
||||
char *base; /* base of ITEMs array */
|
||||
} lists[ MAX_LISTS ];
|
||||
} items;
|
||||
struct {
|
||||
int nel; /* total ITEMs held by this list */
|
||||
char *base; /* base of ITEMs array */
|
||||
} lists[ MAX_LISTS ];
|
||||
} items;
|
||||
|
||||
char *name; /* just for hashstats() */
|
||||
char *name; /* just for hashstats() */
|
||||
} ;
|
||||
|
||||
static void hashrehash( struct hash *hp );
|
||||
@@ -134,7 +134,7 @@ static ITEM * hash_search(
|
||||
}
|
||||
p = i;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ hash_free(
|
||||
ITEM * i = 0;
|
||||
ITEM * prev = 0;
|
||||
unsigned int keyval = hash_keyval(data->key);
|
||||
|
||||
|
||||
i = hash_search( hp, keyval, data->key, &prev );
|
||||
if (i)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ hash_free(
|
||||
hp->items.free = i;
|
||||
/* we have another item */
|
||||
hp->items.more++;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -178,32 +178,32 @@ hash_free(
|
||||
|
||||
int
|
||||
hashitem(
|
||||
register struct hash *hp,
|
||||
HASHDATA **data,
|
||||
int enter )
|
||||
register struct hash *hp,
|
||||
HASHDATA **data,
|
||||
int enter )
|
||||
{
|
||||
register ITEM *i;
|
||||
char *b = (*data)->key;
|
||||
unsigned int keyval = hash_keyval(b);
|
||||
|
||||
register ITEM *i;
|
||||
char *b = (*data)->key;
|
||||
unsigned int keyval = hash_keyval(b);
|
||||
|
||||
#ifdef HASH_DEBUG_PROFILE
|
||||
profile_frame prof[1];
|
||||
if ( DEBUG_PROFILE )
|
||||
profile_enter( 0, prof );
|
||||
#endif
|
||||
|
||||
if( enter && !hp->items.more )
|
||||
hashrehash( hp );
|
||||
if( enter && !hp->items.more )
|
||||
hashrehash( hp );
|
||||
|
||||
if( !enter && !hp->items.nel )
|
||||
if( !enter && !hp->items.nel )
|
||||
{
|
||||
#ifdef HASH_DEBUG_PROFILE
|
||||
if ( DEBUG_PROFILE )
|
||||
profile_exit( prof );
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
i = hash_search( hp, keyval, (*data)->key, 0 );
|
||||
if (i)
|
||||
{
|
||||
@@ -214,10 +214,10 @@ hashitem(
|
||||
return !0;
|
||||
}
|
||||
|
||||
if( enter )
|
||||
if ( enter )
|
||||
{
|
||||
ITEM **base = hash_bucket(hp,keyval);
|
||||
|
||||
ITEM * * base = hash_bucket(hp,keyval);
|
||||
|
||||
/* try to grab one from the free list */
|
||||
if ( hp->items.free )
|
||||
{
|
||||
@@ -248,7 +248,7 @@ hashitem(
|
||||
if ( DEBUG_PROFILE )
|
||||
profile_exit( prof );
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -257,39 +257,39 @@ hashitem(
|
||||
|
||||
static void hashrehash( register struct hash *hp )
|
||||
{
|
||||
int i = ++hp->items.list;
|
||||
hp->items.more = i ? 2 * hp->items.nel : hp->inel;
|
||||
hp->items.next = (char *)hash_mem_alloc( hp->items.datalen, hp->items.more * hp->items.size );
|
||||
int i = ++hp->items.list;
|
||||
hp->items.more = i ? 2 * hp->items.nel : hp->inel;
|
||||
hp->items.next = (char *)hash_mem_alloc( hp->items.datalen, hp->items.more * hp->items.size );
|
||||
hp->items.free = 0;
|
||||
|
||||
hp->items.lists[i].nel = hp->items.more;
|
||||
hp->items.lists[i].base = hp->items.next;
|
||||
hp->items.nel += hp->items.more;
|
||||
|
||||
if( hp->tab.base )
|
||||
hash_mem_free( hp->items.datalen, (char *)hp->tab.base );
|
||||
hp->items.lists[i].nel = hp->items.more;
|
||||
hp->items.lists[i].base = hp->items.next;
|
||||
hp->items.nel += hp->items.more;
|
||||
|
||||
hp->tab.nel = hp->items.nel * hp->bloat;
|
||||
hp->tab.base = (ITEM **)hash_mem_alloc( hp->items.datalen, hp->tab.nel * sizeof(ITEM **) );
|
||||
if( hp->tab.base )
|
||||
hash_mem_free( hp->items.datalen, (char *)hp->tab.base );
|
||||
|
||||
memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) );
|
||||
hp->tab.nel = hp->items.nel * hp->bloat;
|
||||
hp->tab.base = (ITEM **)hash_mem_alloc( hp->items.datalen, hp->tab.nel * sizeof(ITEM **) );
|
||||
|
||||
for( i = 0; i < hp->items.list; i++ )
|
||||
{
|
||||
int nel = hp->items.lists[i].nel;
|
||||
char *next = hp->items.lists[i].base;
|
||||
memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) );
|
||||
|
||||
for( ; nel--; next += hp->items.size )
|
||||
{
|
||||
register ITEM *i = (ITEM *)next;
|
||||
ITEM **ip = hp->tab.base + i->hdr.keyval % hp->tab.nel;
|
||||
for( i = 0; i < hp->items.list; i++ )
|
||||
{
|
||||
int nel = hp->items.lists[i].nel;
|
||||
char *next = hp->items.lists[i].base;
|
||||
|
||||
for( ; nel--; next += hp->items.size )
|
||||
{
|
||||
register ITEM *i = (ITEM *)next;
|
||||
ITEM **ip = hp->tab.base + i->hdr.keyval % hp->tab.nel;
|
||||
/* code currently assumes rehashing only when there are no free items */
|
||||
assert( i->data.key != 0 );
|
||||
|
||||
i->hdr.next = *ip;
|
||||
*ip = i;
|
||||
}
|
||||
}
|
||||
assert( i->data.key != 0 );
|
||||
|
||||
i->hdr.next = *ip;
|
||||
*ip = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data )
|
||||
@@ -304,10 +304,9 @@ void hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data )
|
||||
|
||||
for( ; nel--; next += hp->items.size )
|
||||
{
|
||||
register ITEM *i = (ITEM *)next;
|
||||
|
||||
register ITEM * i = (ITEM *)next;
|
||||
if ( i->data.key != 0 ) /* don't enumerate freed items */
|
||||
f(&i->data, data);
|
||||
f( &i->data, data );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,25 +320,25 @@ void hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data )
|
||||
*/
|
||||
|
||||
struct hash *
|
||||
hashinit(
|
||||
int datalen,
|
||||
char *name )
|
||||
hashinit(
|
||||
int datalen,
|
||||
char *name )
|
||||
{
|
||||
struct hash *hp = (struct hash *)hash_mem_alloc( datalen, sizeof( *hp ) );
|
||||
struct hash *hp = (struct hash *)hash_mem_alloc( datalen, sizeof( *hp ) );
|
||||
|
||||
hp->bloat = 3;
|
||||
hp->tab.nel = 0;
|
||||
hp->tab.base = (ITEM **)0;
|
||||
hp->items.more = 0;
|
||||
hp->bloat = 3;
|
||||
hp->tab.nel = 0;
|
||||
hp->tab.base = (ITEM **)0;
|
||||
hp->items.more = 0;
|
||||
hp->items.free = 0;
|
||||
hp->items.datalen = datalen;
|
||||
hp->items.size = sizeof( struct hashhdr ) + ALIGNED( datalen );
|
||||
hp->items.list = -1;
|
||||
hp->items.nel = 0;
|
||||
hp->inel = /* */ 11 /*/ 47 /* */;
|
||||
hp->name = name;
|
||||
hp->items.datalen = datalen;
|
||||
hp->items.size = sizeof( struct hashhdr ) + ALIGNED( datalen );
|
||||
hp->items.list = -1;
|
||||
hp->items.nel = 0;
|
||||
hp->inel = /* */ 11 /*/ 47 /* */;
|
||||
hp->name = name;
|
||||
|
||||
return hp;
|
||||
return hp;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -349,19 +348,19 @@ hashinit(
|
||||
void
|
||||
hashdone( struct hash *hp )
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if( !hp )
|
||||
return;
|
||||
if( !hp )
|
||||
return;
|
||||
|
||||
if( DEBUG_MEM || DEBUG_PROFILE )
|
||||
hashstat( hp );
|
||||
if( DEBUG_MEM || DEBUG_PROFILE )
|
||||
hashstat( hp );
|
||||
|
||||
if( hp->tab.base )
|
||||
hash_mem_free( hp->items.datalen, (char *)hp->tab.base );
|
||||
for( i = 0; i <= hp->items.list; i++ )
|
||||
hash_mem_free( hp->items.datalen, hp->items.lists[i].base );
|
||||
hash_mem_free( hp->items.datalen, (char *)hp );
|
||||
if( hp->tab.base )
|
||||
hash_mem_free( hp->items.datalen, (char *)hp->tab.base );
|
||||
for( i = 0; i <= hp->items.list; i++ )
|
||||
hash_mem_free( hp->items.datalen, hp->items.lists[i].base );
|
||||
hash_mem_free( hp->items.datalen, (char *)hp );
|
||||
}
|
||||
|
||||
static void * hash_mem_alloc(size_t datalen, size_t size)
|
||||
@@ -403,28 +402,28 @@ static void hash_mem_finalizer(char * key, struct hash * hp)
|
||||
static void
|
||||
hashstat( struct hash *hp )
|
||||
{
|
||||
ITEM **tab = hp->tab.base;
|
||||
int nel = hp->tab.nel;
|
||||
int count = 0;
|
||||
int sets = 0;
|
||||
int run = ( tab[ nel - 1 ] != (ITEM *)0 );
|
||||
int i, here;
|
||||
ITEM **tab = hp->tab.base;
|
||||
int nel = hp->tab.nel;
|
||||
int count = 0;
|
||||
int sets = 0;
|
||||
int run = ( tab[ nel - 1 ] != (ITEM *)0 );
|
||||
int i, here;
|
||||
|
||||
for( i = nel; i > 0; i-- )
|
||||
{
|
||||
if( here = ( *tab++ != (ITEM *)0 ) )
|
||||
count++;
|
||||
if( here && !run )
|
||||
sets++;
|
||||
run = here;
|
||||
}
|
||||
for( i = nel; i > 0; i-- )
|
||||
{
|
||||
if( here = ( *tab++ != (ITEM *)0 ) )
|
||||
count++;
|
||||
if( here && !run )
|
||||
sets++;
|
||||
run = here;
|
||||
}
|
||||
|
||||
printf( "%s table: %d+%d+%d (%dK+%dK) items+table+hash, %f density\n",
|
||||
hp->name,
|
||||
count,
|
||||
hp->items.nel,
|
||||
hp->tab.nel,
|
||||
hp->items.nel * hp->items.size / 1024,
|
||||
hp->tab.nel * sizeof( ITEM ** ) / 1024,
|
||||
(float)count / (float)sets );
|
||||
printf( "%s table: %d+%d+%d (%dK+%dK) items+table+hash, %f density\n",
|
||||
hp->name,
|
||||
count,
|
||||
hp->items.nel,
|
||||
hp->tab.nel,
|
||||
hp->items.nel * hp->items.size / 1024,
|
||||
hp->tab.nel * sizeof( ITEM ** ) / 1024,
|
||||
(float)count / (float)sets );
|
||||
}
|
||||
|
||||
@@ -5,21 +5,21 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* hash.h - simple in-memory hashing routines
|
||||
* hash.h - simple in-memory hashing routines
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BOOST_JAM_HASH_H
|
||||
#define BOOST_JAM_HASH_H
|
||||
|
||||
typedef struct hashdata HASHDATA;
|
||||
|
||||
struct hash * hashinit( int datalen, char *name );
|
||||
int hashitem( struct hash *hp, HASHDATA **data, int enter );
|
||||
void hashdone( struct hash *hp );
|
||||
struct hash * hashinit( int datalen, char *name );
|
||||
int hashitem( struct hash *hp, HASHDATA **data, int enter );
|
||||
void hashdone( struct hash *hp );
|
||||
void hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data );
|
||||
int hash_free( struct hash *hp, HASHDATA *data);
|
||||
|
||||
# define hashenter( hp, data ) (!hashitem( hp, data, !0 ))
|
||||
# define hashcheck( hp, data ) hashitem( hp, data, 0 )
|
||||
# define hashenter( hp, data ) (!hashitem( hp, data, !0 ))
|
||||
# define hashcheck( hp, data ) hashitem( hp, data, 0 )
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,26 +34,26 @@
|
||||
* hcache_init() - read and parse the local .jamdeps file.
|
||||
* hcache_done() - write a new .jamdeps file
|
||||
* hcache() - return list of headers on target. Use cache or do a scan.
|
||||
*
|
||||
*
|
||||
* The dependency file format is an ascii file with 1 line per target.
|
||||
* Each line has the following fields:
|
||||
* @boundname@ timestamp @file@ @file@ @file@ ... \n
|
||||
* */
|
||||
|
||||
struct hcachedata {
|
||||
char *boundname;
|
||||
time_t time;
|
||||
LIST *includes;
|
||||
LIST *hdrscan; /* the HDRSCAN value for this target */
|
||||
int age; /* if too old, we'll remove it from cache */
|
||||
struct hcachedata *next;
|
||||
char *boundname;
|
||||
time_t time;
|
||||
LIST *includes;
|
||||
LIST *hdrscan; /* the HDRSCAN value for this target */
|
||||
int age; /* if too old, we'll remove it from cache */
|
||||
struct hcachedata *next;
|
||||
} ;
|
||||
|
||||
typedef struct hcachedata HCACHEDATA ;
|
||||
|
||||
|
||||
static struct hash *hcachehash = 0;
|
||||
static HCACHEDATA *hcachelist = 0;
|
||||
static HCACHEDATA *hcachelist = 0;
|
||||
|
||||
static int queries = 0;
|
||||
static int hits = 0;
|
||||
@@ -74,23 +74,23 @@ cache_name(void)
|
||||
{
|
||||
static char* name = 0;
|
||||
if (!name) {
|
||||
LIST *hcachevar = var_get("HCACHEFILE");
|
||||
LIST *hcachevar = var_get("HCACHEFILE");
|
||||
|
||||
if (hcachevar) {
|
||||
TARGET *t = bindtarget( hcachevar->string );
|
||||
if (hcachevar) {
|
||||
TARGET *t = bindtarget( hcachevar->string );
|
||||
|
||||
pushsettings( t->settings );
|
||||
pushsettings( t->settings );
|
||||
/* Don't expect cache file to be generated, so pass 0
|
||||
as third argument to search.
|
||||
as third argument to search.
|
||||
Expect the location to be specified via LOCATE,
|
||||
so pass 0 as fourth arugment. */
|
||||
t->boundname = search( t->name, &t->time, 0, 0 );
|
||||
popsettings( t->settings );
|
||||
t->boundname = search( t->name, &t->time, 0, 0 );
|
||||
popsettings( t->settings );
|
||||
|
||||
if (hcachevar) {
|
||||
name = copystr(t->boundname);
|
||||
}
|
||||
}
|
||||
if (hcachevar) {
|
||||
name = copystr(t->boundname);
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@@ -106,9 +106,9 @@ cache_maxage(void)
|
||||
LIST *var = var_get("HCACHEMAXAGE");
|
||||
|
||||
if (var) {
|
||||
age = atoi(var->string);
|
||||
if (age < 0)
|
||||
age = 0;
|
||||
age = atoi(var->string);
|
||||
if (age < 0)
|
||||
age = 0;
|
||||
}
|
||||
|
||||
return age;
|
||||
@@ -127,35 +127,36 @@ read_netstring(FILE* f)
|
||||
static unsigned long buf_len = 0;
|
||||
|
||||
if (fscanf(f, " %9lu", &len) != 1)
|
||||
return NULL;
|
||||
return NULL;
|
||||
if (fgetc(f) != (int)'\t')
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
if (len > 1024 * 64)
|
||||
return NULL; /* sanity check */
|
||||
return NULL; /* sanity check */
|
||||
|
||||
if (len > buf_len)
|
||||
{
|
||||
unsigned long new_len = buf_len * 2;
|
||||
if (new_len < len)
|
||||
new_len = len;
|
||||
buf = (char*)BJAM_REALLOC(buf, new_len + 1);
|
||||
if (buf)
|
||||
buf_len = new_len;
|
||||
unsigned long new_len = buf_len * 2;
|
||||
if (new_len < len)
|
||||
new_len = len;
|
||||
buf = (char*)BJAM_REALLOC(buf, new_len + 1);
|
||||
if (buf)
|
||||
buf_len = new_len;
|
||||
}
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
if (fread(buf, 1, len, f) != len)
|
||||
return NULL;
|
||||
return NULL;
|
||||
if (fgetc(f) != (int)'\n')
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
buf[len] = 0;
|
||||
return newstr(buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a netstring.
|
||||
*/
|
||||
@@ -163,119 +164,121 @@ void
|
||||
write_netstring(FILE* f, const char* s)
|
||||
{
|
||||
if (!s)
|
||||
s = "";
|
||||
s = "";
|
||||
fprintf(f, "%lu\t%s\n", strlen(s), s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hcache_init()
|
||||
{
|
||||
HCACHEDATA cachedata, *c;
|
||||
FILE *f;
|
||||
char *version;
|
||||
int header_count = 0;
|
||||
char* hcachename;
|
||||
HCACHEDATA cachedata;
|
||||
HCACHEDATA * c;
|
||||
FILE * f;
|
||||
char * version;
|
||||
int header_count = 0;
|
||||
char * hcachename;
|
||||
|
||||
hcachehash = hashinit (sizeof (HCACHEDATA), "hcache");
|
||||
|
||||
if (! (hcachename = cache_name()))
|
||||
return;
|
||||
return;
|
||||
|
||||
if (! (f = fopen (hcachename, "rb" )))
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
version = read_netstring(f);
|
||||
if (!version || strcmp(version, CACHE_FILE_VERSION)) {
|
||||
fclose(f);
|
||||
return;
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
char* record_type;
|
||||
char *time_str;
|
||||
char *age_str;
|
||||
char *includes_count_str;
|
||||
char *hdrscan_count_str;
|
||||
int i, count;
|
||||
LIST *l;
|
||||
char* record_type;
|
||||
char *time_str;
|
||||
char *age_str;
|
||||
char *includes_count_str;
|
||||
char *hdrscan_count_str;
|
||||
int i, count;
|
||||
LIST *l;
|
||||
|
||||
record_type = read_netstring(f);
|
||||
if (!record_type) {
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
if (!strcmp(record_type, CACHE_RECORD_END)) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(record_type, CACHE_RECORD_HEADER)) {
|
||||
fprintf(stderr, "invalid %s with record separator <%s>\n",
|
||||
hcachename, record_type ? record_type : "<null>");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
c = &cachedata;
|
||||
|
||||
c->boundname = read_netstring(f);
|
||||
time_str = read_netstring(f);
|
||||
age_str = read_netstring(f);
|
||||
includes_count_str = read_netstring(f);
|
||||
|
||||
if (!c->boundname || !time_str || !age_str
|
||||
|| !includes_count_str)
|
||||
{
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
record_type = read_netstring(f);
|
||||
if (!record_type) {
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
if (!strcmp(record_type, CACHE_RECORD_END)) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(record_type, CACHE_RECORD_HEADER)) {
|
||||
fprintf(stderr, "invalid %s with record separator <%s>\n",
|
||||
hcachename, record_type ? record_type : "<null>");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
c->time = atoi(time_str);
|
||||
c->age = atoi(age_str) + 1;
|
||||
c = &cachedata;
|
||||
|
||||
count = atoi(includes_count_str);
|
||||
for (l = 0, i = 0; i < count; i++) {
|
||||
char* s = read_netstring(f);
|
||||
if (!s) {
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
l = list_new(l, s);
|
||||
}
|
||||
c->includes = l;
|
||||
c->boundname = read_netstring(f);
|
||||
time_str = read_netstring(f);
|
||||
age_str = read_netstring(f);
|
||||
includes_count_str = read_netstring(f);
|
||||
|
||||
hdrscan_count_str = read_netstring(f);
|
||||
if (!includes_count_str) {
|
||||
list_free(c->includes);
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
if (!c->boundname || !time_str || !age_str
|
||||
|| !includes_count_str)
|
||||
{
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
count = atoi(hdrscan_count_str);
|
||||
for (l = 0, i = 0; i < count; i++) {
|
||||
char* s = read_netstring(f);
|
||||
if (!s) {
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
l = list_new(l, s);
|
||||
}
|
||||
c->hdrscan = l;
|
||||
c->time = atoi(time_str);
|
||||
c->age = atoi(age_str) + 1;
|
||||
|
||||
if (!hashenter(hcachehash, (HASHDATA **)&c)) {
|
||||
fprintf(stderr, "can't insert header cache item, bailing on %s\n",
|
||||
hcachename);
|
||||
goto bail;
|
||||
}
|
||||
count = atoi(includes_count_str);
|
||||
for (l = 0, i = 0; i < count; i++) {
|
||||
char* s = read_netstring(f);
|
||||
if (!s) {
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
l = list_new(l, s);
|
||||
}
|
||||
c->includes = l;
|
||||
|
||||
c->next = hcachelist;
|
||||
hcachelist = c;
|
||||
hdrscan_count_str = read_netstring(f);
|
||||
if (!includes_count_str) {
|
||||
list_free(c->includes);
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
header_count++;
|
||||
count = atoi(hdrscan_count_str);
|
||||
for (l = 0, i = 0; i < count; i++) {
|
||||
char* s = read_netstring(f);
|
||||
if (!s) {
|
||||
fprintf(stderr, "invalid %s\n", hcachename);
|
||||
goto bail;
|
||||
}
|
||||
l = list_new(l, s);
|
||||
}
|
||||
c->hdrscan = l;
|
||||
|
||||
if (!hashenter(hcachehash, (HASHDATA **)&c)) {
|
||||
fprintf(stderr, "can't insert header cache item, bailing on %s\n",
|
||||
hcachename);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
c->next = hcachelist;
|
||||
hcachelist = c;
|
||||
|
||||
header_count++;
|
||||
}
|
||||
|
||||
if (DEBUG_HEADER) {
|
||||
printf("hcache read from file %s\n", hcachename);
|
||||
printf("hcache read from file %s\n", hcachename);
|
||||
}
|
||||
|
||||
|
||||
bail:
|
||||
fclose(f);
|
||||
}
|
||||
@@ -283,20 +286,20 @@ hcache_init()
|
||||
void
|
||||
hcache_done()
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f;
|
||||
HCACHEDATA *c;
|
||||
int header_count = 0;
|
||||
char* hcachename;
|
||||
int maxage;
|
||||
|
||||
int header_count = 0;
|
||||
char* hcachename;
|
||||
int maxage;
|
||||
|
||||
if (!hcachehash)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (! (hcachename = cache_name()))
|
||||
return;
|
||||
return;
|
||||
|
||||
if (! (f = fopen (hcachename, "wb" )))
|
||||
return;
|
||||
return;
|
||||
|
||||
maxage = cache_maxage();
|
||||
|
||||
@@ -305,43 +308,43 @@ hcache_done()
|
||||
|
||||
c = hcachelist;
|
||||
for (c = hcachelist; c; c = c->next) {
|
||||
LIST *l;
|
||||
char time_str[30];
|
||||
char age_str[30];
|
||||
char includes_count_str[30];
|
||||
char hdrscan_count_str[30];
|
||||
LIST *l;
|
||||
char time_str[30];
|
||||
char age_str[30];
|
||||
char includes_count_str[30];
|
||||
char hdrscan_count_str[30];
|
||||
|
||||
if (maxage == 0)
|
||||
c->age = 0;
|
||||
else if (c->age > maxage)
|
||||
continue;
|
||||
if (maxage == 0)
|
||||
c->age = 0;
|
||||
else if (c->age > maxage)
|
||||
continue;
|
||||
|
||||
sprintf(includes_count_str, "%lu", list_length(c->includes));
|
||||
sprintf(hdrscan_count_str, "%lu", list_length(c->hdrscan));
|
||||
sprintf(time_str, "%lu", c->time);
|
||||
sprintf(age_str, "%lu", c->age);
|
||||
sprintf(includes_count_str, "%lu", list_length(c->includes));
|
||||
sprintf(hdrscan_count_str, "%lu", list_length(c->hdrscan));
|
||||
sprintf(time_str, "%lu", c->time);
|
||||
sprintf(age_str, "%lu", c->age);
|
||||
|
||||
write_netstring(f, CACHE_RECORD_HEADER);
|
||||
write_netstring(f, c->boundname);
|
||||
write_netstring(f, time_str);
|
||||
write_netstring(f, age_str);
|
||||
write_netstring(f, includes_count_str);
|
||||
for (l = c->includes; l; l = list_next(l)) {
|
||||
write_netstring(f, l->string);
|
||||
}
|
||||
write_netstring(f, hdrscan_count_str);
|
||||
for (l = c->hdrscan; l; l = list_next(l)) {
|
||||
write_netstring(f, l->string);
|
||||
}
|
||||
fputs("\n", f);
|
||||
header_count++;
|
||||
write_netstring(f, CACHE_RECORD_HEADER);
|
||||
write_netstring(f, c->boundname);
|
||||
write_netstring(f, time_str);
|
||||
write_netstring(f, age_str);
|
||||
write_netstring(f, includes_count_str);
|
||||
for (l = c->includes; l; l = list_next(l)) {
|
||||
write_netstring(f, l->string);
|
||||
}
|
||||
write_netstring(f, hdrscan_count_str);
|
||||
for (l = c->hdrscan; l; l = list_next(l)) {
|
||||
write_netstring(f, l->string);
|
||||
}
|
||||
fputs("\n", f);
|
||||
header_count++;
|
||||
}
|
||||
write_netstring(f, CACHE_RECORD_END);
|
||||
|
||||
if (DEBUG_HEADER) {
|
||||
printf("hcache written to %s. %d dependencies, %.0f%% hit rate\n",
|
||||
hcachename, header_count,
|
||||
queries ? 100.0 * hits / queries : 0);
|
||||
printf("hcache written to %s. %d dependencies, %.0f%% hit rate\n",
|
||||
hcachename, header_count,
|
||||
queries ? 100.0 * hits / queries : 0);
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
@@ -351,7 +354,7 @@ LIST *
|
||||
hcache (TARGET *t, int rec, regexp *re[], LIST *hdrscan)
|
||||
{
|
||||
HCACHEDATA cachedata, *c = &cachedata;
|
||||
LIST *l = 0;
|
||||
LIST *l = 0;
|
||||
|
||||
++queries;
|
||||
|
||||
@@ -359,55 +362,55 @@ hcache (TARGET *t, int rec, regexp *re[], LIST *hdrscan)
|
||||
|
||||
if (hashcheck (hcachehash, (HASHDATA **) &c))
|
||||
{
|
||||
if (c->time == t->time)
|
||||
{
|
||||
LIST *l1 = hdrscan, *l2 = c->hdrscan;
|
||||
while (l1 && l2) {
|
||||
if (l1->string != l2->string) {
|
||||
l1 = NULL;
|
||||
} else {
|
||||
l1 = list_next(l1);
|
||||
l2 = list_next(l2);
|
||||
}
|
||||
}
|
||||
if (l1 || l2) {
|
||||
if (DEBUG_HEADER)
|
||||
printf("HDRSCAN out of date in cache for %s\n",
|
||||
t->boundname);
|
||||
if (c->time == t->time)
|
||||
{
|
||||
LIST *l1 = hdrscan, *l2 = c->hdrscan;
|
||||
while (l1 && l2) {
|
||||
if (l1->string != l2->string) {
|
||||
l1 = NULL;
|
||||
} else {
|
||||
l1 = list_next(l1);
|
||||
l2 = list_next(l2);
|
||||
}
|
||||
}
|
||||
if (l1 || l2) {
|
||||
if (DEBUG_HEADER)
|
||||
printf("HDRSCAN out of date in cache for %s\n",
|
||||
t->boundname);
|
||||
|
||||
printf("HDRSCAN out of date for %s\n", t->boundname);
|
||||
printf(" real : ");
|
||||
list_print(hdrscan);
|
||||
printf("\n cached: ");
|
||||
list_print(c->hdrscan);
|
||||
printf("\n");
|
||||
printf("HDRSCAN out of date for %s\n", t->boundname);
|
||||
printf(" real : ");
|
||||
list_print(hdrscan);
|
||||
printf("\n cached: ");
|
||||
list_print(c->hdrscan);
|
||||
printf("\n");
|
||||
|
||||
list_free(c->includes);
|
||||
list_free(c->hdrscan);
|
||||
c->includes = 0;
|
||||
c->hdrscan = 0;
|
||||
} else {
|
||||
if (DEBUG_HEADER)
|
||||
printf ("using header cache for %s\n", t->boundname);
|
||||
c->age = 0;
|
||||
++hits;
|
||||
l = list_copy (0, c->includes);
|
||||
return l;
|
||||
}
|
||||
} else {
|
||||
if (DEBUG_HEADER)
|
||||
printf ("header cache out of date for %s\n", t->boundname);
|
||||
list_free (c->includes);
|
||||
list_free(c->hdrscan);
|
||||
c->includes = 0;
|
||||
c->hdrscan = 0;
|
||||
}
|
||||
list_free(c->includes);
|
||||
list_free(c->hdrscan);
|
||||
c->includes = 0;
|
||||
c->hdrscan = 0;
|
||||
} else {
|
||||
if (DEBUG_HEADER)
|
||||
printf ("using header cache for %s\n", t->boundname);
|
||||
c->age = 0;
|
||||
++hits;
|
||||
l = list_copy (0, c->includes);
|
||||
return l;
|
||||
}
|
||||
} else {
|
||||
if (hashenter (hcachehash, (HASHDATA **)&c)) {
|
||||
c->boundname = newstr (c->boundname);
|
||||
c->next = hcachelist;
|
||||
hcachelist = c;
|
||||
}
|
||||
if (DEBUG_HEADER)
|
||||
printf ("header cache out of date for %s\n", t->boundname);
|
||||
list_free (c->includes);
|
||||
list_free(c->hdrscan);
|
||||
c->includes = 0;
|
||||
c->hdrscan = 0;
|
||||
}
|
||||
} else {
|
||||
if (hashenter (hcachehash, (HASHDATA **)&c)) {
|
||||
c->boundname = newstr (c->boundname);
|
||||
c->next = hcachelist;
|
||||
hcachelist = c;
|
||||
}
|
||||
}
|
||||
|
||||
/* 'c' points at the cache entry. Its out of date. */
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
* #include statements.
|
||||
*
|
||||
* we look for lines like "#define MACRO <....>" or '#define MACRO " "'
|
||||
* in the target file. When found, we
|
||||
* in the target file. When found, we
|
||||
*
|
||||
* we then phony up a rule invocation like:
|
||||
*
|
||||
* $(HDRRULE) <target> : <resolved included files> ;
|
||||
* $(HDRRULE) <target> : <resolved included files> ;
|
||||
*
|
||||
* External routines:
|
||||
* headers1() - scan a target for "#include MACRO" lines and try
|
||||
@@ -42,8 +42,8 @@
|
||||
*
|
||||
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
|
||||
* 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
|
||||
* so that headers() doesn't have to mock up a parse structure
|
||||
* just to invoke a rule.
|
||||
* so that headers() doesn't have to mock up a parse structure
|
||||
* just to invoke a rule.
|
||||
*/
|
||||
|
||||
static LIST *header_macros1( LIST *l, char *file, int rec, regexp *re[] );
|
||||
@@ -53,9 +53,9 @@ typedef struct header_macro
|
||||
{
|
||||
char* symbol;
|
||||
char* filename; /* we could maybe use a LIST here ?? */
|
||||
|
||||
|
||||
} HEADER_MACRO;
|
||||
|
||||
|
||||
static struct hash* header_macros_hash = 0;
|
||||
|
||||
/*
|
||||
@@ -68,9 +68,9 @@ void
|
||||
macro_headers( TARGET *t )
|
||||
{
|
||||
static regexp *re = 0;
|
||||
FILE *f;
|
||||
char buf[ 1024 ];
|
||||
|
||||
FILE *f;
|
||||
char buf[ 1024 ];
|
||||
|
||||
if ( DEBUG_HEADER )
|
||||
printf( "macro header scan for %s\n", t->name );
|
||||
|
||||
@@ -80,10 +80,10 @@ macro_headers( TARGET *t )
|
||||
if ( re == 0 )
|
||||
{
|
||||
re = regex_compile(
|
||||
"^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*"
|
||||
"^[ ]*#[ ]*define[ ]*([A-Za-z][A-Za-z0-9_]*)[ ]*"
|
||||
"[<\"]([^\">]*)[\">].*$" );
|
||||
}
|
||||
|
||||
|
||||
if( !( f = fopen( t->boundname, "r" ) ) )
|
||||
return;
|
||||
|
||||
@@ -96,7 +96,7 @@ macro_headers( TARGET *t )
|
||||
/* we detected a line that looks like "#define MACRO filename */
|
||||
re->endp[1][0] = '\0';
|
||||
re->endp[2][0] = '\0';
|
||||
|
||||
|
||||
if ( DEBUG_HEADER )
|
||||
printf( "macro '%s' used to define filename '%s' in '%s'\n",
|
||||
re->startp[1], re->startp[2], t->boundname );
|
||||
@@ -134,6 +134,6 @@ macro_header_get( const char* macro_name )
|
||||
printf( "### macro '%s' evaluated to '%s'\n", macro_name, v->filename );
|
||||
return v->filename;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
/*
|
||||
* headers.c - handle #includes in source files
|
||||
*
|
||||
* Using regular expressions provided as the variable $(HDRSCAN),
|
||||
* Using regular expressions provided as the variable $(HDRSCAN),
|
||||
* headers() searches a file for #include files and phonies up a
|
||||
* rule invocation:
|
||||
*
|
||||
* $(HDRRULE) <target> : <include files> ;
|
||||
*
|
||||
* $(HDRRULE) <target> : <include files> ;
|
||||
*
|
||||
* External routines:
|
||||
* headers() - scan a target for include files and call HDRRULE
|
||||
@@ -41,8 +41,8 @@
|
||||
*
|
||||
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
|
||||
* 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
|
||||
* so that headers() doesn't have to mock up a parse structure
|
||||
* just to invoke a rule.
|
||||
* so that headers() doesn't have to mock up a parse structure
|
||||
* just to invoke a rule.
|
||||
*/
|
||||
|
||||
#ifndef OPT_HEADER_CACHE_EXT
|
||||
@@ -58,13 +58,13 @@ static LIST *headers1( LIST *l, char *file, int rec, regexp *re[]);
|
||||
void
|
||||
headers( TARGET *t )
|
||||
{
|
||||
LIST *hdrscan;
|
||||
LIST *hdrrule;
|
||||
LIST *headlist = 0;
|
||||
regexp *re[ MAXINC ];
|
||||
int rec = 0;
|
||||
|
||||
if( !( hdrscan = var_get( "HDRSCAN" ) ) ||
|
||||
LIST *hdrscan;
|
||||
LIST *hdrrule;
|
||||
LIST *headlist = 0;
|
||||
regexp *re[ MAXINC ];
|
||||
int rec = 0;
|
||||
|
||||
if( !( hdrscan = var_get( "HDRSCAN" ) ) ||
|
||||
!( hdrrule = var_get( "HDRRULE" ) ) )
|
||||
return;
|
||||
|
||||
@@ -82,7 +82,7 @@ headers( TARGET *t )
|
||||
/* Doctor up call to HDRRULE rule */
|
||||
/* Call headers1() to get LIST of included files. */
|
||||
{
|
||||
FRAME frame[1];
|
||||
FRAME frame[1];
|
||||
frame_init( frame );
|
||||
lol_add( frame->args, list_new( L0, t->name ) );
|
||||
#ifdef OPT_HEADER_CACHE_EXT
|
||||
@@ -115,91 +115,91 @@ LIST *
|
||||
#else
|
||||
static LIST *
|
||||
#endif
|
||||
headers1(
|
||||
LIST *l,
|
||||
char *file,
|
||||
int rec,
|
||||
regexp *re[] )
|
||||
headers1(
|
||||
LIST *l,
|
||||
char *file,
|
||||
int rec,
|
||||
regexp *re[] )
|
||||
{
|
||||
FILE *f;
|
||||
char buf[ 1024 ];
|
||||
int i;
|
||||
FILE *f;
|
||||
char buf[ 1024 ];
|
||||
int i;
|
||||
static regexp *re_macros = 0;
|
||||
|
||||
|
||||
|
||||
#ifdef OPT_IMPROVED_PATIENCE_EXT
|
||||
static int count = 0;
|
||||
++count;
|
||||
if ( ((count == 100) || !( count % 1000 )) && DEBUG_MAKE )
|
||||
printf("...patience...\n");
|
||||
static int count = 0;
|
||||
++count;
|
||||
if ( ((count == 100) || !( count % 1000 )) && DEBUG_MAKE )
|
||||
printf("...patience...\n");
|
||||
#endif
|
||||
|
||||
|
||||
/* the following regexp is used to detect cases where a */
|
||||
/* file is included through a line line "#include MACRO" */
|
||||
if ( re_macros == 0 )
|
||||
{
|
||||
re_macros = regex_compile(
|
||||
"^[ ]*#[ ]*include[ ]*([A-Za-z][A-Za-z0-9_]*).*$" );
|
||||
"^[ ]*#[ ]*include[ ]*([A-Za-z][A-Za-z0-9_]*).*$" );
|
||||
}
|
||||
|
||||
|
||||
if( !( f = fopen( file, "r" ) ) )
|
||||
return l;
|
||||
if( !( f = fopen( file, "r" ) ) )
|
||||
return l;
|
||||
|
||||
while( fgets( buf, sizeof( buf ), f ) )
|
||||
{
|
||||
while( fgets( buf, sizeof( buf ), f ) )
|
||||
{
|
||||
int size = strlen (buf);
|
||||
/* Remove trailing \r and \n, if any. */
|
||||
while (size > 0
|
||||
while (size > 0
|
||||
&& (buf[size-1] == '\n' && buf[size-1] == '\r'))
|
||||
{
|
||||
buf[size-1] = '\0';
|
||||
--size;
|
||||
}
|
||||
|
||||
for( i = 0; i < rec; i++ )
|
||||
if( regexec( re[i], buf ) && re[i]->startp[1] )
|
||||
{
|
||||
re[i]->endp[1][0] = '\0';
|
||||
for( i = 0; i < rec; i++ )
|
||||
if( regexec( re[i], buf ) && re[i]->startp[1] )
|
||||
{
|
||||
re[i]->endp[1][0] = '\0';
|
||||
|
||||
if( DEBUG_HEADER )
|
||||
printf( "header found: %s\n", re[i]->startp[1] );
|
||||
if( DEBUG_HEADER )
|
||||
printf( "header found: %s\n", re[i]->startp[1] );
|
||||
|
||||
l = list_new( l, newstr( re[i]->startp[1] ) );
|
||||
}
|
||||
|
||||
l = list_new( l, newstr( re[i]->startp[1] ) );
|
||||
}
|
||||
|
||||
/* special treatment for #include MACRO */
|
||||
if ( regexec( re_macros, buf ) && re_macros->startp[1] )
|
||||
{
|
||||
char* header_filename;
|
||||
|
||||
re_macros->endp[1][0] = '\0';
|
||||
|
||||
if ( DEBUG_HEADER )
|
||||
printf( "macro header found: %s", re_macros->startp[1] );
|
||||
|
||||
header_filename = macro_header_get( re_macros->startp[1] );
|
||||
if (header_filename)
|
||||
{
|
||||
if ( DEBUG_HEADER )
|
||||
printf( " resolved to '%s'\n", header_filename );
|
||||
l = list_new( l, newstr( header_filename ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( DEBUG_HEADER )
|
||||
printf( " ignored !!\n" );
|
||||
}
|
||||
char* header_filename;
|
||||
|
||||
re_macros->endp[1][0] = '\0';
|
||||
|
||||
if ( DEBUG_HEADER )
|
||||
printf( "macro header found: %s", re_macros->startp[1] );
|
||||
|
||||
header_filename = macro_header_get( re_macros->startp[1] );
|
||||
if ( header_filename )
|
||||
{
|
||||
if ( DEBUG_HEADER )
|
||||
printf( " resolved to '%s'\n", header_filename );
|
||||
l = list_new( l, newstr( header_filename ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( DEBUG_HEADER )
|
||||
printf( " ignored !!\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose( f );
|
||||
fclose( f );
|
||||
|
||||
return l;
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
regerror( char *s )
|
||||
{
|
||||
printf( "re error %s\n", s );
|
||||
printf( "re error %s\n", s );
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* /+\
|
||||
* +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
||||
* +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
|
||||
* \+/
|
||||
*
|
||||
* This file is part of jam.
|
||||
*
|
||||
* License is hereby granted to use this software and distribute it
|
||||
* freely, as long as this copyright notice is retained and modifications
|
||||
* freely, as long as this copyright notice is retained and modifications
|
||||
* are clearly marked.
|
||||
*
|
||||
* ALL WARRANTIES ARE HEREBY DISCLAIMED.
|
||||
@@ -27,11 +27,11 @@
|
||||
*
|
||||
* The top half of the code is structured such:
|
||||
*
|
||||
* jam
|
||||
* / | \
|
||||
* jam
|
||||
* / | \
|
||||
* +---+ | \
|
||||
* / | \
|
||||
* jamgram option \
|
||||
* / | \
|
||||
* jamgram option \
|
||||
* / | \ \
|
||||
* / | \ \
|
||||
* / | \ |
|
||||
@@ -69,32 +69,32 @@
|
||||
*
|
||||
* Roughly, the modules are:
|
||||
*
|
||||
* builtins.c - jam's built-in rules
|
||||
* command.c - maintain lists of commands
|
||||
* compile.c - compile parsed jam statements
|
||||
* execunix.c - execute a shell script on UNIX
|
||||
* execvms.c - execute a shell script, ala VMS
|
||||
* expand.c - expand a buffer, given variable values
|
||||
* file*.c - scan directories and archives on *
|
||||
* hash.c - simple in-memory hashing routines
|
||||
* builtins.c - jam's built-in rules
|
||||
* command.c - maintain lists of commands
|
||||
* compile.c - compile parsed jam statements
|
||||
* execunix.c - execute a shell script on UNIX
|
||||
* execvms.c - execute a shell script, ala VMS
|
||||
* expand.c - expand a buffer, given variable values
|
||||
* file*.c - scan directories and archives on *
|
||||
* hash.c - simple in-memory hashing routines
|
||||
* hdrmacro.c - handle header file parsing for filename macro definitions
|
||||
* headers.c - handle #includes in source files
|
||||
* jambase.c - compilable copy of Jambase
|
||||
* jamgram.y - jam grammar
|
||||
* lists.c - maintain lists of strings
|
||||
* make.c - bring a target up to date, once rules are in place
|
||||
* make1.c - execute command to bring targets up to date
|
||||
* newstr.c - string manipulation routines
|
||||
* option.c - command line option processing
|
||||
* parse.c - make and destroy parse trees as driven by the parser
|
||||
* path*.c - manipulate file names on *
|
||||
* hash.c - simple in-memory hashing routines
|
||||
* regexp.c - Henry Spencer's regexp
|
||||
* rules.c - access to RULEs, TARGETs, and ACTIONs
|
||||
* scan.c - the jam yacc scanner
|
||||
* search.c - find a target along $(SEARCH) or $(LOCATE)
|
||||
* timestamp.c - get the timestamp of a file or archive member
|
||||
* variable.c - handle jam multi-element variables
|
||||
* headers.c - handle #includes in source files
|
||||
* jambase.c - compilable copy of Jambase
|
||||
* jamgram.y - jam grammar
|
||||
* lists.c - maintain lists of strings
|
||||
* make.c - bring a target up to date, once rules are in place
|
||||
* make1.c - execute command to bring targets up to date
|
||||
* newstr.c - string manipulation routines
|
||||
* option.c - command line option processing
|
||||
* parse.c - make and destroy parse trees as driven by the parser
|
||||
* path*.c - manipulate file names on *
|
||||
* hash.c - simple in-memory hashing routines
|
||||
* regexp.c - Henry Spencer's regexp
|
||||
* rules.c - access to RULEs, TARGETs, and ACTIONs
|
||||
* scan.c - the jam yacc scanner
|
||||
* search.c - find a target along $(SEARCH) or $(LOCATE)
|
||||
* timestamp.c - get the timestamp of a file or archive member
|
||||
* variable.c - handle jam multi-element variables
|
||||
*
|
||||
* 05/04/94 (seiwald) - async multiprocess (-j) support
|
||||
* 02/08/95 (seiwald) - -n implies -d2.
|
||||
@@ -138,17 +138,17 @@
|
||||
# endif
|
||||
|
||||
struct globs globs = {
|
||||
0, /* noexec */
|
||||
1, /* jobs */
|
||||
0, /* quitquick */
|
||||
0, /* newestfirst */
|
||||
0, /* noexec */
|
||||
1, /* jobs */
|
||||
0, /* quitquick */
|
||||
0, /* newestfirst */
|
||||
0, /* pipes action stdout and stderr merged to action output */
|
||||
# ifdef OS_MAC
|
||||
{ 0, 0 }, /* debug - suppress tracing output */
|
||||
{ 0, 0 }, /* debug - suppress tracing output */
|
||||
# else
|
||||
{ 0, 1 }, /* debug ... */
|
||||
{ 0, 1 }, /* debug ... */
|
||||
# endif
|
||||
0, /* output commands, not run them */
|
||||
0, /* output commands, not run them */
|
||||
0 /* action timeout */
|
||||
} ;
|
||||
|
||||
@@ -156,9 +156,9 @@ struct globs globs = {
|
||||
|
||||
static char *othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 } ;
|
||||
|
||||
/* Known for sure:
|
||||
* mac needs arg_enviro
|
||||
* OS2 needs extern environ
|
||||
/* Known for sure:
|
||||
* mac needs arg_enviro
|
||||
* OS2 needs extern environ
|
||||
*/
|
||||
|
||||
# ifdef OS_MAC
|
||||
@@ -180,7 +180,7 @@ extern char **_environ;
|
||||
|
||||
# ifndef use_environ
|
||||
# define use_environ environ
|
||||
# if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT )
|
||||
# if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT )
|
||||
extern char **environ;
|
||||
# endif
|
||||
# endif
|
||||
@@ -195,7 +195,7 @@ static void run_unit_tests()
|
||||
# if defined( USE_EXECNT )
|
||||
extern void execnt_unit_test();
|
||||
execnt_unit_test();
|
||||
# endif
|
||||
# endif
|
||||
string_unit_test();
|
||||
var_expand_unit_test();
|
||||
}
|
||||
@@ -204,7 +204,7 @@ static void run_unit_tests()
|
||||
#ifdef HAVE_PYTHON
|
||||
extern PyObject*
|
||||
bjam_call(PyObject *self, PyObject *args);
|
||||
|
||||
|
||||
extern PyObject*
|
||||
bjam_import_rule(PyObject* self, PyObject* args);
|
||||
|
||||
@@ -220,12 +220,12 @@ static void run_unit_tests()
|
||||
|
||||
int main( int argc, char **argv, char **arg_environ )
|
||||
{
|
||||
int n;
|
||||
char *s;
|
||||
struct option optv[N_OPTS];
|
||||
const char *all = "all";
|
||||
int anyhow = 0;
|
||||
int status;
|
||||
int n;
|
||||
char *s;
|
||||
struct option optv[N_OPTS];
|
||||
const char *all = "all";
|
||||
int anyhow = 0;
|
||||
int status;
|
||||
int arg_c = argc;
|
||||
char ** arg_v = argv;
|
||||
const char *progname = argv[0];
|
||||
@@ -292,7 +292,7 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
}
|
||||
|
||||
if( ( s = getoptval( optv, 'q', 0 ) ) )
|
||||
globs.quitquick = 1;
|
||||
globs.quitquick = 1;
|
||||
|
||||
if( ( s = getoptval( optv, 'a', 0 ) ) )
|
||||
anyhow++;
|
||||
@@ -341,7 +341,7 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
{
|
||||
PROFILE_ENTER(MAIN_PYTHON);
|
||||
Py_Initialize();
|
||||
|
||||
|
||||
{
|
||||
static PyMethodDef BjamMethods[] = {
|
||||
{"call", bjam_call, METH_VARARGS,
|
||||
@@ -356,13 +356,13 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
"Returns bjam backtrace from the last call into Python."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
Py_InitModule("bjam", BjamMethods);
|
||||
|
||||
Py_InitModule( "bjam", BjamMethods );
|
||||
}
|
||||
PROFILE_EXIT(MAIN_PYTHON);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
run_unit_tests();
|
||||
#endif
|
||||
@@ -375,10 +375,9 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
|
||||
var_set( "JAMDATE", list_new( L0, outf_time(time(0)) ), VAR_SET );
|
||||
|
||||
|
||||
var_set( "JAM_VERSION",
|
||||
list_new( list_new( list_new( L0, newstr( VERSION_MAJOR_SYM ) ),
|
||||
newstr( VERSION_MINOR_SYM ) ),
|
||||
list_new( list_new( list_new( L0, newstr( VERSION_MAJOR_SYM ) ),
|
||||
newstr( VERSION_MINOR_SYM ) ),
|
||||
newstr( VERSION_PATCH_SYM ) ),
|
||||
VAR_SET );
|
||||
|
||||
@@ -389,12 +388,12 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
|
||||
if( uname( &u ) >= 0 )
|
||||
{
|
||||
var_set( "JAMUNAME",
|
||||
list_new(
|
||||
var_set( "JAMUNAME",
|
||||
list_new(
|
||||
list_new(
|
||||
list_new(
|
||||
list_new(
|
||||
list_new( L0,
|
||||
list_new( L0,
|
||||
newstr( u.sysname ) ),
|
||||
newstr( u.nodename ) ),
|
||||
newstr( u.release ) ),
|
||||
@@ -408,18 +407,18 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
|
||||
/* first into global module, with splitting, for backward compatibility */
|
||||
var_defines( use_environ, 1 );
|
||||
|
||||
|
||||
/* then into .ENVIRON, without splitting */
|
||||
enter_module( bindmodule(".ENVIRON") );
|
||||
var_defines( use_environ, 0 );
|
||||
exit_module( bindmodule(".ENVIRON") );
|
||||
|
||||
/*
|
||||
* Jam defined variables OS, OSPLAT
|
||||
/*
|
||||
* Jam defined variables OS, OSPLAT
|
||||
* We load them after environment, so that
|
||||
* setting OS in environment does not
|
||||
* setting OS in environment does not
|
||||
* change Jam notion of the current platform.
|
||||
*/
|
||||
*/
|
||||
|
||||
var_defines( othersyms, 1 );
|
||||
|
||||
@@ -444,9 +443,9 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
var_set( "ARGV", list_new( L0, newstr( arg_v[n] ) ), VAR_APPEND );
|
||||
}
|
||||
|
||||
/* Initialize built-in rules */
|
||||
/* Initialize built-in rules */
|
||||
|
||||
load_builtins();
|
||||
load_builtins();
|
||||
|
||||
/* Add the targets in the command line to update list */
|
||||
|
||||
@@ -469,11 +468,11 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
{
|
||||
FRAME frame[1];
|
||||
frame_init( frame );
|
||||
for( n = 0; s = getoptval( optv, 'f', n ); n++ )
|
||||
parse_file( s, frame );
|
||||
for( n = 0; s = getoptval( optv, 'f', n ); n++ )
|
||||
parse_file( s, frame );
|
||||
|
||||
if( !n )
|
||||
parse_file( "+", frame );
|
||||
if( !n )
|
||||
parse_file( "+", frame );
|
||||
}
|
||||
|
||||
status = yyanyerrors();
|
||||
@@ -499,13 +498,13 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
|
||||
{
|
||||
PROFILE_ENTER(MAIN_MAKE);
|
||||
|
||||
LIST* targets = targets_to_update();
|
||||
|
||||
LIST * targets = targets_to_update();
|
||||
if ( !targets )
|
||||
{
|
||||
status |= make( 1, &all, anyhow );
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
int targets_count = list_length(targets);
|
||||
const char **targets2 = (const char **)BJAM_MALLOC(targets_count * sizeof(char *));
|
||||
@@ -514,16 +513,16 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
{
|
||||
targets2[n++] = targets->string;
|
||||
}
|
||||
status |= make( targets_count, targets2, anyhow );
|
||||
status |= make( targets_count, targets2, anyhow );
|
||||
free(targets);
|
||||
}
|
||||
|
||||
|
||||
PROFILE_EXIT(MAIN_MAKE);
|
||||
}
|
||||
|
||||
|
||||
PROFILE_EXIT(MAIN); }
|
||||
|
||||
|
||||
if ( DEBUG_PROFILE )
|
||||
profile_dump();
|
||||
|
||||
@@ -543,9 +542,8 @@ int main( int argc, char **argv, char **arg_environ )
|
||||
#ifdef HAVE_PYTHON
|
||||
Py_Finalize();
|
||||
#endif
|
||||
|
||||
BJAM_MEM_CLOSE();
|
||||
|
||||
BJAM_MEM_CLOSE();
|
||||
|
||||
return status ? EXITBAD : EXITOK;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
/* This may be inaccurate */
|
||||
# ifndef __DECC
|
||||
# define OSPLAT "OSPLAT=VAX"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
# define SPLITPATH ';'
|
||||
/* Windows NT 3.51 only allows 996 chars per line, but we deal */
|
||||
/* with problem in "execnt.c". */
|
||||
# define MAXLINE (maxline()) /* longest 'together' actions */
|
||||
# define MAXLINE (maxline()) /* longest 'together' actions */
|
||||
# define USE_EXECNT
|
||||
# define USE_PATHUNIX
|
||||
# define PATH_DELIM '\\'
|
||||
@@ -147,7 +147,7 @@
|
||||
# define OSMINOR "OS=MINGW"
|
||||
# define OS_NT
|
||||
# define SPLITPATH ';'
|
||||
# define MAXLINE 996 /* longest 'together' actions */
|
||||
# define MAXLINE 996 /* longest 'together' actions */
|
||||
# define USE_EXECUNIX
|
||||
# define USE_PATHUNIX
|
||||
# define PATH_DELIM '\\'
|
||||
@@ -174,7 +174,7 @@
|
||||
# define OSMINOR "OS=OS2"
|
||||
# define OS_OS2
|
||||
# define SPLITPATH ';'
|
||||
# define MAXLINE 996 /* longest 'together' actions */
|
||||
# define MAXLINE 996 /* longest 'together' actions */
|
||||
# define USE_EXECUNIX
|
||||
# define USE_PATHUNIX
|
||||
# define PATH_DELIM '\\'
|
||||
@@ -430,9 +430,9 @@
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*
|
||||
/*
|
||||
* OSPLAT definitions - suppressed when it's a one-of-a-kind
|
||||
*/
|
||||
|
||||
@@ -453,7 +453,7 @@
|
||||
defined( __i386__ ) || \
|
||||
defined( _M_IX86 )
|
||||
# define OSPLAT "OSPLAT=X86"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined( __ia64__ ) || defined( __IA64__ ) || defined( __ia64 )
|
||||
# define OSPLAT "OSPLAT=IA64"
|
||||
@@ -496,7 +496,7 @@
|
||||
*/
|
||||
|
||||
# ifndef MAXLINE
|
||||
# define MAXLINE 102400 /* longest 'together' actions' */
|
||||
# define MAXLINE 102400 /* longest 'together' actions' */
|
||||
# endif
|
||||
|
||||
# ifndef EXITOK
|
||||
@@ -510,55 +510,55 @@
|
||||
|
||||
/* You probably don't need to muck with these. */
|
||||
|
||||
# define MAXSYM 1024 /* longest symbol in the environment */
|
||||
# define MAXJPATH 1024 /* longest filename */
|
||||
# define MAXSYM 1024 /* longest symbol in the environment */
|
||||
# define MAXJPATH 1024 /* longest filename */
|
||||
|
||||
# define MAXJOBS 64 /* silently enforce -j limit */
|
||||
# define MAXARGC 32 /* words in $(JAMSHELL) */
|
||||
# define MAXJOBS 64 /* silently enforce -j limit */
|
||||
# define MAXARGC 32 /* words in $(JAMSHELL) */
|
||||
|
||||
/* Jam private definitions below. */
|
||||
|
||||
# define DEBUG_MAX 14
|
||||
# define DEBUG_MAX 14
|
||||
|
||||
struct globs {
|
||||
int noexec;
|
||||
int jobs;
|
||||
int quitquick;
|
||||
int newestfirst; /* build newest sources first */
|
||||
int noexec;
|
||||
int jobs;
|
||||
int quitquick;
|
||||
int newestfirst; /* build newest sources first */
|
||||
int pipe_action;
|
||||
char debug[DEBUG_MAX];
|
||||
FILE *cmdout; /* print cmds, not run them */
|
||||
char debug[DEBUG_MAX];
|
||||
FILE *cmdout; /* print cmds, not run them */
|
||||
long timeout; /* number of seconds to limit actions to, default 0 for no limit. */
|
||||
int dart; /* output build and test results formatted for Dart */
|
||||
} ;
|
||||
|
||||
extern struct globs globs;
|
||||
|
||||
# define DEBUG_MAKE ( globs.debug[ 1 ] ) /* show actions when executed */
|
||||
# define DEBUG_MAKEQ ( globs.debug[ 2 ] ) /* show even quiet actions */
|
||||
# define DEBUG_EXEC ( globs.debug[ 2 ] ) /* show text of actons */
|
||||
# define DEBUG_MAKEPROG ( globs.debug[ 3 ] ) /* show progress of make0 */
|
||||
# define DEBUG_BIND ( globs.debug[ 3 ] ) /* show when files bound */
|
||||
# define DEBUG_MAKE ( globs.debug[ 1 ] ) /* show actions when executed */
|
||||
# define DEBUG_MAKEQ ( globs.debug[ 2 ] ) /* show even quiet actions */
|
||||
# define DEBUG_EXEC ( globs.debug[ 2 ] ) /* show text of actons */
|
||||
# define DEBUG_MAKEPROG ( globs.debug[ 3 ] ) /* show progress of make0 */
|
||||
# define DEBUG_BIND ( globs.debug[ 3 ] ) /* show when files bound */
|
||||
|
||||
# define DEBUG_EXECCMD ( globs.debug[ 4 ] ) /* show execcmds()'s work */
|
||||
# define DEBUG_EXECCMD ( globs.debug[ 4 ] ) /* show execcmds()'s work */
|
||||
|
||||
# define DEBUG_COMPILE ( globs.debug[ 5 ] ) /* show rule invocations */
|
||||
# define DEBUG_COMPILE ( globs.debug[ 5 ] ) /* show rule invocations */
|
||||
|
||||
# define DEBUG_HEADER ( globs.debug[ 6 ] ) /* show result of header scan */
|
||||
# define DEBUG_BINDSCAN ( globs.debug[ 6 ] ) /* show result of dir scan */
|
||||
# define DEBUG_SEARCH ( globs.debug[ 6 ] ) /* show attempts at binding */
|
||||
# define DEBUG_HEADER ( globs.debug[ 6 ] ) /* show result of header scan */
|
||||
# define DEBUG_BINDSCAN ( globs.debug[ 6 ] ) /* show result of dir scan */
|
||||
# define DEBUG_SEARCH ( globs.debug[ 6 ] ) /* show attempts at binding */
|
||||
|
||||
# define DEBUG_VARSET ( globs.debug[ 7 ] ) /* show variable settings */
|
||||
# define DEBUG_VARGET ( globs.debug[ 8 ] ) /* show variable fetches */
|
||||
# define DEBUG_VAREXP ( globs.debug[ 8 ] ) /* show variable expansions */
|
||||
# define DEBUG_IF ( globs.debug[ 8 ] ) /* show 'if' calculations */
|
||||
# define DEBUG_LISTS ( globs.debug[ 9 ] ) /* show list manipulation */
|
||||
# define DEBUG_SCAN ( globs.debug[ 9 ] ) /* show scanner tokens */
|
||||
# define DEBUG_MEM ( globs.debug[ 9 ] ) /* show memory use */
|
||||
# define DEBUG_VARSET ( globs.debug[ 7 ] ) /* show variable settings */
|
||||
# define DEBUG_VARGET ( globs.debug[ 8 ] ) /* show variable fetches */
|
||||
# define DEBUG_VAREXP ( globs.debug[ 8 ] ) /* show variable expansions */
|
||||
# define DEBUG_IF ( globs.debug[ 8 ] ) /* show 'if' calculations */
|
||||
# define DEBUG_LISTS ( globs.debug[ 9 ] ) /* show list manipulation */
|
||||
# define DEBUG_SCAN ( globs.debug[ 9 ] ) /* show scanner tokens */
|
||||
# define DEBUG_MEM ( globs.debug[ 9 ] ) /* show memory use */
|
||||
|
||||
# define DEBUG_PROFILE ( globs.debug[ 10 ] ) /* dump rule execution times */
|
||||
# define DEBUG_PARSE ( globs.debug[ 11 ] ) /* debug parsing */
|
||||
# define DEBUG_GRAPH ( globs.debug[ 12 ] ) /* debug dependencies */
|
||||
# define DEBUG_PROFILE ( globs.debug[ 10 ] ) /* dump rule execution times */
|
||||
# define DEBUG_PARSE ( globs.debug[ 11 ] ) /* debug parsing */
|
||||
# define DEBUG_GRAPH ( globs.debug[ 12 ] ) /* debug dependencies */
|
||||
# define DEBUG_FATE ( globs.debug[ 13 ] ) /* show changes to fate in make0() */
|
||||
|
||||
/* Everyone gets the memory definitions. */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* jambase.h - declaration for the internal jambase
|
||||
*
|
||||
* The file Jambase is turned into a C array of strings in jambase.c
|
||||
* so that it can be built in to the executable. This is the
|
||||
* so that it can be built in to the executable. This is the
|
||||
* declaration for that array.
|
||||
*/
|
||||
|
||||
|
||||
@@ -438,17 +438,17 @@ static const unsigned short yyrline[] =
|
||||
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
|
||||
static const char *const yytname[] =
|
||||
{
|
||||
"$end", "error", "$undefined", "_BANG_t", "_BANG_EQUALS_t", "_AMPER_t",
|
||||
"_AMPERAMPER_t", "_LPAREN_t", "_RPAREN_t", "_PLUS_EQUALS_t", "_COLON_t",
|
||||
"_SEMIC_t", "_LANGLE_t", "_LANGLE_EQUALS_t", "_EQUALS_t", "_RANGLE_t",
|
||||
"_RANGLE_EQUALS_t", "_QUESTION_EQUALS_t", "_LBRACKET_t", "_RBRACKET_t",
|
||||
"ACTIONS_t", "BIND_t", "CASE_t", "CLASS_t", "DEFAULT_t", "ELSE_t",
|
||||
"EXISTING_t", "FOR_t", "IF_t", "IGNORE_t", "IN_t", "INCLUDE_t",
|
||||
"LOCAL_t", "MODULE_t", "ON_t", "PIECEMEAL_t", "QUIETLY_t", "RETURN_t",
|
||||
"RULE_t", "SWITCH_t", "TOGETHER_t", "UPDATED_t", "WHILE_t", "_LBRACE_t",
|
||||
"_BAR_t", "_BARBAR_t", "_RBRACE_t", "ARG", "STRING", "$accept", "run",
|
||||
"block", "rules", "null", "assign_list_opt", "arglist_opt", "local_opt",
|
||||
"rule", "@1", "@2", "assign", "expr", "cases", "case", "lol", "list",
|
||||
"$end", "error", "$undefined", "_BANG_t", "_BANG_EQUALS_t", "_AMPER_t",
|
||||
"_AMPERAMPER_t", "_LPAREN_t", "_RPAREN_t", "_PLUS_EQUALS_t", "_COLON_t",
|
||||
"_SEMIC_t", "_LANGLE_t", "_LANGLE_EQUALS_t", "_EQUALS_t", "_RANGLE_t",
|
||||
"_RANGLE_EQUALS_t", "_QUESTION_EQUALS_t", "_LBRACKET_t", "_RBRACKET_t",
|
||||
"ACTIONS_t", "BIND_t", "CASE_t", "CLASS_t", "DEFAULT_t", "ELSE_t",
|
||||
"EXISTING_t", "FOR_t", "IF_t", "IGNORE_t", "IN_t", "INCLUDE_t",
|
||||
"LOCAL_t", "MODULE_t", "ON_t", "PIECEMEAL_t", "QUIETLY_t", "RETURN_t",
|
||||
"RULE_t", "SWITCH_t", "TOGETHER_t", "UPDATED_t", "WHILE_t", "_LBRACE_t",
|
||||
"_BAR_t", "_BARBAR_t", "_RBRACE_t", "ARG", "STRING", "$accept", "run",
|
||||
"block", "rules", "null", "assign_list_opt", "arglist_opt", "local_opt",
|
||||
"rule", "@1", "@2", "assign", "expr", "cases", "case", "lol", "list",
|
||||
"listp", "arg", "@3", "func", "eflags", "eflag", "bindlist", 0
|
||||
};
|
||||
#endif
|
||||
@@ -1007,7 +1007,7 @@ yyparse ()
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
|
||||
|
||||
register int yystate;
|
||||
register int yyn;
|
||||
int yyresult;
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
*
|
||||
* New "[ rule ]" syntax evals rule into a LIST.
|
||||
*
|
||||
* Lists are now generated by compile_list() and
|
||||
* Lists are now generated by compile_list() and
|
||||
* compile_append(), and any other rule that indirectly
|
||||
* makes a list, rather than being built directly here,
|
||||
* so that lists values can contain rule evaluations.
|
||||
@@ -81,7 +81,7 @@
|
||||
* New 'return' rule sets the return value, though
|
||||
* other statements also may have return values.
|
||||
*
|
||||
* 'run' production split from 'block' production so
|
||||
* 'run' production split from 'block' production so
|
||||
* that empty blocks can be handled separately.
|
||||
*/
|
||||
|
||||
@@ -201,13 +201,13 @@ rule : _LBRACE_t block _RBRACE_t
|
||||
{ $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); }
|
||||
| SWITCH_t list _LBRACE_t cases _RBRACE_t
|
||||
{ $$.parse = pswitch( $2.parse, $4.parse ); }
|
||||
| IF_t expr _LBRACE_t block _RBRACE_t
|
||||
| IF_t expr _LBRACE_t block _RBRACE_t
|
||||
{ $$.parse = pif( $2.parse, $4.parse, pnull() ); }
|
||||
| MODULE_t list _LBRACE_t block _RBRACE_t
|
||||
| MODULE_t list _LBRACE_t block _RBRACE_t
|
||||
{ $$.parse = pmodule( $2.parse, $4.parse ); }
|
||||
| CLASS_t lol _LBRACE_t block _RBRACE_t
|
||||
| CLASS_t lol _LBRACE_t block _RBRACE_t
|
||||
{ $$.parse = pclass( $2.parse, $4.parse ); }
|
||||
| WHILE_t expr _LBRACE_t block _RBRACE_t
|
||||
| WHILE_t expr _LBRACE_t block _RBRACE_t
|
||||
{ $$.parse = pwhile( $2.parse, $4.parse ); }
|
||||
| IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule
|
||||
{ $$.parse = pif( $2.parse, $4.parse, $7.parse ); }
|
||||
@@ -217,7 +217,7 @@ rule : _LBRACE_t block _RBRACE_t
|
||||
{ $$.parse = pon( $2.parse, $3.parse ); }
|
||||
| ACTIONS_t eflags ARG bindlist _LBRACE_t
|
||||
{ yymode( SCAN_STRING ); }
|
||||
STRING
|
||||
STRING
|
||||
{ yymode( SCAN_NORMAL ); }
|
||||
_RBRACE_t
|
||||
{ $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); }
|
||||
@@ -240,23 +240,23 @@ assign : _EQUALS_t
|
||||
/*
|
||||
* expr - an expression for if
|
||||
*/
|
||||
expr : arg
|
||||
expr : arg
|
||||
{ $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); }
|
||||
| expr _EQUALS_t expr
|
||||
| expr _EQUALS_t expr
|
||||
{ $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); }
|
||||
| expr _BANG_EQUALS_t expr
|
||||
{ $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); }
|
||||
| expr _LANGLE_t expr
|
||||
{ $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); }
|
||||
| expr _LANGLE_EQUALS_t expr
|
||||
| expr _LANGLE_EQUALS_t expr
|
||||
{ $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); }
|
||||
| expr _RANGLE_t expr
|
||||
| expr _RANGLE_t expr
|
||||
{ $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); }
|
||||
| expr _RANGLE_EQUALS_t expr
|
||||
| expr _RANGLE_EQUALS_t expr
|
||||
{ $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); }
|
||||
| expr _AMPER_t expr
|
||||
| expr _AMPER_t expr
|
||||
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
|
||||
| expr _AMPERAMPER_t expr
|
||||
| expr _AMPERAMPER_t expr
|
||||
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
|
||||
| expr _BAR_t expr
|
||||
{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
|
||||
@@ -314,7 +314,7 @@ listp : /* empty */
|
||||
{ $$.parse = pappend( $1.parse, $2.parse ); }
|
||||
;
|
||||
|
||||
arg : ARG
|
||||
arg : ARG
|
||||
{ $$.parse = plist( $1.string ); }
|
||||
| _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t
|
||||
{ $$.parse = $3.parse; }
|
||||
@@ -329,7 +329,7 @@ func : arg lol
|
||||
{ $$.parse = prule( $1.string, $2.parse ); }
|
||||
| ON_t arg arg lol
|
||||
{ $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); }
|
||||
| ON_t arg RETURN_t list
|
||||
| ON_t arg RETURN_t list
|
||||
{ $$.parse = pon( $2.parse, $4.parse ); }
|
||||
;
|
||||
|
||||
@@ -369,5 +369,3 @@ bindlist : /* empty */
|
||||
| BIND_t list
|
||||
{ $$.parse = $2.parse; }
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*
|
||||
* New "[ rule ]" syntax evals rule into a LIST.
|
||||
*
|
||||
* Lists are now generated by compile_list() and
|
||||
* Lists are now generated by compile_list() and
|
||||
* compile_append(), and any other rule that indirectly
|
||||
* makes a list, rather than being built directly here,
|
||||
* so that lists values can contain rule evaluations.
|
||||
@@ -37,7 +37,7 @@
|
||||
* New 'return' rule sets the return value, though
|
||||
* other statements also may have return values.
|
||||
*
|
||||
* 'run' production split from 'block' production so
|
||||
* 'run' production split from 'block' production so
|
||||
* that empty blocks can be handled separately.
|
||||
*/
|
||||
|
||||
@@ -157,13 +157,13 @@ rule : `{` block `}`
|
||||
{ $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); }
|
||||
| `switch` list `{` cases `}`
|
||||
{ $$.parse = pswitch( $2.parse, $4.parse ); }
|
||||
| `if` expr `{` block `}`
|
||||
| `if` expr `{` block `}`
|
||||
{ $$.parse = pif( $2.parse, $4.parse, pnull() ); }
|
||||
| `module` list `{` block `}`
|
||||
| `module` list `{` block `}`
|
||||
{ $$.parse = pmodule( $2.parse, $4.parse ); }
|
||||
| `class` lol `{` block `}`
|
||||
| `class` lol `{` block `}`
|
||||
{ $$.parse = pclass( $2.parse, $4.parse ); }
|
||||
| `while` expr `{` block `}`
|
||||
| `while` expr `{` block `}`
|
||||
{ $$.parse = pwhile( $2.parse, $4.parse ); }
|
||||
| `if` expr `{` block `}` `else` rule
|
||||
{ $$.parse = pif( $2.parse, $4.parse, $7.parse ); }
|
||||
@@ -173,7 +173,7 @@ rule : `{` block `}`
|
||||
{ $$.parse = pon( $2.parse, $3.parse ); }
|
||||
| `actions` eflags ARG bindlist `{`
|
||||
{ yymode( SCAN_STRING ); }
|
||||
STRING
|
||||
STRING
|
||||
{ yymode( SCAN_NORMAL ); }
|
||||
`}`
|
||||
{ $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); }
|
||||
@@ -196,23 +196,23 @@ assign : `=`
|
||||
/*
|
||||
* expr - an expression for if
|
||||
*/
|
||||
expr : arg
|
||||
expr : arg
|
||||
{ $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); }
|
||||
| expr `=` expr
|
||||
| expr `=` expr
|
||||
{ $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); }
|
||||
| expr `!=` expr
|
||||
{ $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); }
|
||||
| expr `<` expr
|
||||
{ $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); }
|
||||
| expr `<=` expr
|
||||
| expr `<=` expr
|
||||
{ $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); }
|
||||
| expr `>` expr
|
||||
| expr `>` expr
|
||||
{ $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); }
|
||||
| expr `>=` expr
|
||||
| expr `>=` expr
|
||||
{ $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); }
|
||||
| expr `&` expr
|
||||
| expr `&` expr
|
||||
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
|
||||
| expr `&&` expr
|
||||
| expr `&&` expr
|
||||
{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
|
||||
| expr `|` expr
|
||||
{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
|
||||
@@ -270,7 +270,7 @@ listp : /* empty */
|
||||
{ $$.parse = pappend( $1.parse, $2.parse ); }
|
||||
;
|
||||
|
||||
arg : ARG
|
||||
arg : ARG
|
||||
{ $$.parse = plist( $1.string ); }
|
||||
| `[` { yymode( SCAN_NORMAL ); } func `]`
|
||||
{ $$.parse = $3.parse; }
|
||||
@@ -285,7 +285,7 @@ func : arg lol
|
||||
{ $$.parse = prule( $1.string, $2.parse ); }
|
||||
| `on` arg arg lol
|
||||
{ $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); }
|
||||
| `on` arg `return` list
|
||||
| `on` arg `return` list
|
||||
{ $$.parse = pon( $2.parse, $4.parse ); }
|
||||
;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* 09/07/00 (seiwald) - documented lol_*() functions
|
||||
*/
|
||||
|
||||
static LIST *freelist = 0; /* junkpile for list_free() */
|
||||
static LIST *freelist = 0; /* junkpile for list_free() */
|
||||
|
||||
/*
|
||||
* list_append() - append a list onto another one, returning total
|
||||
@@ -33,25 +33,25 @@ static LIST *freelist = 0; /* junkpile for list_free() */
|
||||
|
||||
LIST *
|
||||
list_append(
|
||||
LIST *l,
|
||||
LIST *nl )
|
||||
LIST *l,
|
||||
LIST *nl )
|
||||
{
|
||||
if( !nl )
|
||||
{
|
||||
/* Just return l */
|
||||
}
|
||||
else if( !l )
|
||||
{
|
||||
l = nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Graft two non-empty lists. */
|
||||
l->tail->next = nl;
|
||||
l->tail = nl->tail;
|
||||
}
|
||||
if( !nl )
|
||||
{
|
||||
/* Just return l */
|
||||
}
|
||||
else if( !l )
|
||||
{
|
||||
l = nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Graft two non-empty lists. */
|
||||
l->tail->next = nl;
|
||||
l->tail = nl->tail;
|
||||
}
|
||||
|
||||
return l;
|
||||
return l;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -60,41 +60,41 @@ list_append(
|
||||
|
||||
LIST *
|
||||
list_new(
|
||||
LIST *head,
|
||||
char *string )
|
||||
LIST *head,
|
||||
char *string )
|
||||
{
|
||||
LIST *l;
|
||||
LIST *l;
|
||||
|
||||
if( DEBUG_LISTS )
|
||||
printf( "list > %s <\n", string );
|
||||
if( DEBUG_LISTS )
|
||||
printf( "list > %s <\n", string );
|
||||
|
||||
/* Get list struct from freelist, if one available. */
|
||||
/* Otherwise allocate. */
|
||||
/* If from freelist, must free string first */
|
||||
/* Get list struct from freelist, if one available. */
|
||||
/* Otherwise allocate. */
|
||||
/* If from freelist, must free string first */
|
||||
|
||||
if( freelist )
|
||||
{
|
||||
l = freelist;
|
||||
freestr( l->string );
|
||||
freelist = freelist->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( freelist )
|
||||
{
|
||||
l = freelist;
|
||||
freestr( l->string );
|
||||
freelist = freelist->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = (LIST *)BJAM_MALLOC( sizeof( LIST ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* If first on chain, head points here. */
|
||||
/* If adding to chain, tack us on. */
|
||||
/* Tail must point to this new, last element. */
|
||||
/* If first on chain, head points here. */
|
||||
/* If adding to chain, tack us on. */
|
||||
/* Tail must point to this new, last element. */
|
||||
|
||||
if( !head ) head = l;
|
||||
else head->tail->next = l;
|
||||
head->tail = l;
|
||||
l->next = 0;
|
||||
if( !head ) head = l;
|
||||
else head->tail->next = l;
|
||||
head->tail = l;
|
||||
l->next = 0;
|
||||
|
||||
l->string = string;
|
||||
l->string = string;
|
||||
|
||||
return head;
|
||||
return head;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,13 +103,13 @@ list_new(
|
||||
|
||||
LIST *
|
||||
list_copy(
|
||||
LIST *l,
|
||||
LIST *nl )
|
||||
LIST *l,
|
||||
LIST *nl )
|
||||
{
|
||||
for( ; nl; nl = list_next( nl ) )
|
||||
l = list_new( l, copystr( nl->string ) );
|
||||
for( ; nl; nl = list_next( nl ) )
|
||||
l = list_new( l, copystr( nl->string ) );
|
||||
|
||||
return l;
|
||||
return l;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -118,19 +118,19 @@ list_copy(
|
||||
|
||||
LIST *
|
||||
list_sublist(
|
||||
LIST *l,
|
||||
int start,
|
||||
int count )
|
||||
LIST *l,
|
||||
int start,
|
||||
int count )
|
||||
{
|
||||
LIST *nl = 0;
|
||||
LIST *nl = 0;
|
||||
|
||||
for( ; l && start--; l = list_next( l ) )
|
||||
;
|
||||
for( ; l && start--; l = list_next( l ) )
|
||||
;
|
||||
|
||||
for( ; l && count--; l = list_next( l ) )
|
||||
nl = list_new( nl, copystr( l->string ) );
|
||||
for( ; l && count--; l = list_next( l ) )
|
||||
nl = list_new( nl, copystr( l->string ) );
|
||||
|
||||
return nl;
|
||||
return nl;
|
||||
}
|
||||
|
||||
static int str_ptr_compare(const void *va, const void *vb)
|
||||
@@ -177,15 +177,15 @@ list_sort(
|
||||
*/
|
||||
|
||||
void
|
||||
list_free( LIST *head )
|
||||
list_free( LIST *head )
|
||||
{
|
||||
/* Just tack onto freelist. */
|
||||
/* Just tack onto freelist. */
|
||||
|
||||
if( head )
|
||||
{
|
||||
head->tail->next = freelist;
|
||||
freelist = head;
|
||||
}
|
||||
if( head )
|
||||
{
|
||||
head->tail->next = freelist;
|
||||
freelist = head;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -226,12 +226,12 @@ list_print( LIST *l )
|
||||
int
|
||||
list_length( LIST *l )
|
||||
{
|
||||
int n = 0;
|
||||
int n = 0;
|
||||
|
||||
for( ; l; l = list_next( l ), ++n )
|
||||
;
|
||||
for( ; l; l = list_next( l ), ++n )
|
||||
;
|
||||
|
||||
return n;
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -277,11 +277,11 @@ lol_init( LOL *lol )
|
||||
|
||||
void
|
||||
lol_add(
|
||||
LOL *lol,
|
||||
LIST *l )
|
||||
LOL *lol,
|
||||
LIST *l )
|
||||
{
|
||||
if( lol->count < LOL_MAX )
|
||||
lol->list[ lol->count++ ] = l;
|
||||
if( lol->count < LOL_MAX )
|
||||
lol->list[ lol->count++ ] = l;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -291,12 +291,12 @@ lol_add(
|
||||
void
|
||||
lol_free( LOL *lol )
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < lol->count; i++ )
|
||||
list_free( lol->list[i] );
|
||||
for( i = 0; i < lol->count; i++ )
|
||||
list_free( lol->list[i] );
|
||||
|
||||
lol->count = 0;
|
||||
lol->count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -305,10 +305,10 @@ lol_free( LOL *lol )
|
||||
|
||||
LIST *
|
||||
lol_get(
|
||||
LOL *lol,
|
||||
int i )
|
||||
LOL *lol,
|
||||
int i )
|
||||
{
|
||||
return i < lol->count ? lol->list[i] : 0;
|
||||
return i < lol->count ? lol->list[i] : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -318,12 +318,12 @@ lol_get(
|
||||
void
|
||||
lol_print( LOL *lol )
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < lol->count; i++ )
|
||||
{
|
||||
if( i )
|
||||
printf( " : " );
|
||||
list_print( lol->list[i] );
|
||||
}
|
||||
for( i = 0; i < lol->count; i++ )
|
||||
{
|
||||
if( i )
|
||||
printf( " : " );
|
||||
list_print( lol->list[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,24 +19,24 @@
|
||||
*
|
||||
* Structures defined:
|
||||
*
|
||||
* LIST - list of strings
|
||||
* LOL - list of LISTs
|
||||
* LIST - list of strings
|
||||
* LOL - list of LISTs
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* list_append() - append a list onto another one, returning total
|
||||
* list_new() - tack a string onto the end of a list of strings
|
||||
* list_copy() - copy a whole list of strings
|
||||
* list_sublist() - copy a subset of a list of strings
|
||||
* list_free() - free a list of strings
|
||||
* list_print() - print a list of strings to stdout
|
||||
* list_length() - return the number of items in the list
|
||||
* list_append() - append a list onto another one, returning total
|
||||
* list_new() - tack a string onto the end of a list of strings
|
||||
* list_copy() - copy a whole list of strings
|
||||
* list_sublist() - copy a subset of a list of strings
|
||||
* list_free() - free a list of strings
|
||||
* list_print() - print a list of strings to stdout
|
||||
* list_length() - return the number of items in the list
|
||||
*
|
||||
* lol_init() - initialize a LOL (list of lists)
|
||||
* lol_add() - append a LIST onto an LOL
|
||||
* lol_free() - free the LOL and its LISTs
|
||||
* lol_get() - return one of the LISTs in the LOL
|
||||
* lol_print() - debug print LISTS separated by ":"
|
||||
* lol_init() - initialize a LOL (list of lists)
|
||||
* lol_add() - append a LIST onto an LOL
|
||||
* lol_free() - free the LOL and its LISTs
|
||||
* lol_get() - return one of the LISTs in the LOL
|
||||
* lol_print() - debug print LISTS separated by ":"
|
||||
*
|
||||
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
|
||||
* 08/23/94 (seiwald) - new list_append()
|
||||
@@ -52,9 +52,9 @@
|
||||
typedef struct _list LIST;
|
||||
|
||||
struct _list {
|
||||
LIST *next;
|
||||
LIST *tail; /* only valid in head node */
|
||||
char *string; /* private copy */
|
||||
LIST *next;
|
||||
LIST *tail; /* only valid in head node */
|
||||
char *string; /* private copy */
|
||||
} ;
|
||||
|
||||
/*
|
||||
@@ -66,17 +66,17 @@ typedef struct _lol LOL;
|
||||
# define LOL_MAX 9
|
||||
|
||||
struct _lol {
|
||||
int count;
|
||||
LIST *list[ LOL_MAX ];
|
||||
int count;
|
||||
LIST *list[ LOL_MAX ];
|
||||
} ;
|
||||
|
||||
LIST * list_append( LIST *l, LIST *nl );
|
||||
LIST * list_copy( LIST *l, LIST *nl );
|
||||
void list_free( LIST *head );
|
||||
LIST * list_new( LIST *head, char *string );
|
||||
void list_print( LIST *l );
|
||||
int list_length( LIST *l );
|
||||
LIST * list_sublist( LIST *l, int start, int count );
|
||||
LIST * list_append( LIST *l, LIST *nl );
|
||||
LIST * list_copy( LIST *l, LIST *nl );
|
||||
void list_free( LIST *head );
|
||||
LIST * list_new( LIST *head, char *string );
|
||||
void list_print( LIST *l );
|
||||
int list_length( LIST *l );
|
||||
LIST * list_sublist( LIST *l, int start, int count );
|
||||
LIST * list_pop_front( LIST *l );
|
||||
LIST * list_sort( LIST *l);
|
||||
LIST * list_unique( LIST *sorted_list);
|
||||
@@ -86,11 +86,11 @@ int list_in(LIST* l, char* value);
|
||||
|
||||
# define L0 ((LIST *)0)
|
||||
|
||||
void lol_add( LOL *lol, LIST *l );
|
||||
void lol_init( LOL *lol );
|
||||
void lol_free( LOL *lol );
|
||||
LIST * lol_get( LOL *lol, int i );
|
||||
void lol_print( LOL *lol );
|
||||
void lol_add( LOL *lol, LIST *l );
|
||||
void lol_init( LOL *lol );
|
||||
void lol_free( LOL *lol );
|
||||
LIST * lol_get( LOL *lol, int i );
|
||||
void lol_print( LOL *lol );
|
||||
void lol_build( LOL* lol, char** elements );
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,16 +14,16 @@ int make( int n_targets, const char **targets, int anyhow );
|
||||
int make1( TARGET *t );
|
||||
|
||||
typedef struct {
|
||||
int temp;
|
||||
int updating;
|
||||
int cantfind;
|
||||
int cantmake;
|
||||
int targets;
|
||||
int made;
|
||||
int temp;
|
||||
int updating;
|
||||
int cantfind;
|
||||
int cantmake;
|
||||
int targets;
|
||||
int made;
|
||||
} COUNTS ;
|
||||
|
||||
|
||||
void make0( TARGET *t, TARGET *p, int depth,
|
||||
void make0( TARGET *t, TARGET *p, int depth,
|
||||
COUNTS *counts, int anyhow );
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ void make0( TARGET *t, TARGET *p, int depth,
|
||||
* Specifies that the target should be updated.
|
||||
*/
|
||||
void mark_target_for_updating(char *target);
|
||||
/*
|
||||
/*
|
||||
* Returns the list of all the target previously passed to 'mark_target_for_updating'.
|
||||
*/
|
||||
LIST *targets_to_update();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
#define ATOMIC_UNCOLLECTABLE
|
||||
#define NO_EXECUTE_PERMISSION
|
||||
#define ALL_INTERIOR_POINTERS
|
||||
|
||||
|
||||
#define LARGE_CONFIG
|
||||
/*
|
||||
#define NO_SIGNALS
|
||||
@@ -25,11 +25,11 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef GC_DEBUG
|
||||
#define NO_DEBUGGING
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
|
||||
|
||||
#include "boehm_gc/reclaim.c"
|
||||
#include "boehm_gc/allchblk.c"
|
||||
#include "boehm_gc/misc.c"
|
||||
@@ -60,7 +60,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include "boehm_gc/gc_dlopen.c"
|
||||
#include "boehm_gc/backgraph.c"
|
||||
#include "boehm_gc/win32_threads.c"
|
||||
|
||||
|
||||
/* Needs to be last. */
|
||||
#include "boehm_gc/finalize.c"
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
#define bjam_calloc_raw_x(n,s) calloc(n,s)
|
||||
#define bjam_realloc_raw_x(p,s) realloc(p,s)
|
||||
#define bjam_free_raw_x(p) free(p)
|
||||
|
||||
|
||||
#ifndef BJAM_NEWSTR_NO_ALLOCATE
|
||||
#define BJAM_NEWSTR_NO_ALLOCATE
|
||||
#endif
|
||||
@@ -54,7 +54,7 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
#define bjam_calloc_x(n,s) calloc(n,s)
|
||||
#define bjam_realloc_x(p,s) realloc(p,s)
|
||||
#define bjam_free_x(p) free(p)
|
||||
|
||||
|
||||
#ifndef BJAM_NEWSTR_NO_ALLOCATE
|
||||
#define BJAM_NEWSTR_NO_ALLOCATE
|
||||
#endif
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
*
|
||||
* Results look like this:
|
||||
*
|
||||
* char *jambase[] = {
|
||||
* "...\n",
|
||||
* ...
|
||||
* 0 };
|
||||
* char *jambase[] = {
|
||||
* "...\n",
|
||||
* ...
|
||||
* 0 };
|
||||
*
|
||||
* Handles \'s and "'s specially; knows to delete blank and comment lines.
|
||||
*
|
||||
@@ -31,101 +31,101 @@
|
||||
|
||||
int main( int argc, char **argv, char **envp )
|
||||
{
|
||||
char buf[ 1024 ];
|
||||
FILE *fin;
|
||||
FILE *fout;
|
||||
char *p;
|
||||
int doDotC = 0;
|
||||
char buf[ 1024 ];
|
||||
FILE *fin;
|
||||
FILE *fout;
|
||||
char *p;
|
||||
int doDotC = 0;
|
||||
|
||||
if( argc < 3 )
|
||||
{
|
||||
fprintf( stderr, "usage: %s jambase.c Jambase ...\n", argv[0] );
|
||||
return -1;
|
||||
}
|
||||
if( argc < 3 )
|
||||
{
|
||||
fprintf( stderr, "usage: %s jambase.c Jambase ...\n", argv[0] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !( fout = fopen( argv[1], "w" ) ) )
|
||||
{
|
||||
perror( argv[1] );
|
||||
return -1;
|
||||
}
|
||||
if( !( fout = fopen( argv[1], "w" ) ) )
|
||||
{
|
||||
perror( argv[1] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If the file ends in .c generate a C source file */
|
||||
/* If the file ends in .c generate a C source file */
|
||||
|
||||
if( ( p = strrchr( argv[1], '.' ) ) && !strcmp( p, ".c" ) )
|
||||
doDotC++;
|
||||
if( ( p = strrchr( argv[1], '.' ) ) && !strcmp( p, ".c" ) )
|
||||
doDotC++;
|
||||
|
||||
/* Now process the files */
|
||||
/* Now process the files */
|
||||
|
||||
argc -= 2, argv += 2;
|
||||
argc -= 2, argv += 2;
|
||||
|
||||
if( doDotC )
|
||||
{
|
||||
fprintf( fout, "/* Generated by mkjambase from Jambase */\n" );
|
||||
fprintf( fout, "char *jambase[] = {\n" );
|
||||
}
|
||||
if( doDotC )
|
||||
{
|
||||
fprintf( fout, "/* Generated by mkjambase from Jambase */\n" );
|
||||
fprintf( fout, "char *jambase[] = {\n" );
|
||||
}
|
||||
|
||||
for( ; argc--; argv++ )
|
||||
{
|
||||
if( !( fin = fopen( *argv, "r" ) ) )
|
||||
{
|
||||
perror( *argv );
|
||||
return -1;
|
||||
}
|
||||
for( ; argc--; argv++ )
|
||||
{
|
||||
if( !( fin = fopen( *argv, "r" ) ) )
|
||||
{
|
||||
perror( *argv );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( doDotC )
|
||||
{
|
||||
fprintf( fout, "/* %s */\n", *argv );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( fout, "### %s ###\n", *argv );
|
||||
}
|
||||
if( doDotC )
|
||||
{
|
||||
fprintf( fout, "/* %s */\n", *argv );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( fout, "### %s ###\n", *argv );
|
||||
}
|
||||
|
||||
while( fgets( buf, sizeof( buf ), fin ) )
|
||||
{
|
||||
if( doDotC )
|
||||
{
|
||||
char *p = buf;
|
||||
while( fgets( buf, sizeof( buf ), fin ) )
|
||||
{
|
||||
if( doDotC )
|
||||
{
|
||||
char *p = buf;
|
||||
|
||||
/* Strip leading whitespace. */
|
||||
/* Strip leading whitespace. */
|
||||
|
||||
while( *p == ' ' || *p == '\t' || *p == '\n' )
|
||||
p++;
|
||||
while( *p == ' ' || *p == '\t' || *p == '\n' )
|
||||
p++;
|
||||
|
||||
/* Drop comments and empty lines. */
|
||||
/* Drop comments and empty lines. */
|
||||
|
||||
if( *p == '#' || !*p )
|
||||
continue;
|
||||
if( *p == '#' || !*p )
|
||||
continue;
|
||||
|
||||
/* Copy */
|
||||
/* Copy */
|
||||
|
||||
putc( '"', fout );
|
||||
putc( '"', fout );
|
||||
|
||||
for( ; *p && *p != '\n'; p++ )
|
||||
switch( *p )
|
||||
{
|
||||
case '\\': putc( '\\', fout ); putc( '\\', fout ); break;
|
||||
case '"': putc( '\\', fout ); putc( '"', fout ); break;
|
||||
for( ; *p && *p != '\n'; p++ )
|
||||
switch( *p )
|
||||
{
|
||||
case '\\': putc( '\\', fout ); putc( '\\', fout ); break;
|
||||
case '"': putc( '\\', fout ); putc( '"', fout ); break;
|
||||
case '\r': break;
|
||||
default: putc( *p, fout ); break;
|
||||
}
|
||||
default: putc( *p, fout ); break;
|
||||
}
|
||||
|
||||
fprintf( fout, "\\n\",\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( fout, "%s", buf );
|
||||
}
|
||||
fprintf( fout, "\\n\",\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( fout, "%s", buf );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fclose( fin );
|
||||
}
|
||||
|
||||
if( doDotC )
|
||||
fprintf( fout, "0 };\n" );
|
||||
fclose( fin );
|
||||
}
|
||||
|
||||
fclose( fout );
|
||||
if( doDotC )
|
||||
fprintf( fout, "0 };\n" );
|
||||
|
||||
return 0;
|
||||
fclose( fout );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
#include "strings.h"
|
||||
#include <assert.h>
|
||||
|
||||
static struct hash* module_hash = 0;
|
||||
static struct hash * module_hash = 0;
|
||||
|
||||
static char* new_module_str( module_t* m, char* suffix )
|
||||
|
||||
static char * new_module_str( module_t * m, char * suffix )
|
||||
{
|
||||
char* result;
|
||||
char * result;
|
||||
string s;
|
||||
string_copy( &s, m->name );
|
||||
string_append( &s, suffix );
|
||||
@@ -29,10 +30,11 @@ static char* new_module_str( module_t* m, char* suffix )
|
||||
return result;
|
||||
}
|
||||
|
||||
module_t* bindmodule( char* name )
|
||||
|
||||
module_t * bindmodule( char * name )
|
||||
{
|
||||
PROFILE_ENTER(BINDMODULE);
|
||||
|
||||
|
||||
string s;
|
||||
module_t m_, *m = &m_;
|
||||
|
||||
@@ -45,9 +47,9 @@ module_t* bindmodule( char* name )
|
||||
string_append( &s, name );
|
||||
string_push_back( &s, '.' );
|
||||
}
|
||||
|
||||
|
||||
m->name = s.value;
|
||||
|
||||
|
||||
if ( hashenter( module_hash, (HASHDATA **)&m ) )
|
||||
{
|
||||
m->name = newstr( m->name );
|
||||
@@ -115,46 +117,47 @@ void enter_module( module_t* m )
|
||||
var_hash_swap( &m->variables );
|
||||
}
|
||||
|
||||
void exit_module( module_t* m )
|
||||
|
||||
void exit_module( module_t * m )
|
||||
{
|
||||
var_hash_swap( &m->variables );
|
||||
}
|
||||
|
||||
void import_module(LIST* module_names, module_t* target_module)
|
||||
|
||||
void import_module( LIST * module_names, module_t * target_module )
|
||||
{
|
||||
PROFILE_ENTER(IMPORT_MODULE);
|
||||
|
||||
struct hash* h;
|
||||
|
||||
if (!target_module->imported_modules)
|
||||
target_module->imported_modules = hashinit( sizeof(char*), "imported");
|
||||
|
||||
struct hash * h;
|
||||
|
||||
if ( !target_module->imported_modules )
|
||||
target_module->imported_modules = hashinit( sizeof( char * ), "imported" );
|
||||
h = target_module->imported_modules;
|
||||
|
||||
for(;module_names; module_names = module_names->next) {
|
||||
|
||||
char* s = module_names->string;
|
||||
char** ss = &s;
|
||||
|
||||
hashenter(h, (HASHDATA**)&ss);
|
||||
for ( ; module_names; module_names = module_names->next )
|
||||
{
|
||||
char * s = module_names->string;
|
||||
char * * ss = &s;
|
||||
hashenter( h, (HASHDATA * *)&ss );
|
||||
}
|
||||
|
||||
|
||||
PROFILE_EXIT(IMPORT_MODULE);
|
||||
}
|
||||
|
||||
static void add_module_name( void* r_, void* result_ )
|
||||
|
||||
static void add_module_name( void * r_, void * result_ )
|
||||
{
|
||||
char** r = (char**)r_;
|
||||
LIST** result = (LIST**)result_;
|
||||
char * * r = (char * *)r_;
|
||||
LIST * * result = (LIST * *)result_;
|
||||
|
||||
*result = list_new( *result, copystr( *r ) );
|
||||
}
|
||||
|
||||
LIST* imported_modules(module_t* module)
|
||||
{
|
||||
LIST *result = L0;
|
||||
|
||||
LIST * imported_modules( module_t * module )
|
||||
{
|
||||
LIST * result = L0;
|
||||
if ( module->imported_modules )
|
||||
hashenumerate( module->imported_modules, add_module_name, &result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ struct native_rule_t
|
||||
};
|
||||
|
||||
/* MSVC debugger gets confused unless this is provided */
|
||||
typedef struct native_rule_t native_rule_t ;
|
||||
typedef struct native_rule_t native_rule_t ;
|
||||
|
||||
void declare_native_rule(char* module, char* rule, char** args,
|
||||
void declare_native_rule(char* module, char* rule, char** args,
|
||||
LIST*(*f)(PARSE*, FRAME*), int version);
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
*
|
||||
* Once a string is passed to newstr(), the returned string is readonly.
|
||||
*
|
||||
* This implementation builds a hash table of all strings, so that multiple
|
||||
* This implementation builds a hash table of all strings, so that multiple
|
||||
* calls of newstr() on the same string allocate memory for the string once.
|
||||
* Strings are never actually freed.
|
||||
*/
|
||||
@@ -104,25 +104,25 @@ static char* allocate(size_t n)
|
||||
char *
|
||||
newstr( char *string )
|
||||
{
|
||||
STRING str, *s = &str;
|
||||
STRING str, *s = &str;
|
||||
|
||||
if( !strhash )
|
||||
strhash = hashinit( sizeof( STRING ), "strings" );
|
||||
if( !strhash )
|
||||
strhash = hashinit( sizeof( STRING ), "strings" );
|
||||
|
||||
*s = string;
|
||||
*s = string;
|
||||
|
||||
if( hashenter( strhash, (HASHDATA **)&s ) )
|
||||
{
|
||||
int l = strlen( string );
|
||||
char *m = (char *)allocate( l + 1 );
|
||||
if( hashenter( strhash, (HASHDATA **)&s ) )
|
||||
{
|
||||
int l = strlen( string );
|
||||
char *m = (char *)allocate( l + 1 );
|
||||
|
||||
strtotal += l + 1;
|
||||
memcpy( m, string, l + 1 );
|
||||
*s = m;
|
||||
}
|
||||
strtotal += l + 1;
|
||||
memcpy( m, string, l + 1 );
|
||||
*s = m;
|
||||
}
|
||||
|
||||
strcount_in += 1;
|
||||
return *s;
|
||||
return *s;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -133,7 +133,7 @@ char *
|
||||
copystr( char *s )
|
||||
{
|
||||
strcount_in += 1;
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -160,11 +160,11 @@ donestr()
|
||||
BJAM_FREE(strblock_chain);
|
||||
strblock_chain = n;
|
||||
}
|
||||
|
||||
|
||||
hashdone( strhash );
|
||||
|
||||
|
||||
if( DEBUG_MEM )
|
||||
printf( "%dK in strings\n", strtotal / 1024 );
|
||||
|
||||
|
||||
/* printf( "--- %d strings of %d dangling\n", strcount_in-strcount_out, strcount_in ); */
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
*
|
||||
* {o >o
|
||||
* \<>) "Process command line options as defined in <option.h>.
|
||||
* Return the number of argv[] elements used up by options,
|
||||
* or -1 if an invalid option flag was given or an argument
|
||||
* was supplied for an option that does not require one."
|
||||
* Return the number of argv[] elements used up by options,
|
||||
* or -1 if an invalid option flag was given or an argument
|
||||
* was supplied for an option that does not require one."
|
||||
*/
|
||||
|
||||
int
|
||||
@@ -31,73 +31,68 @@ getoptions(
|
||||
|
||||
for( i = 0; i < argc; i++ )
|
||||
{
|
||||
char *arg;
|
||||
char *arg;
|
||||
|
||||
if( argv[i][0] != '-' || ( argv[i][1] != '-' && !isalpha( argv[i][1] ) ) )
|
||||
continue;
|
||||
if( argv[i][0] != '-' || ( argv[i][1] != '-' && !isalpha( argv[i][1] ) ) )
|
||||
continue;
|
||||
|
||||
if( !optc-- )
|
||||
{
|
||||
printf( "too many options (%d max)\n", N_OPTS );
|
||||
return -1;
|
||||
}
|
||||
if( !optc-- )
|
||||
{
|
||||
printf( "too many options (%d max)\n", N_OPTS );
|
||||
return -1;
|
||||
}
|
||||
|
||||
for( arg = &argv[i][1]; *arg; arg++ )
|
||||
{
|
||||
char *f;
|
||||
for( arg = &argv[i][1]; *arg; arg++ )
|
||||
{
|
||||
char *f;
|
||||
|
||||
for( f = opts; *f; f++ )
|
||||
if( *f == *arg )
|
||||
break;
|
||||
for( f = opts; *f; f++ )
|
||||
if( *f == *arg )
|
||||
break;
|
||||
|
||||
if( !*f )
|
||||
{
|
||||
printf( "Invalid option: -%c\n", *arg );
|
||||
return -1;
|
||||
}
|
||||
if( !*f )
|
||||
{
|
||||
printf( "Invalid option: -%c\n", *arg );
|
||||
return -1;
|
||||
}
|
||||
|
||||
optv->flag = *f;
|
||||
optv->flag = *f;
|
||||
|
||||
if( f[1] != ':' )
|
||||
{
|
||||
optv++->val = "true";
|
||||
}
|
||||
else if( arg[1] )
|
||||
{
|
||||
optv++->val = &arg[1];
|
||||
break;
|
||||
}
|
||||
else if( ++i < argc )
|
||||
{
|
||||
optv++->val = argv[i];
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "option: -%c needs argument\n", *f );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if( f[1] != ':' )
|
||||
{
|
||||
optv++->val = "true";
|
||||
}
|
||||
else if( arg[1] )
|
||||
{
|
||||
optv++->val = &arg[1];
|
||||
break;
|
||||
}
|
||||
else if( ++i < argc )
|
||||
{
|
||||
optv++->val = argv[i];
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "option: -%c needs argument\n", *f );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Name: getoptval() - find an option given its character
|
||||
* Name: getoptval() - find an option given its character.
|
||||
*/
|
||||
|
||||
char *
|
||||
getoptval(
|
||||
option *optv,
|
||||
char opt,
|
||||
int subopt )
|
||||
char * getoptval( option * optv, char opt, int subopt )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < N_OPTS; i++, optv++ )
|
||||
if( optv->flag == opt && !subopt-- )
|
||||
return optv->val;
|
||||
|
||||
return 0;
|
||||
int i;
|
||||
for ( i = 0; i < N_OPTS; ++i, ++optv )
|
||||
if ( ( optv->flag == opt ) && !subopt-- )
|
||||
return optv->val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
|
||||
typedef struct option
|
||||
{
|
||||
char flag; /* filled in by getoption() */
|
||||
char *val; /* set to random address if true */
|
||||
char flag; /* filled in by getoption() */
|
||||
char *val; /* set to random address if true */
|
||||
} option;
|
||||
|
||||
# define N_OPTS 256
|
||||
|
||||
int getoptions( int argc, char **argv, char *opts, option *optv );
|
||||
char * getoptval( option *optv, char opt, int subopt );
|
||||
int getoptions( int argc, char **argv, char *opts, option *optv );
|
||||
char * getoptval( option *optv, char opt, int subopt );
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
Copyright 2007 Rene Rivera
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -12,10 +12,11 @@
|
||||
#define bjam_out (stdout)
|
||||
#define bjam_err (stderr)
|
||||
|
||||
static void out_(
|
||||
const char * data,
|
||||
FILE * io
|
||||
)
|
||||
static void out_
|
||||
(
|
||||
char const * data,
|
||||
FILE * io
|
||||
)
|
||||
{
|
||||
while ( *data )
|
||||
{
|
||||
@@ -26,36 +27,39 @@ static void out_(
|
||||
}
|
||||
}
|
||||
|
||||
void out_action(
|
||||
const char * action,
|
||||
const char * target,
|
||||
const char * command,
|
||||
const char * out_data,
|
||||
const char * err_data,
|
||||
int exit_reason
|
||||
)
|
||||
|
||||
void out_action
|
||||
(
|
||||
char const * action,
|
||||
char const * target,
|
||||
char const * command,
|
||||
char const * out_data,
|
||||
char const * err_data,
|
||||
int exit_reason
|
||||
)
|
||||
{
|
||||
/* print out the action+target line, if the action is quite
|
||||
the action should be null. */
|
||||
/* Print out the action+target line, if the action is quite the action
|
||||
* should be null.
|
||||
*/
|
||||
if ( action )
|
||||
{
|
||||
fprintf(bjam_out,"%s %s\n",action,target);
|
||||
}
|
||||
|
||||
/* print out the command executed if given -d+2 */
|
||||
if ( DEBUG_EXEC )
|
||||
{
|
||||
fputs(command,bjam_out);
|
||||
fputc('\n',bjam_out);
|
||||
}
|
||||
|
||||
/* print out the command executed to the command stream */
|
||||
if ( globs.cmdout )
|
||||
{
|
||||
fputs(command,globs.cmdout);
|
||||
fprintf( bjam_out, "%s %s\n", action, target );
|
||||
}
|
||||
|
||||
switch (exit_reason)
|
||||
/* Print out the command executed if given -d+2. */
|
||||
if ( DEBUG_EXEC )
|
||||
{
|
||||
fputs( command, bjam_out );
|
||||
fputc( '\n', bjam_out );
|
||||
}
|
||||
|
||||
/* Print out the command executed to the command stream. */
|
||||
if ( globs.cmdout )
|
||||
{
|
||||
fputs( command, globs.cmdout );
|
||||
}
|
||||
|
||||
switch ( exit_reason )
|
||||
{
|
||||
case EXIT_OK:
|
||||
break;
|
||||
@@ -63,59 +67,60 @@ void out_action(
|
||||
break;
|
||||
case EXIT_TIMEOUT:
|
||||
{
|
||||
/* process expired, make user aware with explicit message */
|
||||
/* Process expired, make user aware with explicit message. */
|
||||
if ( action )
|
||||
{
|
||||
/* but only output for non-quietly actions */
|
||||
fprintf(bjam_out, "%d second time limit exceeded\n", globs.timeout);
|
||||
/* But only output for non-quietly actions. */
|
||||
fprintf( bjam_out, "%d second time limit exceeded\n", globs.timeout );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* print out the command output, if requested */
|
||||
|
||||
/* Print out the command output, if requested. */
|
||||
if ( action )
|
||||
{
|
||||
/* but only output for non-quietly actions */
|
||||
if (0 != out_data &&
|
||||
( globs.pipe_action & 1 /* STDOUT_FILENO */ ||
|
||||
globs.pipe_action == 0))
|
||||
/* But only output for non-quietly actions. */
|
||||
if ( ( 0 != out_data ) &&
|
||||
( ( globs.pipe_action & 1 /* STDOUT_FILENO */ ) ||
|
||||
( globs.pipe_action == 0 ) ) )
|
||||
{
|
||||
out_(out_data,bjam_out);
|
||||
out_( out_data, bjam_out );
|
||||
}
|
||||
if (0 != err_data &&
|
||||
globs.pipe_action & 2 /* STDERR_FILENO */)
|
||||
if ( ( 0 != err_data ) &&
|
||||
( globs.pipe_action & 2 /* STDERR_FILENO */ ) )
|
||||
{
|
||||
out_(err_data,bjam_err);
|
||||
out_( err_data, bjam_err );
|
||||
}
|
||||
}
|
||||
|
||||
fflush(bjam_out);
|
||||
fflush(bjam_err);
|
||||
fflush(globs.cmdout);
|
||||
|
||||
fflush( bjam_out );
|
||||
fflush( bjam_err );
|
||||
fflush( globs.cmdout );
|
||||
}
|
||||
|
||||
|
||||
char * outf_int( int value )
|
||||
{
|
||||
char buffer[50];
|
||||
sprintf(buffer, "%i", value);
|
||||
return newstr(buffer);
|
||||
sprintf( buffer, "%i", value );
|
||||
return newstr( buffer );
|
||||
}
|
||||
|
||||
|
||||
char * outf_double( double value )
|
||||
{
|
||||
char buffer[50];
|
||||
sprintf(buffer, "%f", value);
|
||||
return newstr(buffer);
|
||||
sprintf( buffer, "%f", value );
|
||||
return newstr( buffer );
|
||||
}
|
||||
|
||||
|
||||
char * outf_time( time_t value )
|
||||
{
|
||||
char buffer[50];
|
||||
strftime(buffer,49,"%Y-%m-%d %H:%M:%SZ",gmtime(&value));
|
||||
return newstr(buffer);
|
||||
strftime( buffer, 49, "%Y-%m-%d %H:%M:%SZ", gmtime( &value ) );
|
||||
return newstr( buffer );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
Copyright 2007 Rene Rivera
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
* parse.c - make and destroy parse trees as driven by the parser
|
||||
*
|
||||
* 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used,
|
||||
* as per Matt Armstrong.
|
||||
* as per Matt Armstrong.
|
||||
* 09/11/00 (seiwald) - structure reworked to reflect that (*func)()
|
||||
* returns a LIST *.
|
||||
* returns a LIST *.
|
||||
*/
|
||||
|
||||
static PARSE *yypsave;
|
||||
@@ -32,63 +32,63 @@ static PARSE *yypsave;
|
||||
void
|
||||
parse_file( char *f, FRAME* frame )
|
||||
{
|
||||
/* Suspend scan of current file */
|
||||
/* and push this new file in the stream */
|
||||
/* Suspend scan of current file */
|
||||
/* and push this new file in the stream */
|
||||
|
||||
yyfparse(f);
|
||||
yyfparse(f);
|
||||
|
||||
/* Now parse each block of rules and execute it. */
|
||||
/* Execute it outside of the parser so that recursive */
|
||||
/* calls to yyrun() work (no recursive yyparse's). */
|
||||
/* Now parse each block of rules and execute it. */
|
||||
/* Execute it outside of the parser so that recursive */
|
||||
/* calls to yyrun() work (no recursive yyparse's). */
|
||||
|
||||
for(;;)
|
||||
{
|
||||
PARSE *p;
|
||||
for(;;)
|
||||
{
|
||||
PARSE *p;
|
||||
|
||||
/* Filled by yyparse() calling parse_save() */
|
||||
/* Filled by yyparse() calling parse_save() */
|
||||
|
||||
yypsave = 0;
|
||||
yypsave = 0;
|
||||
|
||||
/* If parse error or empty parse, outta here */
|
||||
/* If parse error or empty parse, outta here */
|
||||
|
||||
if( yyparse() || !( p = yypsave ) )
|
||||
break;
|
||||
if( yyparse() || !( p = yypsave ) )
|
||||
break;
|
||||
|
||||
/* Run the parse tree. */
|
||||
/* Run the parse tree. */
|
||||
|
||||
parse_evaluate( p, frame );
|
||||
parse_free( p );
|
||||
}
|
||||
parse_free( p );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parse_save( PARSE *p )
|
||||
{
|
||||
yypsave = p;
|
||||
yypsave = p;
|
||||
}
|
||||
|
||||
PARSE *
|
||||
parse_make(
|
||||
LIST *(*func)( PARSE *p, FRAME *args ),
|
||||
PARSE *left,
|
||||
PARSE *right,
|
||||
PARSE *third,
|
||||
char *string,
|
||||
char *string1,
|
||||
int num )
|
||||
{
|
||||
PARSE *p = (PARSE *)BJAM_MALLOC( sizeof( PARSE ) );
|
||||
|
||||
p->func = func;
|
||||
p->left = left;
|
||||
p->right = right;
|
||||
p->third = third;
|
||||
p->string = string;
|
||||
p->string1 = string1;
|
||||
p->num = num;
|
||||
p->refs = 1;
|
||||
PARSE * parse_make(
|
||||
LIST *(*func)( PARSE *p, FRAME *args ),
|
||||
PARSE *left,
|
||||
PARSE *right,
|
||||
PARSE *third,
|
||||
char *string,
|
||||
char *string1,
|
||||
int num )
|
||||
{
|
||||
PARSE *p = (PARSE *)BJAM_MALLOC( sizeof( PARSE ) );
|
||||
|
||||
p->func = func;
|
||||
p->left = left;
|
||||
p->right = right;
|
||||
p->third = third;
|
||||
p->string = string;
|
||||
p->string1 = string1;
|
||||
p->num = num;
|
||||
p->refs = 1;
|
||||
p->rulename = 0;
|
||||
|
||||
|
||||
if ( left )
|
||||
{
|
||||
p->file = left->file;
|
||||
@@ -99,39 +99,40 @@ parse_make(
|
||||
yyinput_stream( &p->file, &p->line );
|
||||
}
|
||||
|
||||
return p;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
parse_refer( PARSE *p )
|
||||
{
|
||||
++p->refs;
|
||||
++p->refs;
|
||||
}
|
||||
|
||||
void
|
||||
parse_free( PARSE *p )
|
||||
|
||||
void parse_free( PARSE * p )
|
||||
{
|
||||
if( --p->refs )
|
||||
return;
|
||||
if ( --p->refs )
|
||||
return;
|
||||
|
||||
if( p->string )
|
||||
freestr( p->string );
|
||||
if( p->string1 )
|
||||
freestr( p->string1 );
|
||||
if( p->left )
|
||||
parse_free( p->left );
|
||||
if( p->right )
|
||||
parse_free( p->right );
|
||||
if( p->third )
|
||||
parse_free( p->third );
|
||||
if ( p->rulename )
|
||||
freestr( p->rulename );
|
||||
|
||||
BJAM_FREE( (char *)p );
|
||||
if ( p->string )
|
||||
freestr( p->string );
|
||||
if ( p->string1 )
|
||||
freestr( p->string1 );
|
||||
if ( p->left )
|
||||
parse_free( p->left );
|
||||
if ( p->right )
|
||||
parse_free( p->right );
|
||||
if ( p->third )
|
||||
parse_free( p->third );
|
||||
if ( p->rulename )
|
||||
freestr( p->rulename );
|
||||
|
||||
BJAM_FREE( (char *)p );
|
||||
}
|
||||
|
||||
LIST* parse_evaluate( PARSE *p, FRAME* frame )
|
||||
|
||||
LIST * parse_evaluate( PARSE * p, FRAME * frame )
|
||||
{
|
||||
frame->procedure = p;
|
||||
return (*p->func)(p, frame);
|
||||
return (*p->func)( p, frame );
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ struct _PARSE {
|
||||
void parse_file( char *f, FRAME* frame );
|
||||
void parse_save( PARSE *p );
|
||||
|
||||
PARSE * parse_make(
|
||||
PARSE * parse_make(
|
||||
LIST *(*func)( PARSE *p, FRAME* frame ),
|
||||
PARSE *left,
|
||||
PARSE *right,
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* path_parse() - split a file name into dir/base/suffix/member
|
||||
* path_build() - build a filename given dir/base/suffix/member
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
* path_parse() - split a file name into dir/base/suffix/member
|
||||
* path_build() - build a filename given dir/base/suffix/member
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
*
|
||||
* File_parse() and path_build() just manipuate a string and a structure;
|
||||
* they do not make system calls.
|
||||
@@ -41,10 +41,10 @@
|
||||
* 03/16/95 (seiwald) - fixed accursed typo on line 69.
|
||||
* 05/03/96 (seiwald) - split from filent.c, fileunix.c
|
||||
* 12/20/96 (seiwald) - when looking for the rightmost . in a file name,
|
||||
* don't include the archive member name.
|
||||
* don't include the archive member name.
|
||||
* 01/10/01 (seiwald) - path_parse now strips the trailing : from the
|
||||
* directory name, unless the directory name is all
|
||||
* :'s, so that $(d:P) works.
|
||||
* directory name, unless the directory name is all
|
||||
* :'s, so that $(d:P) works.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -52,131 +52,131 @@
|
||||
*/
|
||||
|
||||
void
|
||||
path_parse(
|
||||
char *file,
|
||||
PATHNAME *f )
|
||||
path_parse(
|
||||
char *file,
|
||||
PATHNAME *f )
|
||||
{
|
||||
char *p, *q;
|
||||
char *end;
|
||||
|
||||
memset( (char *)f, 0, sizeof( *f ) );
|
||||
char *p, *q;
|
||||
char *end;
|
||||
|
||||
/* Look for <grist> */
|
||||
memset( (char *)f, 0, sizeof( *f ) );
|
||||
|
||||
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
|
||||
{
|
||||
f->f_grist.ptr = file;
|
||||
f->f_grist.len = p - file;
|
||||
file = p + 1;
|
||||
}
|
||||
/* Look for <grist> */
|
||||
|
||||
/* Look for dir: */
|
||||
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
|
||||
{
|
||||
f->f_grist.ptr = file;
|
||||
f->f_grist.len = p - file;
|
||||
file = p + 1;
|
||||
}
|
||||
|
||||
if( p = strrchr( file, DELIM ) )
|
||||
{
|
||||
f->f_dir.ptr = file;
|
||||
f->f_dir.len = p - file;
|
||||
file = p + 1;
|
||||
/* Look for dir: */
|
||||
|
||||
/* All :'s? Include last : as part of directory name */
|
||||
if( p = strrchr( file, DELIM ) )
|
||||
{
|
||||
f->f_dir.ptr = file;
|
||||
f->f_dir.len = p - file;
|
||||
file = p + 1;
|
||||
|
||||
while( p > f->f_dir.ptr && *--p == DELIM )
|
||||
;
|
||||
|
||||
if( p == f->f_dir.ptr )
|
||||
f->f_dir.len++;
|
||||
}
|
||||
/* All :'s? Include last : as part of directory name */
|
||||
|
||||
end = file + strlen( file );
|
||||
while( p > f->f_dir.ptr && *--p == DELIM )
|
||||
;
|
||||
|
||||
/* Look for (member) */
|
||||
if( p == f->f_dir.ptr )
|
||||
f->f_dir.len++;
|
||||
}
|
||||
|
||||
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
|
||||
{
|
||||
f->f_member.ptr = p + 1;
|
||||
f->f_member.len = end - p - 2;
|
||||
end = p;
|
||||
}
|
||||
end = file + strlen( file );
|
||||
|
||||
/* Look for .suffix */
|
||||
/* This would be memrchr() */
|
||||
/* Look for (member) */
|
||||
|
||||
p = 0;
|
||||
q = file;
|
||||
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
|
||||
{
|
||||
f->f_member.ptr = p + 1;
|
||||
f->f_member.len = end - p - 2;
|
||||
end = p;
|
||||
}
|
||||
|
||||
while( q = memchr( q, '.', end - q ) )
|
||||
p = q++;
|
||||
/* Look for .suffix */
|
||||
/* This would be memrchr() */
|
||||
|
||||
if( p )
|
||||
{
|
||||
f->f_suffix.ptr = p;
|
||||
f->f_suffix.len = end - p;
|
||||
end = p;
|
||||
}
|
||||
p = 0;
|
||||
q = file;
|
||||
|
||||
/* Leaves base */
|
||||
while( q = memchr( q, '.', end - q ) )
|
||||
p = q++;
|
||||
|
||||
f->f_base.ptr = file;
|
||||
f->f_base.len = end - file;
|
||||
if( p )
|
||||
{
|
||||
f->f_suffix.ptr = p;
|
||||
f->f_suffix.len = end - p;
|
||||
end = p;
|
||||
}
|
||||
|
||||
/* Leaves base */
|
||||
|
||||
f->f_base.ptr = file;
|
||||
f->f_base.len = end - file;
|
||||
}
|
||||
|
||||
/*
|
||||
* path_build() - build a filename given dir/base/suffix/member
|
||||
* path_build() - build a filename given dir/base/suffix/member.
|
||||
*/
|
||||
|
||||
# define DIR_EMPTY 0 /* "" */
|
||||
# define DIR_DOT 1 /* : */
|
||||
# define DIR_DOTDOT 2 /* :: */
|
||||
# define DIR_ABS 3 /* dira:dirb: */
|
||||
# define DIR_REL 4 /* :dira:dirb: */
|
||||
|
||||
# define G_DIR 0 /* take dir */
|
||||
# define G_ROOT 1 /* take root */
|
||||
# define G_CAT 2 /* prepend root to dir */
|
||||
# define G_DTDR 3 /* :: of rel dir */
|
||||
# define G_DDDD 4 /* make it ::: (../..) */
|
||||
# define G_MT 5 /* leave it empty */
|
||||
# define DIR_EMPTY 0 /* "" */
|
||||
# define DIR_DOT 1 /* : */
|
||||
# define DIR_DOTDOT 2 /* :: */
|
||||
# define DIR_ABS 3 /* dira:dirb: */
|
||||
# define DIR_REL 4 /* :dira:dirb: */
|
||||
|
||||
# define G_DIR 0 /* take dir */
|
||||
# define G_ROOT 1 /* take root */
|
||||
# define G_CAT 2 /* prepend root to dir */
|
||||
# define G_DTDR 3 /* :: of rel dir */
|
||||
# define G_DDDD 4 /* make it ::: (../..) */
|
||||
# define G_MT 5 /* leave it empty */
|
||||
|
||||
char grid[5][5] = {
|
||||
/* EMPTY DOT DOTDOT ABS REL */
|
||||
/* EMPTY */ { G_MT, G_DIR, G_DIR, G_DIR, G_DIR },
|
||||
/* DOT */ { G_ROOT, G_DIR, G_DIR, G_DIR, G_DIR },
|
||||
/* DOTDOT */ { G_ROOT, G_ROOT, G_DDDD, G_DIR, G_DTDR },
|
||||
/* ABS */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT },
|
||||
/* REL */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT }
|
||||
/* EMPTY DOT DOTDOT ABS REL */
|
||||
/* EMPTY */ { G_MT, G_DIR, G_DIR, G_DIR, G_DIR },
|
||||
/* DOT */ { G_ROOT, G_DIR, G_DIR, G_DIR, G_DIR },
|
||||
/* DOTDOT */ { G_ROOT, G_ROOT, G_DDDD, G_DIR, G_DTDR },
|
||||
/* ABS */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT },
|
||||
/* REL */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT }
|
||||
} ;
|
||||
|
||||
static int
|
||||
file_flags(
|
||||
char *ptr,
|
||||
int len )
|
||||
file_flags(
|
||||
char *ptr,
|
||||
int len )
|
||||
{
|
||||
if( !len )
|
||||
return DIR_EMPTY;
|
||||
if( len == 1 && ptr[0] == DELIM )
|
||||
return DIR_DOT;
|
||||
if( len == 2 && ptr[0] == DELIM && ptr[1] == DELIM )
|
||||
return DIR_DOTDOT;
|
||||
if( ptr[0] == DELIM )
|
||||
return DIR_REL;
|
||||
return DIR_ABS;
|
||||
if( !len )
|
||||
return DIR_EMPTY;
|
||||
if( len == 1 && ptr[0] == DELIM )
|
||||
return DIR_DOT;
|
||||
if( len == 2 && ptr[0] == DELIM && ptr[1] == DELIM )
|
||||
return DIR_DOTDOT;
|
||||
if( ptr[0] == DELIM )
|
||||
return DIR_REL;
|
||||
return DIR_ABS;
|
||||
}
|
||||
|
||||
void
|
||||
path_build(
|
||||
PATHNAME *f,
|
||||
string* file,
|
||||
int binding )
|
||||
PATHNAME *f,
|
||||
string* file,
|
||||
int binding )
|
||||
{
|
||||
int dflag, rflag, act;
|
||||
|
||||
file_build1( f, file );
|
||||
|
||||
|
||||
/* Combine root & directory, according to the grid. */
|
||||
|
||||
|
||||
dflag = file_flags( f->f_dir.ptr, f->f_dir.len );
|
||||
rflag = file_flags( f->f_root.ptr, f->f_root.len );
|
||||
|
||||
|
||||
switch( act = grid[ rflag ][ dflag ] )
|
||||
{
|
||||
case G_DTDR:
|
||||
@@ -185,35 +185,35 @@ path_build(
|
||||
string_push_back( file, DELIM );
|
||||
}
|
||||
/* fall through */
|
||||
|
||||
case G_DIR:
|
||||
|
||||
case G_DIR:
|
||||
/* take dir */
|
||||
string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len );
|
||||
break;
|
||||
|
||||
case G_ROOT:
|
||||
|
||||
case G_ROOT:
|
||||
/* take root */
|
||||
string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len );
|
||||
break;
|
||||
|
||||
case G_CAT:
|
||||
|
||||
case G_CAT:
|
||||
/* prepend root to dir */
|
||||
string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len );
|
||||
if( file->value[file->size - 1] == DELIM )
|
||||
string_pop_back( file );
|
||||
string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len );
|
||||
break;
|
||||
|
||||
case G_DDDD:
|
||||
|
||||
case G_DDDD:
|
||||
/* make it ::: (../..) */
|
||||
string_append( file, ":::" );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Put : between dir and file (if none already) */
|
||||
|
||||
if( act != G_MT &&
|
||||
file->value[file->size - 1] != DELIM &&
|
||||
|
||||
if( act != G_MT &&
|
||||
file->value[file->size - 1] != DELIM &&
|
||||
( f->f_base.len || f->f_suffix.len ) )
|
||||
{
|
||||
string_push_back( file, DELIM );
|
||||
@@ -235,27 +235,27 @@ path_build(
|
||||
string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len );
|
||||
string_push_back( file, ')' );
|
||||
}
|
||||
|
||||
|
||||
if( DEBUG_SEARCH )
|
||||
printf(" -> '%s'\n", file->value);
|
||||
}
|
||||
|
||||
/*
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
*/
|
||||
|
||||
void
|
||||
path_parent( PATHNAME *f )
|
||||
{
|
||||
/* just set everything else to nothing */
|
||||
/* just set everything else to nothing */
|
||||
|
||||
f->f_base.ptr =
|
||||
f->f_suffix.ptr =
|
||||
f->f_member.ptr = "";
|
||||
f->f_base.ptr =
|
||||
f->f_suffix.ptr =
|
||||
f->f_member.ptr = "";
|
||||
|
||||
f->f_base.len =
|
||||
f->f_suffix.len =
|
||||
f->f_member.len = 0;
|
||||
f->f_base.len =
|
||||
f->f_suffix.len =
|
||||
f->f_member.len = 0;
|
||||
}
|
||||
|
||||
# endif /* OS_MAC */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* pathsys.h - PATHNAME struct
|
||||
* pathsys.h - PATHNAME struct
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* <grist> is salt to distinguish between targets that otherwise would
|
||||
* have the same name: it never appears in the bound name of a target.
|
||||
* (member) is an archive member name: the syntax is arbitrary, but must
|
||||
* (member) is an archive member name: the syntax is arbitrary, but must
|
||||
* agree in path_parse(), path_build() and the Jambase.
|
||||
*
|
||||
* On VMS, we keep track of whether the original path was a directory
|
||||
@@ -29,22 +29,22 @@ typedef struct _pathname PATHNAME;
|
||||
typedef struct _pathpart PATHPART;
|
||||
|
||||
struct _pathpart {
|
||||
char *ptr;
|
||||
int len;
|
||||
char *ptr;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct _pathname {
|
||||
PATHPART part[6];
|
||||
PATHPART part[6];
|
||||
# ifdef OS_VMS
|
||||
int parent;
|
||||
int parent;
|
||||
# endif
|
||||
|
||||
# define f_grist part[0]
|
||||
# define f_root part[1]
|
||||
# define f_dir part[2]
|
||||
# define f_base part[3]
|
||||
# define f_suffix part[4]
|
||||
# define f_member part[5]
|
||||
# define f_grist part[0]
|
||||
# define f_root part[1]
|
||||
# define f_dir part[2]
|
||||
# define f_base part[3]
|
||||
# define f_suffix part[4]
|
||||
# define f_member part[5]
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* path_parse() - split a file name into dir/base/suffix/member
|
||||
* path_build() - build a filename given dir/base/suffix/member
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
* path_parse() - split a file name into dir/base/suffix/member
|
||||
* path_build() - build a filename given dir/base/suffix/member
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
*
|
||||
* File_parse() and path_build() just manipuate a string and a structure;
|
||||
* they do not make system calls.
|
||||
@@ -48,7 +48,7 @@
|
||||
* 03/16/95 (seiwald) - fixed accursed typo on line 69.
|
||||
* 05/03/96 (seiwald) - split from filent.c, fileunix.c
|
||||
* 12/20/96 (seiwald) - when looking for the rightmost . in a file name,
|
||||
* don't include the archive member name.
|
||||
* don't include the archive member name.
|
||||
* 01/13/01 (seiwald) - turn on \ handling on UNIX, on by accident
|
||||
*/
|
||||
|
||||
@@ -57,87 +57,87 @@
|
||||
*/
|
||||
|
||||
void
|
||||
path_parse(
|
||||
char *file,
|
||||
PATHNAME *f )
|
||||
path_parse(
|
||||
char *file,
|
||||
PATHNAME *f )
|
||||
{
|
||||
char *p, *q;
|
||||
char *end;
|
||||
|
||||
memset( (char *)f, 0, sizeof( *f ) );
|
||||
char *p, *q;
|
||||
char *end;
|
||||
|
||||
/* Look for <grist> */
|
||||
memset( (char *)f, 0, sizeof( *f ) );
|
||||
|
||||
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
|
||||
{
|
||||
f->f_grist.ptr = file;
|
||||
f->f_grist.len = p - file;
|
||||
file = p + 1;
|
||||
}
|
||||
/* Look for <grist> */
|
||||
|
||||
/* Look for dir/ */
|
||||
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
|
||||
{
|
||||
f->f_grist.ptr = file;
|
||||
f->f_grist.len = p - file;
|
||||
file = p + 1;
|
||||
}
|
||||
|
||||
p = strrchr( file, '/' );
|
||||
/* Look for dir/ */
|
||||
|
||||
p = strrchr( file, '/' );
|
||||
|
||||
# if PATH_DELIM == '\\'
|
||||
/* On NT, look for dir\ as well */
|
||||
{
|
||||
char *p1 = strrchr( file, '\\' );
|
||||
p = p1 > p ? p1 : p;
|
||||
}
|
||||
/* On NT, look for dir\ as well */
|
||||
{
|
||||
char *p1 = strrchr( file, '\\' );
|
||||
p = p1 > p ? p1 : p;
|
||||
}
|
||||
# endif
|
||||
|
||||
if( p )
|
||||
{
|
||||
f->f_dir.ptr = file;
|
||||
f->f_dir.len = p - file;
|
||||
|
||||
/* Special case for / - dirname is /, not "" */
|
||||
if( p )
|
||||
{
|
||||
f->f_dir.ptr = file;
|
||||
f->f_dir.len = p - file;
|
||||
|
||||
if( !f->f_dir.len )
|
||||
f->f_dir.len = 1;
|
||||
/* Special case for / - dirname is /, not "" */
|
||||
|
||||
if( !f->f_dir.len )
|
||||
f->f_dir.len = 1;
|
||||
|
||||
# if PATH_DELIM == '\\'
|
||||
/* Special case for D:/ - dirname is D:/, not "D:" */
|
||||
/* Special case for D:/ - dirname is D:/, not "D:" */
|
||||
|
||||
if( f->f_dir.len == 2 && file[1] == ':' )
|
||||
f->f_dir.len = 3;
|
||||
if( f->f_dir.len == 2 && file[1] == ':' )
|
||||
f->f_dir.len = 3;
|
||||
# endif
|
||||
|
||||
file = p + 1;
|
||||
}
|
||||
file = p + 1;
|
||||
}
|
||||
|
||||
end = file + strlen( file );
|
||||
end = file + strlen( file );
|
||||
|
||||
/* Look for (member) */
|
||||
/* Look for (member) */
|
||||
|
||||
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
|
||||
{
|
||||
f->f_member.ptr = p + 1;
|
||||
f->f_member.len = end - p - 2;
|
||||
end = p;
|
||||
}
|
||||
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
|
||||
{
|
||||
f->f_member.ptr = p + 1;
|
||||
f->f_member.len = end - p - 2;
|
||||
end = p;
|
||||
}
|
||||
|
||||
/* Look for .suffix */
|
||||
/* This would be memrchr() */
|
||||
/* Look for .suffix */
|
||||
/* This would be memrchr() */
|
||||
|
||||
p = 0;
|
||||
q = file;
|
||||
p = 0;
|
||||
q = file;
|
||||
|
||||
while( q = (char *)memchr( q, '.', end - q ) )
|
||||
p = q++;
|
||||
while( q = (char *)memchr( q, '.', end - q ) )
|
||||
p = q++;
|
||||
|
||||
if( p )
|
||||
{
|
||||
f->f_suffix.ptr = p;
|
||||
f->f_suffix.len = end - p;
|
||||
end = p;
|
||||
}
|
||||
if( p )
|
||||
{
|
||||
f->f_suffix.ptr = p;
|
||||
f->f_suffix.len = end - p;
|
||||
end = p;
|
||||
}
|
||||
|
||||
/* Leaves base */
|
||||
/* Leaves base */
|
||||
|
||||
f->f_base.ptr = file;
|
||||
f->f_base.len = end - file;
|
||||
f->f_base.ptr = file;
|
||||
f->f_base.len = end - file;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -188,22 +188,22 @@ static char as_path_delim( char c )
|
||||
|
||||
void
|
||||
path_build(
|
||||
PATHNAME *f,
|
||||
string *file,
|
||||
int binding )
|
||||
PATHNAME *f,
|
||||
string *file,
|
||||
int binding )
|
||||
{
|
||||
file_build1( f, file );
|
||||
|
||||
|
||||
/* Don't prepend root if it's . or directory is rooted */
|
||||
# if PATH_DELIM == '/'
|
||||
|
||||
if( f->f_root.len
|
||||
if( f->f_root.len
|
||||
&& !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' )
|
||||
&& !( f->f_dir.len && f->f_dir.ptr[0] == '/' ) )
|
||||
|
||||
# else /* unix */
|
||||
|
||||
if( f->f_root.len
|
||||
if( f->f_root.len
|
||||
&& !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' )
|
||||
&& !( f->f_dir.len && f->f_dir.ptr[0] == '/' )
|
||||
&& !( f->f_dir.len && f->f_dir.ptr[0] == '\\' )
|
||||
@@ -213,7 +213,7 @@ path_build(
|
||||
|
||||
{
|
||||
string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len );
|
||||
/* If 'root' already ends with path delimeter,
|
||||
/* If 'root' already ends with path delimeter,
|
||||
don't add yet another one. */
|
||||
if( ! is_path_delim( f->f_root.ptr[f->f_root.len-1] ) )
|
||||
string_push_back( file, as_path_delim( f->f_root.ptr[f->f_root.len] ) );
|
||||
@@ -258,21 +258,21 @@ path_build(
|
||||
}
|
||||
|
||||
/*
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
*/
|
||||
|
||||
void
|
||||
path_parent( PATHNAME *f )
|
||||
{
|
||||
/* just set everything else to nothing */
|
||||
/* just set everything else to nothing */
|
||||
|
||||
f->f_base.ptr =
|
||||
f->f_suffix.ptr =
|
||||
f->f_member.ptr = "";
|
||||
f->f_base.ptr =
|
||||
f->f_suffix.ptr =
|
||||
f->f_member.ptr = "";
|
||||
|
||||
f->f_base.len =
|
||||
f->f_suffix.len =
|
||||
f->f_member.len = 0;
|
||||
f->f_base.len =
|
||||
f->f_suffix.len =
|
||||
f->f_member.len = 0;
|
||||
}
|
||||
|
||||
#ifdef NT
|
||||
@@ -296,7 +296,7 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
|
||||
/* Is the string valid? */
|
||||
if (!lpszShortPath) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is the path valid? */
|
||||
@@ -305,7 +305,7 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
|
||||
|
||||
/* Convert "/" to "\" */
|
||||
for (i=0;i<len;++i) {
|
||||
if (lpszShortPath[i]==_T('/'))
|
||||
if (lpszShortPath[i]==_T('/'))
|
||||
path[i]=_T('\\');
|
||||
else
|
||||
path[i]=lpszShortPath[i];
|
||||
@@ -331,7 +331,7 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
|
||||
}
|
||||
_tcsncpy(ret,path,2);
|
||||
}
|
||||
|
||||
|
||||
/* Expand the path for each subpath, and strip trailing backslashes */
|
||||
for (prev_pos = pos-1;pos<=len;++pos) {
|
||||
if (path[pos]==_T('\\') || (path[pos]==_T('\0') &&
|
||||
@@ -356,9 +356,9 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
|
||||
/* If it's ".." element, we need to append it, not
|
||||
the name in parent that FindFirstFile will return.
|
||||
Same goes for "." */
|
||||
|
||||
|
||||
if (new_element[0] == _T('.') && new_element[1] == _T('\0') ||
|
||||
new_element[0] == _T('.') && new_element[1] == _T('.')
|
||||
new_element[0] == _T('.') && new_element[1] == _T('.')
|
||||
&& new_element[2] == _T('\0'))
|
||||
{
|
||||
_tcscat(ret, new_element);
|
||||
@@ -378,21 +378,21 @@ DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
|
||||
prev_pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
len=_tcslen(ret)+1;
|
||||
if (cchBuffer>=len)
|
||||
_tcscpy(lpszLongPath,ret);
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char* short_path_to_long_path(char* short_path)
|
||||
{
|
||||
{
|
||||
char buffer2[_MAX_PATH];
|
||||
int ret = ShortPathToLongPath(short_path, buffer2, _MAX_PATH);
|
||||
|
||||
if (ret)
|
||||
return newstr(buffer2);
|
||||
return newstr(buffer2);
|
||||
else
|
||||
return newstr(short_path);
|
||||
}
|
||||
@@ -446,14 +446,14 @@ const char * path_tmpnam(void)
|
||||
const char * path_tmpfile(void)
|
||||
{
|
||||
const char * result = 0;
|
||||
|
||||
|
||||
string file_path;
|
||||
string_copy(&file_path,path_tmpdir());
|
||||
string_push_back(&file_path,PATH_DELIM);
|
||||
string_append(&file_path,path_tmpnam());
|
||||
result = newstr(file_path.value);
|
||||
string_free(&file_path);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* path_parse() - split a file name into dir/base/suffix/member
|
||||
* path_build() - build a filename given dir/base/suffix/member
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
* path_parse() - split a file name into dir/base/suffix/member
|
||||
* path_build() - build a filename given dir/base/suffix/member
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
*
|
||||
* File_parse() and path_build() just manipuate a string and a structure;
|
||||
* they do not make system calls.
|
||||
*
|
||||
* WARNING! This file contains voodoo logic, as black magic is
|
||||
* WARNING! This file contains voodoo logic, as black magic is
|
||||
* necessary for wrangling with VMS file name. Woe be to people
|
||||
* who mess with this code.
|
||||
*
|
||||
@@ -42,192 +42,192 @@
|
||||
*/
|
||||
|
||||
void
|
||||
path_parse(
|
||||
char *file,
|
||||
PATHNAME *f )
|
||||
path_parse(
|
||||
char *file,
|
||||
PATHNAME *f )
|
||||
{
|
||||
char *p, *q;
|
||||
char *end;
|
||||
|
||||
memset( (char *)f, 0, sizeof( *f ) );
|
||||
char *p, *q;
|
||||
char *end;
|
||||
|
||||
/* Look for <grist> */
|
||||
memset( (char *)f, 0, sizeof( *f ) );
|
||||
|
||||
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
|
||||
{
|
||||
f->f_grist.ptr = file;
|
||||
f->f_grist.len = p - file;
|
||||
file = p + 1;
|
||||
}
|
||||
/* Look for <grist> */
|
||||
|
||||
/* Look for dev:[dir] or dev: */
|
||||
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
|
||||
{
|
||||
f->f_grist.ptr = file;
|
||||
f->f_grist.len = p - file;
|
||||
file = p + 1;
|
||||
}
|
||||
|
||||
if( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) )
|
||||
{
|
||||
f->f_dir.ptr = file;
|
||||
f->f_dir.len = p + 1 - file;
|
||||
file = p + 1;
|
||||
}
|
||||
/* Look for dev:[dir] or dev: */
|
||||
|
||||
end = file + strlen( file );
|
||||
if( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) )
|
||||
{
|
||||
f->f_dir.ptr = file;
|
||||
f->f_dir.len = p + 1 - file;
|
||||
file = p + 1;
|
||||
}
|
||||
|
||||
/* Look for (member) */
|
||||
end = file + strlen( file );
|
||||
|
||||
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
|
||||
{
|
||||
f->f_member.ptr = p + 1;
|
||||
f->f_member.len = end - p - 2;
|
||||
end = p;
|
||||
}
|
||||
/* Look for (member) */
|
||||
|
||||
/* Look for .suffix */
|
||||
/* This would be memrchr() */
|
||||
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
|
||||
{
|
||||
f->f_member.ptr = p + 1;
|
||||
f->f_member.len = end - p - 2;
|
||||
end = p;
|
||||
}
|
||||
|
||||
p = 0;
|
||||
q = file;
|
||||
/* Look for .suffix */
|
||||
/* This would be memrchr() */
|
||||
|
||||
while( q = (char *)memchr( q, '.', end - q ) )
|
||||
p = q++;
|
||||
p = 0;
|
||||
q = file;
|
||||
|
||||
if( p )
|
||||
{
|
||||
f->f_suffix.ptr = p;
|
||||
f->f_suffix.len = end - p;
|
||||
end = p;
|
||||
}
|
||||
while( q = (char *)memchr( q, '.', end - q ) )
|
||||
p = q++;
|
||||
|
||||
/* Leaves base */
|
||||
if( p )
|
||||
{
|
||||
f->f_suffix.ptr = p;
|
||||
f->f_suffix.len = end - p;
|
||||
end = p;
|
||||
}
|
||||
|
||||
f->f_base.ptr = file;
|
||||
f->f_base.len = end - file;
|
||||
/* Leaves base */
|
||||
|
||||
/* Is this a directory without a file spec? */
|
||||
f->f_base.ptr = file;
|
||||
f->f_base.len = end - file;
|
||||
|
||||
f->parent = 0;
|
||||
/* Is this a directory without a file spec? */
|
||||
|
||||
f->parent = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* dir mods result
|
||||
* --- --- ------
|
||||
* dir mods result
|
||||
* --- --- ------
|
||||
* Rerooting:
|
||||
*
|
||||
* (none) :R=dev: dev:
|
||||
* devd: :R=dev: devd:
|
||||
* devd:[dir] :R=dev: devd:[dir]
|
||||
* [.dir] :R=dev: dev:[dir] questionable
|
||||
* [dir] :R=dev: dev:[dir]
|
||||
* (none) :R=dev: dev:
|
||||
* devd: :R=dev: devd:
|
||||
* devd:[dir] :R=dev: devd:[dir]
|
||||
* [.dir] :R=dev: dev:[dir] questionable
|
||||
* [dir] :R=dev: dev:[dir]
|
||||
*
|
||||
* (none) :R=[rdir] [rdir] questionable
|
||||
* devd: :R=[rdir] devd:
|
||||
* devd:[dir] :R=[rdir] devd:[dir]
|
||||
* [.dir] :R=[rdir] [rdir.dir] questionable
|
||||
* [dir] :R=[rdir] [rdir]
|
||||
* (none) :R=[rdir] [rdir] questionable
|
||||
* devd: :R=[rdir] devd:
|
||||
* devd:[dir] :R=[rdir] devd:[dir]
|
||||
* [.dir] :R=[rdir] [rdir.dir] questionable
|
||||
* [dir] :R=[rdir] [rdir]
|
||||
*
|
||||
* (none) :R=dev:[root] dev:[root]
|
||||
* devd: :R=dev:[root] devd:
|
||||
* devd:[dir] :R=dev:[root] devd:[dir]
|
||||
* [.dir] :R=dev:[root] dev:[root.dir]
|
||||
* [dir] :R=dev:[root] [dir]
|
||||
* (none) :R=dev:[root] dev:[root]
|
||||
* devd: :R=dev:[root] devd:
|
||||
* devd:[dir] :R=dev:[root] devd:[dir]
|
||||
* [.dir] :R=dev:[root] dev:[root.dir]
|
||||
* [dir] :R=dev:[root] [dir]
|
||||
*
|
||||
* Climbing to parent:
|
||||
*
|
||||
*/
|
||||
|
||||
# define DIR_EMPTY 0 /* empty string */
|
||||
# define DIR_DEV 1 /* dev: */
|
||||
# define DIR_DEVDIR 2 /* dev:[dir] */
|
||||
# define DIR_DOTDIR 3 /* [.dir] */
|
||||
# define DIR_DASHDIR 4 /* [-] or [-.dir] */
|
||||
# define DIR_ABSDIR 5 /* [dir] */
|
||||
# define DIR_ROOT 6 /* [000000] or dev:[000000] */
|
||||
# define DIR_EMPTY 0 /* empty string */
|
||||
# define DIR_DEV 1 /* dev: */
|
||||
# define DIR_DEVDIR 2 /* dev:[dir] */
|
||||
# define DIR_DOTDIR 3 /* [.dir] */
|
||||
# define DIR_DASHDIR 4 /* [-] or [-.dir] */
|
||||
# define DIR_ABSDIR 5 /* [dir] */
|
||||
# define DIR_ROOT 6 /* [000000] or dev:[000000] */
|
||||
|
||||
# define G_DIR 0 /* take just dir */
|
||||
# define G_ROOT 1 /* take just root */
|
||||
# define G_VAD 2 /* root's dev: + [abs] */
|
||||
# define G_DRD 3 /* root's dev:[dir] + [.rel] */
|
||||
# define G_VRD 4 /* root's dev: + [.rel] made [abs] */
|
||||
# define G_DDD 5 /* root's dev:[dir] + . + [dir] */
|
||||
# define G_DIR 0 /* take just dir */
|
||||
# define G_ROOT 1 /* take just root */
|
||||
# define G_VAD 2 /* root's dev: + [abs] */
|
||||
# define G_DRD 3 /* root's dev:[dir] + [.rel] */
|
||||
# define G_VRD 4 /* root's dev: + [.rel] made [abs] */
|
||||
# define G_DDD 5 /* root's dev:[dir] + . + [dir] */
|
||||
|
||||
static int grid[7][7] = {
|
||||
|
||||
/* root/dir EMPTY DEV DEVDIR DOTDIR DASH, ABSDIR ROOT */
|
||||
/* EMPTY */ G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR,
|
||||
/* DEV */ G_ROOT, G_DIR, G_DIR, G_VRD, G_VAD, G_VAD, G_VAD,
|
||||
/* DEVDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_VAD, G_VAD, G_VAD,
|
||||
/* DOTDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR,
|
||||
/* DASHDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DDD, G_DIR, G_DIR,
|
||||
/* ABSDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR,
|
||||
/* ROOT */ G_ROOT, G_DIR, G_DIR, G_VRD, G_DIR, G_DIR, G_DIR,
|
||||
/* root/dir EMPTY DEV DEVDIR DOTDIR DASH, ABSDIR ROOT */
|
||||
/* EMPTY */ G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR,
|
||||
/* DEV */ G_ROOT, G_DIR, G_DIR, G_VRD, G_VAD, G_VAD, G_VAD,
|
||||
/* DEVDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_VAD, G_VAD, G_VAD,
|
||||
/* DOTDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR,
|
||||
/* DASHDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DDD, G_DIR, G_DIR,
|
||||
/* ABSDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR,
|
||||
/* ROOT */ G_ROOT, G_DIR, G_DIR, G_VRD, G_DIR, G_DIR, G_DIR,
|
||||
|
||||
} ;
|
||||
|
||||
struct dirinf {
|
||||
int flags;
|
||||
int flags;
|
||||
|
||||
struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
} dev, dir;
|
||||
struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
} dev, dir;
|
||||
} ;
|
||||
|
||||
static char *
|
||||
strnchr(
|
||||
char *buf,
|
||||
int c,
|
||||
int len )
|
||||
strnchr(
|
||||
char *buf,
|
||||
int c,
|
||||
int len )
|
||||
{
|
||||
while( len-- )
|
||||
if( *buf && *buf++ == c )
|
||||
return buf - 1;
|
||||
while( len-- )
|
||||
if( *buf && *buf++ == c )
|
||||
return buf - 1;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dir_flags(
|
||||
char *buf,
|
||||
int len,
|
||||
struct dirinf *i )
|
||||
dir_flags(
|
||||
char *buf,
|
||||
int len,
|
||||
struct dirinf *i )
|
||||
{
|
||||
char *p;
|
||||
char *p;
|
||||
|
||||
if( !buf || !len )
|
||||
{
|
||||
i->flags = DIR_EMPTY;
|
||||
i->dev.ptr =
|
||||
i->dir.ptr = 0;
|
||||
i->dev.len =
|
||||
i->dir.len = 0;
|
||||
}
|
||||
else if( p = strnchr( buf, ':', len ) )
|
||||
{
|
||||
i->dev.ptr = buf;
|
||||
i->dev.len = p + 1 - buf;
|
||||
i->dir.ptr = buf + i->dev.len;
|
||||
i->dir.len = len - i->dev.len;
|
||||
i->flags = i->dir.len && *i->dir.ptr == '[' ? DIR_DEVDIR : DIR_DEV;
|
||||
}
|
||||
else
|
||||
{
|
||||
i->dev.ptr = buf;
|
||||
i->dev.len = 0;
|
||||
i->dir.ptr = buf;
|
||||
i->dir.len = len;
|
||||
if( !buf || !len )
|
||||
{
|
||||
i->flags = DIR_EMPTY;
|
||||
i->dev.ptr =
|
||||
i->dir.ptr = 0;
|
||||
i->dev.len =
|
||||
i->dir.len = 0;
|
||||
}
|
||||
else if( p = strnchr( buf, ':', len ) )
|
||||
{
|
||||
i->dev.ptr = buf;
|
||||
i->dev.len = p + 1 - buf;
|
||||
i->dir.ptr = buf + i->dev.len;
|
||||
i->dir.len = len - i->dev.len;
|
||||
i->flags = i->dir.len && *i->dir.ptr == '[' ? DIR_DEVDIR : DIR_DEV;
|
||||
}
|
||||
else
|
||||
{
|
||||
i->dev.ptr = buf;
|
||||
i->dev.len = 0;
|
||||
i->dir.ptr = buf;
|
||||
i->dir.len = len;
|
||||
|
||||
if( *buf == '[' && buf[1] == ']' )
|
||||
i->flags = DIR_EMPTY;
|
||||
else if( *buf == '[' && buf[1] == '.' )
|
||||
i->flags = DIR_DOTDIR;
|
||||
else if( *buf == '[' && buf[1] == '-' )
|
||||
i->flags = DIR_DASHDIR;
|
||||
else
|
||||
i->flags = DIR_ABSDIR;
|
||||
}
|
||||
if( *buf == '[' && buf[1] == ']' )
|
||||
i->flags = DIR_EMPTY;
|
||||
else if( *buf == '[' && buf[1] == '.' )
|
||||
i->flags = DIR_DOTDIR;
|
||||
else if( *buf == '[' && buf[1] == '-' )
|
||||
i->flags = DIR_DASHDIR;
|
||||
else
|
||||
i->flags = DIR_ABSDIR;
|
||||
}
|
||||
|
||||
/* But if its rooted in any way */
|
||||
/* But if its rooted in any way */
|
||||
|
||||
if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) )
|
||||
i->flags = DIR_ROOT;
|
||||
if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) )
|
||||
i->flags = DIR_ROOT;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -236,15 +236,15 @@ dir_flags(
|
||||
|
||||
void
|
||||
path_build(
|
||||
PATHNAME *f,
|
||||
string *file,
|
||||
int binding )
|
||||
PATHNAME *f,
|
||||
string *file,
|
||||
int binding )
|
||||
{
|
||||
struct dirinf root, dir;
|
||||
int g;
|
||||
|
||||
file_build1( f, file );
|
||||
|
||||
|
||||
/* Get info on root and dir for combining. */
|
||||
|
||||
dir_flags( f->f_root.ptr, f->f_root.len, &root );
|
||||
@@ -254,23 +254,23 @@ path_build(
|
||||
|
||||
switch( g = grid[ root.flags ][ dir.flags ] )
|
||||
{
|
||||
case G_DIR:
|
||||
case G_DIR:
|
||||
/* take dir */
|
||||
string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len );
|
||||
break;
|
||||
|
||||
case G_ROOT:
|
||||
case G_ROOT:
|
||||
/* take root */
|
||||
string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len );
|
||||
break;
|
||||
|
||||
case G_VAD:
|
||||
case G_VAD:
|
||||
/* root's dev + abs directory */
|
||||
string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len );
|
||||
string_append_range( file, dir.dir.ptr, dir.dir.ptr + dir.dir.len );
|
||||
break;
|
||||
|
||||
case G_DRD:
|
||||
|
||||
case G_DRD:
|
||||
case G_DDD:
|
||||
/* root's dev:[dir] + rel directory */
|
||||
string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len );
|
||||
@@ -289,7 +289,7 @@ path_build(
|
||||
string_append_range( file, dir.dir.ptr + 1, dir.dir.ptr + 1 + dir.dir.len - 1 );
|
||||
break;
|
||||
|
||||
case G_VRD:
|
||||
case G_VRD:
|
||||
/* root's dev + rel directory made abs */
|
||||
string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len );
|
||||
string_push_back( file, '[' );
|
||||
@@ -304,15 +304,15 @@ path_build(
|
||||
printf( "%d x %d = %d (%s)\n", root.flags, dir.flags,
|
||||
grid[ root.flags ][ dir.flags ], file->value );
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*
|
||||
/*
|
||||
* Now do the special :P modifier when no file was present.
|
||||
* (none) (none)
|
||||
* [dir1.dir2] [dir1]
|
||||
* [dir] [000000]
|
||||
* [.dir] (none)
|
||||
* [] []
|
||||
* (none) (none)
|
||||
* [dir1.dir2] [dir1]
|
||||
* [dir] [000000]
|
||||
* [.dir] (none)
|
||||
* [] []
|
||||
*/
|
||||
|
||||
if( file->value[file->size - 1] == ']' && f->parent )
|
||||
@@ -337,7 +337,7 @@ path_build(
|
||||
/* handle .- or - */
|
||||
if( p > file->value && p[-1] == '.' )
|
||||
--p;
|
||||
|
||||
|
||||
*p++ = ']';
|
||||
break;
|
||||
}
|
||||
@@ -388,7 +388,7 @@ path_build(
|
||||
|
||||
# ifdef DEBUG
|
||||
if( DEBUG_SEARCH )
|
||||
printf("built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n",
|
||||
printf("built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n",
|
||||
f->f_root.len, f->f_root.ptr,
|
||||
f->f_dir.len, f->f_dir.ptr,
|
||||
f->f_base.len, f->f_base.ptr,
|
||||
@@ -399,26 +399,26 @@ path_build(
|
||||
}
|
||||
|
||||
/*
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
* path_parent() - make a PATHNAME point to its parent dir
|
||||
*/
|
||||
|
||||
void
|
||||
path_parent( PATHNAME *f )
|
||||
{
|
||||
if( f->f_base.len )
|
||||
{
|
||||
f->f_base.ptr =
|
||||
f->f_suffix.ptr =
|
||||
f->f_member.ptr = "";
|
||||
if( f->f_base.len )
|
||||
{
|
||||
f->f_base.ptr =
|
||||
f->f_suffix.ptr =
|
||||
f->f_member.ptr = "";
|
||||
|
||||
f->f_base.len =
|
||||
f->f_suffix.len =
|
||||
f->f_member.len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->parent = 1;
|
||||
}
|
||||
f->f_base.len =
|
||||
f->f_suffix.len =
|
||||
f->f_member.len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->parent = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# endif /* VMS */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,13 +9,13 @@
|
||||
|
||||
#define NSUBEXP 10
|
||||
typedef struct regexp {
|
||||
char *startp[NSUBEXP];
|
||||
char *endp[NSUBEXP];
|
||||
char regstart; /* Internal use only. */
|
||||
char reganch; /* Internal use only. */
|
||||
char *regmust; /* Internal use only. */
|
||||
int regmlen; /* Internal use only. */
|
||||
char program[1]; /* Unwarranted chumminess with compiler. */
|
||||
char *startp[NSUBEXP];
|
||||
char *endp[NSUBEXP];
|
||||
char regstart; /* Internal use only. */
|
||||
char reganch; /* Internal use only. */
|
||||
char *regmust; /* Internal use only. */
|
||||
int regmlen; /* Internal use only. */
|
||||
char program[1]; /* Unwarranted chumminess with compiler. */
|
||||
} regexp;
|
||||
|
||||
regexp *regcomp( char *exp );
|
||||
@@ -26,7 +26,7 @@ void regerror( char *s );
|
||||
* The first byte of the regexp internal "program" is actually this magic
|
||||
* number; the start node begins in the second byte.
|
||||
*/
|
||||
#define MAGIC 0234
|
||||
#define MAGIC 0234
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,11 +53,12 @@ static struct hash *targethash = 0;
|
||||
|
||||
typedef struct _located_target LOCATED_TARGET ;
|
||||
|
||||
struct _located_target {
|
||||
char* file_name;
|
||||
TARGET* target;
|
||||
struct _located_target
|
||||
{
|
||||
char * file_name;
|
||||
TARGET * target;
|
||||
};
|
||||
static struct hash *located_targets = 0;
|
||||
static struct hash * located_targets = 0;
|
||||
|
||||
|
||||
/*
|
||||
@@ -82,16 +83,16 @@ void add_include( TARGET * including, TARGET * included )
|
||||
* enter_rule() - return pointer to RULE, creating it if necessary in
|
||||
* target_module.
|
||||
*/
|
||||
static RULE *
|
||||
enter_rule( char *rulename, module_t *target_module )
|
||||
static RULE * enter_rule( char * rulename, module_t * target_module )
|
||||
{
|
||||
RULE rule, *r = &rule;
|
||||
RULE rule;
|
||||
RULE * r = &rule;
|
||||
|
||||
r->name = rulename;
|
||||
|
||||
if ( hashenter( demand_rules( target_module ), (HASHDATA **)&r ) )
|
||||
if ( hashenter( demand_rules( target_module ), (HASHDATA * *)&r ) )
|
||||
{
|
||||
r->name = newstr( rulename ); /* never freed */
|
||||
r->name = newstr( rulename ); /* never freed */
|
||||
r->procedure = (PARSE *)0;
|
||||
r->module = 0;
|
||||
r->actions = 0;
|
||||
@@ -105,38 +106,42 @@ enter_rule( char *rulename, module_t *target_module )
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* define_rule() - return pointer to RULE, creating it if necessary in
|
||||
* target_module. Prepare it to accept a body or action originating in
|
||||
* src_module.
|
||||
*/
|
||||
static RULE *
|
||||
define_rule( module_t *src_module, char *rulename, module_t *target_module )
|
||||
{
|
||||
RULE *r = enter_rule( rulename, target_module );
|
||||
|
||||
static RULE * define_rule
|
||||
(
|
||||
module_t * src_module,
|
||||
char * rulename,
|
||||
module_t * target_module
|
||||
)
|
||||
{
|
||||
RULE * r = enter_rule( rulename, target_module );
|
||||
if ( r->module != src_module ) /* if the rule was imported from elsewhere, clear it now */
|
||||
{
|
||||
set_rule_body( r, 0, 0 );
|
||||
set_rule_body( r, 0, 0 );
|
||||
set_rule_actions( r, 0 );
|
||||
r->module = src_module; /* r will be executed in the source module */
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
rule_free( RULE* r )
|
||||
|
||||
void rule_free( RULE * r )
|
||||
{
|
||||
freestr( r->name );
|
||||
r->name = "";
|
||||
parse_free( r->procedure );
|
||||
r->procedure = 0;
|
||||
if ( r->arguments )
|
||||
args_free( r->arguments );
|
||||
if ( r->arguments )
|
||||
args_free( r->arguments );
|
||||
r->arguments = 0;
|
||||
if ( r->actions )
|
||||
actions_free( r->actions );
|
||||
actions_free( r->actions );
|
||||
r->actions = 0;
|
||||
}
|
||||
|
||||
@@ -147,25 +152,25 @@ rule_free( RULE* r )
|
||||
TARGET *
|
||||
bindtarget( const char *targetname )
|
||||
{
|
||||
TARGET target, *t = ⌖
|
||||
TARGET target, *t = ⌖
|
||||
|
||||
if( !targethash )
|
||||
targethash = hashinit( sizeof( TARGET ), "targets" );
|
||||
if( !targethash )
|
||||
targethash = hashinit( sizeof( TARGET ), "targets" );
|
||||
|
||||
/* Perforce added const everywhere. No time to merge that change. */
|
||||
#ifdef NT
|
||||
targetname = short_path_to_long_path( (char*)targetname );
|
||||
#endif
|
||||
t->name = (char*)targetname;
|
||||
t->name = (char*)targetname;
|
||||
|
||||
if( hashenter( targethash, (HASHDATA **)&t ) )
|
||||
{
|
||||
memset( (char *)t, '\0', sizeof( *t ) );
|
||||
t->name = newstr( (char*)targetname ); /* never freed */
|
||||
t->boundname = t->name; /* default for T_FLAG_NOTFILE */
|
||||
}
|
||||
if( hashenter( targethash, (HASHDATA **)&t ) )
|
||||
{
|
||||
memset( (char *)t, '\0', sizeof( *t ) );
|
||||
t->name = newstr( (char*)targetname ); /* never freed */
|
||||
t->boundname = t->name; /* default for T_FLAG_NOTFILE */
|
||||
}
|
||||
|
||||
return t;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@@ -177,8 +182,8 @@ static void bind_explicitly_located_target(void* xtarget, void* data)
|
||||
/* Check if there's a setting for LOCATE */
|
||||
SETTINGS* s = t->settings;
|
||||
for(; s ; s = s->next)
|
||||
{
|
||||
if (strcmp(s->symbol, "LOCATE") == 0)
|
||||
{
|
||||
if (strcmp(s->symbol, "LOCATE") == 0)
|
||||
{
|
||||
pushsettings(t->settings);
|
||||
/* We're binding a target with explicit LOCATE. So
|
||||
@@ -192,16 +197,19 @@ static void bind_explicitly_located_target(void* xtarget, void* data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bind_explicitly_located_targets()
|
||||
{
|
||||
if (targethash)
|
||||
hashenumerate(targethash, bind_explicitly_located_target, (void*)0);
|
||||
}
|
||||
|
||||
/* TODO: this is probably not a good idea to use functions in other modules like
|
||||
|
||||
/* TODO: it is probably not a good idea to use functions in other modules like
|
||||
that. */
|
||||
void call_bind_rule(char* target, char* boundname);
|
||||
|
||||
|
||||
TARGET* search_for_target ( char * name, LIST* search_path )
|
||||
{
|
||||
PATHNAME f[1];
|
||||
@@ -213,7 +221,7 @@ TARGET* search_for_target ( char * name, LIST* search_path )
|
||||
|
||||
string_new( buf );
|
||||
|
||||
path_parse( name, f );
|
||||
path_parse( name, f );
|
||||
|
||||
f->f_grist.ptr = 0;
|
||||
f->f_grist.len = 0;
|
||||
@@ -256,7 +264,7 @@ TARGET* search_for_target ( char * name, LIST* search_path )
|
||||
string_truncate( buf, 0 );
|
||||
path_build( f, buf, 1 );
|
||||
|
||||
timestamp( buf->value, &time );
|
||||
timestamp( buf->value, &time );
|
||||
}
|
||||
|
||||
result = bindtarget( name );
|
||||
@@ -265,32 +273,31 @@ TARGET* search_for_target ( char * name, LIST* search_path )
|
||||
result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING;
|
||||
|
||||
call_bind_rule( result->name, result->boundname );
|
||||
|
||||
|
||||
string_free( buf );
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* copytarget() - make a new target with the old target's name
|
||||
*
|
||||
* Not entered into hash table -- for internal nodes.
|
||||
*/
|
||||
|
||||
TARGET *
|
||||
copytarget( const TARGET *ot )
|
||||
TARGET * copytarget( const TARGET * ot )
|
||||
{
|
||||
TARGET *t;
|
||||
TARGET *t;
|
||||
|
||||
t = (TARGET *)BJAM_MALLOC( sizeof( *t ) );
|
||||
memset( (char *)t, '\0', sizeof( *t ) );
|
||||
t->name = copystr( ot->name );
|
||||
t->boundname = t->name;
|
||||
t = (TARGET *)BJAM_MALLOC( sizeof( *t ) );
|
||||
memset( (char *)t, '\0', sizeof( *t ) );
|
||||
t->name = copystr( ot->name );
|
||||
t->boundname = t->name;
|
||||
|
||||
t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL;
|
||||
t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL;
|
||||
|
||||
return t;
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -300,78 +307,80 @@ copytarget( const TARGET *ot )
|
||||
void
|
||||
touchtarget( char *t )
|
||||
{
|
||||
bindtarget( t )->flags |= T_FLAG_TOUCHED;
|
||||
bindtarget( t )->flags |= T_FLAG_TOUCHED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* targetlist() - turn list of target names into a TARGET chain
|
||||
*
|
||||
* Inputs:
|
||||
* chain existing TARGETS to append to
|
||||
* targets list of target names
|
||||
* chain existing TARGETS to append to
|
||||
* targets list of target names
|
||||
*/
|
||||
|
||||
TARGETS *
|
||||
targetlist(
|
||||
TARGETS *chain,
|
||||
LIST *targets )
|
||||
targetlist(
|
||||
TARGETS *chain,
|
||||
LIST *targets )
|
||||
{
|
||||
for( ; targets; targets = list_next( targets ) )
|
||||
chain = targetentry( chain, bindtarget( targets->string ) );
|
||||
for( ; targets; targets = list_next( targets ) )
|
||||
chain = targetentry( chain, bindtarget( targets->string ) );
|
||||
|
||||
return chain;
|
||||
return chain;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* targetentry() - add a TARGET to a chain of TARGETS
|
||||
*
|
||||
* Inputs:
|
||||
* chain exisitng TARGETS to append to
|
||||
* target new target to append
|
||||
* chain existing TARGETS to append to
|
||||
* target new target to append
|
||||
*/
|
||||
|
||||
TARGETS *
|
||||
targetentry(
|
||||
TARGETS *chain,
|
||||
TARGET *target )
|
||||
targetentry(
|
||||
TARGETS *chain,
|
||||
TARGET *target )
|
||||
{
|
||||
TARGETS *c;
|
||||
TARGETS *c;
|
||||
|
||||
c = (TARGETS *)BJAM_MALLOC( sizeof( TARGETS ) );
|
||||
c->target = target;
|
||||
c = (TARGETS *)BJAM_MALLOC( sizeof( TARGETS ) );
|
||||
c->target = target;
|
||||
|
||||
if( !chain ) chain = c;
|
||||
else chain->tail->next = c;
|
||||
chain->tail = c;
|
||||
c->next = 0;
|
||||
if( !chain ) chain = c;
|
||||
else chain->tail->next = c;
|
||||
chain->tail = c;
|
||||
c->next = 0;
|
||||
|
||||
return chain;
|
||||
return chain;
|
||||
}
|
||||
|
||||
/*
|
||||
* targetchain() - append two TARGET chains
|
||||
*
|
||||
* Inputs:
|
||||
* chain exisitng TARGETS to append to
|
||||
* target new target to append
|
||||
* chain exisitng TARGETS to append to
|
||||
* target new target to append
|
||||
*/
|
||||
|
||||
TARGETS *
|
||||
targetchain(
|
||||
TARGETS *chain,
|
||||
TARGETS *targets )
|
||||
targetchain(
|
||||
TARGETS *chain,
|
||||
TARGETS *targets )
|
||||
{
|
||||
TARGETS *c;
|
||||
TARGETS *c;
|
||||
|
||||
if( !targets )
|
||||
return chain;
|
||||
else if( !chain )
|
||||
return targets;
|
||||
if( !targets )
|
||||
return chain;
|
||||
else if( !chain )
|
||||
return targets;
|
||||
|
||||
chain->tail->next = targets;
|
||||
chain->tail = targets->tail;
|
||||
chain->tail->next = targets;
|
||||
chain->tail = targets->tail;
|
||||
|
||||
return chain;
|
||||
return chain;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -380,19 +389,19 @@ targetchain(
|
||||
|
||||
ACTIONS *
|
||||
actionlist(
|
||||
ACTIONS *chain,
|
||||
ACTION *action )
|
||||
ACTIONS *chain,
|
||||
ACTION *action )
|
||||
{
|
||||
ACTIONS *actions = (ACTIONS *)BJAM_MALLOC( sizeof( ACTIONS ) );
|
||||
ACTIONS *actions = (ACTIONS *)BJAM_MALLOC( sizeof( ACTIONS ) );
|
||||
|
||||
actions->action = action;
|
||||
actions->action = action;
|
||||
|
||||
if( !chain ) chain = actions;
|
||||
else chain->tail->next = actions;
|
||||
chain->tail = actions;
|
||||
actions->next = 0;
|
||||
if( !chain ) chain = actions;
|
||||
else chain->tail->next = actions;
|
||||
chain->tail = actions;
|
||||
actions->next = 0;
|
||||
|
||||
return chain;
|
||||
return chain;
|
||||
}
|
||||
|
||||
static SETTINGS* settings_freelist;
|
||||
@@ -409,54 +418,54 @@ static SETTINGS* settings_freelist;
|
||||
|
||||
SETTINGS *
|
||||
addsettings(
|
||||
SETTINGS *head,
|
||||
int flag,
|
||||
char *symbol,
|
||||
LIST *value )
|
||||
SETTINGS *head,
|
||||
int flag,
|
||||
char *symbol,
|
||||
LIST *value )
|
||||
{
|
||||
SETTINGS *v;
|
||||
|
||||
/* Look for previous setting */
|
||||
SETTINGS *v;
|
||||
|
||||
for( v = head; v; v = v->next )
|
||||
if( !strcmp( v->symbol, symbol ) )
|
||||
break;
|
||||
/* Look for previous setting */
|
||||
|
||||
/* If not previously set, alloc a new. */
|
||||
/* If appending, do so. */
|
||||
/* Else free old and set new. */
|
||||
for( v = head; v; v = v->next )
|
||||
if( !strcmp( v->symbol, symbol ) )
|
||||
break;
|
||||
|
||||
if( !v )
|
||||
{
|
||||
/* If not previously set, alloc a new. */
|
||||
/* If appending, do so. */
|
||||
/* Else free old and set new. */
|
||||
|
||||
if( !v )
|
||||
{
|
||||
v = settings_freelist;
|
||||
|
||||
|
||||
if ( v )
|
||||
settings_freelist = v->next;
|
||||
else
|
||||
{
|
||||
v = (SETTINGS *)BJAM_MALLOC( sizeof( *v ) );
|
||||
}
|
||||
|
||||
v->symbol = newstr( symbol );
|
||||
v->value = value;
|
||||
v->next = head;
|
||||
head = v;
|
||||
}
|
||||
else if( flag == VAR_APPEND )
|
||||
{
|
||||
v->value = list_append( v->value, value );
|
||||
}
|
||||
else if( flag != VAR_DEFAULT )
|
||||
{
|
||||
list_free( v->value );
|
||||
v->value = value;
|
||||
}
|
||||
|
||||
v->symbol = newstr( symbol );
|
||||
v->value = value;
|
||||
v->next = head;
|
||||
head = v;
|
||||
}
|
||||
else if( flag == VAR_APPEND )
|
||||
{
|
||||
v->value = list_append( v->value, value );
|
||||
}
|
||||
else if( flag != VAR_DEFAULT )
|
||||
{
|
||||
list_free( v->value );
|
||||
v->value = value;
|
||||
}
|
||||
else
|
||||
list_free( value );
|
||||
|
||||
/* Return (new) head of list. */
|
||||
/* Return (new) head of list. */
|
||||
|
||||
return head;
|
||||
return head;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -466,8 +475,8 @@ addsettings(
|
||||
void
|
||||
pushsettings( SETTINGS *v )
|
||||
{
|
||||
for( ; v; v = v->next )
|
||||
v->value = var_swap( v->symbol, v->value );
|
||||
for( ; v; v = v->next )
|
||||
v->value = var_swap( v->symbol, v->value );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -477,7 +486,7 @@ pushsettings( SETTINGS *v )
|
||||
void
|
||||
popsettings( SETTINGS *v )
|
||||
{
|
||||
pushsettings( v ); /* just swap again */
|
||||
pushsettings( v ); /* just swap again */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -489,7 +498,7 @@ copysettings( SETTINGS *head )
|
||||
SETTINGS *copy = 0, *v;
|
||||
|
||||
for (v = head; v; v = v->next)
|
||||
copy = addsettings(copy, VAR_SET, v->symbol, list_copy(0, v->value));
|
||||
copy = addsettings(copy, VAR_SET, v->symbol, list_copy(0, v->value));
|
||||
|
||||
return copy;
|
||||
}
|
||||
@@ -528,17 +537,17 @@ void freeactions( ACTIONS *chain )
|
||||
void
|
||||
freesettings( SETTINGS *v )
|
||||
{
|
||||
while( v )
|
||||
{
|
||||
SETTINGS *n = v->next;
|
||||
while( v )
|
||||
{
|
||||
SETTINGS *n = v->next;
|
||||
|
||||
freestr( v->symbol );
|
||||
list_free( v->value );
|
||||
freestr( v->symbol );
|
||||
list_free( v->value );
|
||||
v->next = settings_freelist;
|
||||
settings_freelist = v;
|
||||
|
||||
v = n;
|
||||
}
|
||||
v = n;
|
||||
}
|
||||
}
|
||||
|
||||
static void freetarget( void *xt, void *data )
|
||||
@@ -562,7 +571,7 @@ void
|
||||
donerules()
|
||||
{
|
||||
hashenumerate( targethash, freetarget, 0 );
|
||||
hashdone( targethash );
|
||||
hashdone( targethash );
|
||||
while ( settings_freelist )
|
||||
{
|
||||
SETTINGS* n = settings_freelist->next;
|
||||
@@ -633,7 +642,7 @@ static void set_rule_body( RULE* rule, argument_list* args, PARSE* procedure )
|
||||
if ( rule->arguments )
|
||||
args_free( rule->arguments );
|
||||
rule->arguments = args;
|
||||
|
||||
|
||||
if ( procedure )
|
||||
parse_refer( procedure );
|
||||
if ( rule->procedure )
|
||||
@@ -688,7 +697,7 @@ RULE* new_rule_body( module_t* m, char* rulename, argument_list* args, PARSE* pr
|
||||
RULE* local = define_rule( m, rulename, m );
|
||||
local->exported = exported;
|
||||
set_rule_body( local, args, procedure );
|
||||
|
||||
|
||||
/* Mark the procedure with the global rule name, regardless of
|
||||
* whether the rule is exported. That gives us something
|
||||
* reasonably identifiable that we can use, e.g. in profiling
|
||||
@@ -708,7 +717,7 @@ static void set_rule_actions( RULE* rule, rule_actions* actions )
|
||||
if ( rule->actions )
|
||||
actions_free( rule->actions );
|
||||
rule->actions = actions;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static rule_actions* actions_new( char* command, LIST* bindlist, int flags )
|
||||
@@ -732,7 +741,7 @@ RULE* new_rule_actions( module_t* m, char* rulename, char* command, LIST* bindli
|
||||
|
||||
/* Looks for a rule in the specified module, and returns it, if found.
|
||||
First checks if the rule is present in the module's rule table.
|
||||
Second, if name of the rule is in the form name1.name2 and name1 is in
|
||||
Second, if name of the rule is in the form name1.name2 and name1 is in
|
||||
the list of imported modules, look in module 'name1' for rule 'name2'.
|
||||
*/
|
||||
RULE *lookup_rule( char *rulename, module_t *m, int local_only )
|
||||
@@ -757,7 +766,7 @@ RULE *lookup_rule( char *rulename, module_t *m, int local_only )
|
||||
result = lookup_rule(p+1, bindmodule(rulename), 1);
|
||||
}
|
||||
*p = '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
@@ -771,15 +780,15 @@ RULE *lookup_rule( char *rulename, module_t *m, int local_only )
|
||||
Mark it for execution in the instance where we've started lookup.
|
||||
*/
|
||||
int execute_in_class = (result->module == m);
|
||||
int execute_in_some_instance =
|
||||
int execute_in_some_instance =
|
||||
(result->module->class_module && result->module->class_module == m);
|
||||
if (original_module != m && (execute_in_class || execute_in_some_instance))
|
||||
result->module = original_module;
|
||||
result->module = original_module;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -790,7 +799,7 @@ RULE *bindrule( char *rulename, module_t* m)
|
||||
result = lookup_rule(rulename, m, 0);
|
||||
if (!result)
|
||||
result = lookup_rule(rulename, root_module(), 0);
|
||||
/* We've only one caller, 'evaluate_rule', which will complain about
|
||||
/* We've only one caller, 'evaluate_rule', which will complain about
|
||||
calling underfined rule. We could issue the error
|
||||
here, but we don't have necessary information, such as frame.
|
||||
*/
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
*
|
||||
* The following are defined:
|
||||
*
|
||||
* RULE - a generic jam rule, the product of RULE and ACTIONS
|
||||
* ACTIONS - a chain of ACTIONs
|
||||
* ACTION - a RULE instance with targets and sources
|
||||
* SETTINGS - variables to set when executing a TARGET's ACTIONS
|
||||
* TARGETS - a chain of TARGETs
|
||||
* TARGET - a file or "thing" that can be built
|
||||
* RULE - a generic jam rule, the product of RULE and ACTIONS
|
||||
* ACTIONS - a chain of ACTIONs
|
||||
* ACTION - a RULE instance with targets and sources
|
||||
* SETTINGS - variables to set when executing a TARGET's ACTIONS
|
||||
* TARGETS - a chain of TARGETs
|
||||
* TARGET - a file or "thing" that can be built
|
||||
*
|
||||
* 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET.
|
||||
* 04/12/94 (seiwald) - actionlist() now just appends a single action.
|
||||
@@ -77,77 +77,79 @@ struct rule_actions
|
||||
typedef struct rule_actions rule_actions;
|
||||
typedef struct argument_list argument_list;
|
||||
|
||||
struct _rule {
|
||||
char *name;
|
||||
PARSE *procedure; /* parse tree from RULE */
|
||||
argument_list* arguments; /* argument checking info, or NULL for unchecked */
|
||||
rule_actions* actions; /* build actions, or NULL for no actions */
|
||||
module_t *module; /* module in which this rule is executed */
|
||||
int exported; /* nonzero if this rule is supposed to
|
||||
* appear in the global module and be
|
||||
* automatically imported into other modules
|
||||
*/
|
||||
struct _rule
|
||||
{
|
||||
char * name;
|
||||
PARSE * procedure; /* parse tree from RULE */
|
||||
argument_list * arguments; /* argument checking info, or NULL for unchecked
|
||||
*/
|
||||
rule_actions * actions; /* build actions, or NULL for no actions */
|
||||
module_t * module; /* module in which this rule is executed */
|
||||
int exported; /* nonzero if this rule is supposed to appear in
|
||||
* the global module and be automatically
|
||||
* imported into other modules
|
||||
*/
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject* python_function;
|
||||
#endif
|
||||
PyObject * python_function;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ACTIONS - a chain of ACTIONs */
|
||||
|
||||
struct _actions {
|
||||
ACTIONS *next;
|
||||
ACTIONS *tail; /* valid only for head */
|
||||
ACTION *action;
|
||||
ACTIONS *next;
|
||||
ACTIONS *tail; /* valid only for head */
|
||||
ACTION *action;
|
||||
} ;
|
||||
|
||||
/* ACTION - a RULE instance with targets and sources */
|
||||
|
||||
struct _action {
|
||||
RULE *rule;
|
||||
TARGETS *targets;
|
||||
TARGETS *sources; /* aka $(>) */
|
||||
char running; /* has been started */
|
||||
char status; /* see TARGET status */
|
||||
RULE *rule;
|
||||
TARGETS *targets;
|
||||
TARGETS *sources; /* aka $(>) */
|
||||
char running; /* has been started */
|
||||
char status; /* see TARGET status */
|
||||
} ;
|
||||
|
||||
/* SETTINGS - variables to set when executing a TARGET's ACTIONS */
|
||||
|
||||
struct _settings {
|
||||
SETTINGS *next;
|
||||
char *symbol; /* symbol name for var_set() */
|
||||
LIST *value; /* symbol value for var_set() */
|
||||
SETTINGS *next;
|
||||
char *symbol; /* symbol name for var_set() */
|
||||
LIST *value; /* symbol value for var_set() */
|
||||
} ;
|
||||
|
||||
/* TARGETS - a chain of TARGETs */
|
||||
|
||||
struct _targets {
|
||||
TARGETS *next;
|
||||
TARGETS *tail; /* valid only for head */
|
||||
TARGET *target;
|
||||
TARGETS *next;
|
||||
TARGETS *tail; /* valid only for head */
|
||||
TARGET *target;
|
||||
} ;
|
||||
|
||||
/* TARGET - a file or "thing" that can be built */
|
||||
|
||||
struct _target {
|
||||
char *name;
|
||||
char *boundname; /* if search() relocates target */
|
||||
ACTIONS *actions; /* rules to execute, if any */
|
||||
SETTINGS *settings; /* variables to define */
|
||||
char *name;
|
||||
char *boundname; /* if search() relocates target */
|
||||
ACTIONS *actions; /* rules to execute, if any */
|
||||
SETTINGS *settings; /* variables to define */
|
||||
|
||||
short flags; /* status info */
|
||||
short flags; /* status info */
|
||||
|
||||
# define T_FLAG_TEMP 0x0001 /* TEMPORARY applied */
|
||||
# define T_FLAG_NOCARE 0x0002 /* NOCARE applied */
|
||||
# define T_FLAG_NOTFILE 0x0004 /* NOTFILE applied */
|
||||
# define T_FLAG_TOUCHED 0x0008 /* ALWAYS applied or -t target */
|
||||
# define T_FLAG_LEAVES 0x0010 /* LEAVES applied */
|
||||
# define T_FLAG_NOUPDATE 0x0020 /* NOUPDATE applied */
|
||||
# define T_FLAG_VISITED 0x0040 /* CWM: Used in debugging */
|
||||
# define T_FLAG_TEMP 0x0001 /* TEMPORARY applied */
|
||||
# define T_FLAG_NOCARE 0x0002 /* NOCARE applied */
|
||||
# define T_FLAG_NOTFILE 0x0004 /* NOTFILE applied */
|
||||
# define T_FLAG_TOUCHED 0x0008 /* ALWAYS applied or -t target */
|
||||
# define T_FLAG_LEAVES 0x0010 /* LEAVES applied */
|
||||
# define T_FLAG_NOUPDATE 0x0020 /* NOUPDATE applied */
|
||||
# define T_FLAG_VISITED 0x0040 /* CWM: Used in debugging */
|
||||
|
||||
/* this flag was added to support a new builtin rule named "RMBAD" */
|
||||
/* it is used to force removal of outdated targets whose dependencies
|
||||
* fail to build */
|
||||
|
||||
|
||||
# define T_FLAG_RMOLD 0x0080 /* RMBAD applied */
|
||||
|
||||
/* this flag was added to support a new builting rule named "FAIL_EXPECTED" */
|
||||
@@ -166,72 +168,72 @@ struct _target {
|
||||
|
||||
|
||||
#ifdef OPT_SEMAPHORE
|
||||
# define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */
|
||||
# define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */
|
||||
#endif
|
||||
|
||||
|
||||
char binding; /* how target relates to real file */
|
||||
char binding; /* how target relates to real file */
|
||||
|
||||
# define T_BIND_UNBOUND 0 /* a disembodied name */
|
||||
# define T_BIND_MISSING 1 /* couldn't find real file */
|
||||
# define T_BIND_UNBOUND 0 /* a disembodied name */
|
||||
# define T_BIND_MISSING 1 /* couldn't find real file */
|
||||
#ifdef OPT_SEMAPHORE
|
||||
TARGET *semaphore; /* used in serialization */
|
||||
TARGET *semaphore; /* used in serialization */
|
||||
#endif
|
||||
# define T_BIND_PARENTS 2 /* using parent's timestamp */
|
||||
# define T_BIND_EXISTS 3 /* real file, timestamp valid */
|
||||
# define T_BIND_PARENTS 2 /* using parent's timestamp */
|
||||
# define T_BIND_EXISTS 3 /* real file, timestamp valid */
|
||||
|
||||
TARGETS *depends; /* dependencies */
|
||||
TARGETS *dependents;/* the inverse of dependencies */
|
||||
TARGETS *depends; /* dependencies */
|
||||
TARGETS *dependents;/* the inverse of dependencies */
|
||||
TARGETS *rebuilds; /* targets that should be force-rebuilt whenever this one is */
|
||||
TARGET *includes; /* includes */
|
||||
TARGET *original_target; /* original_target->includes = this */
|
||||
TARGET *includes; /* internal includes node */
|
||||
TARGET *original_target; /* original_target->includes = this */
|
||||
char rescanned;
|
||||
|
||||
time_t time; /* update time */
|
||||
time_t leaf; /* update time of leaf sources */
|
||||
time_t time; /* update time */
|
||||
time_t leaf; /* update time of leaf sources */
|
||||
|
||||
char fate; /* make0()'s diagnosis */
|
||||
char fate; /* make0()'s diagnosis */
|
||||
|
||||
# define T_FATE_INIT 0 /* nothing done to target */
|
||||
# define T_FATE_MAKING 1 /* make0(target) on stack */
|
||||
# define T_FATE_INIT 0 /* nothing done to target */
|
||||
# define T_FATE_MAKING 1 /* make0(target) on stack */
|
||||
|
||||
# define T_FATE_STABLE 2 /* target didn't need updating */
|
||||
# define T_FATE_NEWER 3 /* target newer than parent */
|
||||
# define T_FATE_STABLE 2 /* target didn't need updating */
|
||||
# define T_FATE_NEWER 3 /* target newer than parent */
|
||||
|
||||
# define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */
|
||||
# define T_FATE_ISTMP 4 /* unneeded temp target oddly present */
|
||||
# define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */
|
||||
# define T_FATE_ISTMP 4 /* unneeded temp target oddly present */
|
||||
|
||||
# define T_FATE_BUILD 5 /* >= BUILD rebuilds target */
|
||||
# define T_FATE_TOUCHED 5 /* manually touched with -t */
|
||||
# define T_FATE_REBUILD 6
|
||||
# define T_FATE_MISSING 7 /* is missing, needs updating */
|
||||
# define T_FATE_NEEDTMP 8 /* missing temp that must be rebuild */
|
||||
# define T_FATE_OUTDATED 9 /* is out of date, needs updating */
|
||||
# define T_FATE_UPDATE 10 /* deps updated, needs updating */
|
||||
# define T_FATE_BUILD 5 /* >= BUILD rebuilds target */
|
||||
# define T_FATE_TOUCHED 5 /* manually touched with -t */
|
||||
# define T_FATE_REBUILD 6
|
||||
# define T_FATE_MISSING 7 /* is missing, needs updating */
|
||||
# define T_FATE_NEEDTMP 8 /* missing temp that must be rebuild */
|
||||
# define T_FATE_OUTDATED 9 /* is out of date, needs updating */
|
||||
# define T_FATE_UPDATE 10 /* deps updated, needs updating */
|
||||
|
||||
# define T_FATE_BROKEN 11 /* >= BROKEN ruins parents */
|
||||
# define T_FATE_CANTFIND 11 /* no rules to make missing target */
|
||||
# define T_FATE_CANTMAKE 12 /* can't find dependents */
|
||||
# define T_FATE_BROKEN 11 /* >= BROKEN ruins parents */
|
||||
# define T_FATE_CANTFIND 11 /* no rules to make missing target */
|
||||
# define T_FATE_CANTMAKE 12 /* can't find dependents */
|
||||
|
||||
char progress; /* tracks make1() progress */
|
||||
char progress; /* tracks make1() progress */
|
||||
|
||||
# define T_MAKE_INIT 0 /* make1(target) not yet called */
|
||||
# define T_MAKE_ONSTACK 1 /* make1(target) on stack */
|
||||
# define T_MAKE_ACTIVE 2 /* make1(target) in make1b() */
|
||||
# define T_MAKE_RUNNING 3 /* make1(target) running commands */
|
||||
# define T_MAKE_DONE 4 /* make1(target) done */
|
||||
# define T_MAKE_INIT 0 /* make1(target) not yet called */
|
||||
# define T_MAKE_ONSTACK 1 /* make1(target) on stack */
|
||||
# define T_MAKE_ACTIVE 2 /* make1(target) in make1b() */
|
||||
# define T_MAKE_RUNNING 3 /* make1(target) running commands */
|
||||
# define T_MAKE_DONE 4 /* make1(target) done */
|
||||
|
||||
char status; /* execcmd() result */
|
||||
char status; /* execcmd() result */
|
||||
|
||||
int asynccnt; /* child deps outstanding */
|
||||
TARGETS *parents; /* used by make1() for completion */
|
||||
char *cmds; /* type-punned command list */
|
||||
int asynccnt; /* child deps outstanding */
|
||||
TARGETS *parents; /* used by make1() for completion */
|
||||
char *cmds; /* type-punned command list */
|
||||
|
||||
char* failed;
|
||||
} ;
|
||||
|
||||
void add_include( TARGET * including, TARGET * included );
|
||||
RULE *bindrule( char *rulename, module_t* );
|
||||
void add_include( TARGET * including, TARGET * included );
|
||||
RULE * bindrule ( char * rulename, module_t* );
|
||||
|
||||
RULE* import_rule( RULE* source, module_t* m, char* name );
|
||||
RULE* new_rule_body( module_t* m, char* rulename, argument_list* args, PARSE* procedure, int exprt );
|
||||
@@ -240,7 +242,7 @@ TARGET *bindtarget( const char *targetname );
|
||||
TARGET *copytarget( const TARGET *t );
|
||||
void bind_explicitly_located_targets();
|
||||
TARGET* search_for_target( char * name, LIST* search_path );
|
||||
void touchtarget( char *t );
|
||||
void touchtarget( char *t );
|
||||
TARGETS *targetlist( TARGETS *chain, LIST *targets );
|
||||
TARGETS *targetentry( TARGETS *chain, TARGET *target );
|
||||
TARGETS *targetchain( TARGETS *chain, TARGETS *targets );
|
||||
@@ -248,12 +250,12 @@ void freetargets( TARGETS *chain );
|
||||
ACTIONS *actionlist( ACTIONS *chain, ACTION *action );
|
||||
void freeactions( ACTIONS *chain );
|
||||
SETTINGS *addsettings( SETTINGS *head, int flag, char *symbol, LIST *value );
|
||||
void pushsettings( SETTINGS *v );
|
||||
void popsettings( SETTINGS *v );
|
||||
void pushsettings( SETTINGS *v );
|
||||
void popsettings( SETTINGS *v );
|
||||
SETTINGS *copysettings( SETTINGS *v );
|
||||
void freesettings( SETTINGS *v );
|
||||
void freesettings( SETTINGS *v );
|
||||
void rule_free( RULE *r );
|
||||
void donerules();
|
||||
void donerules();
|
||||
|
||||
argument_list* args_new();
|
||||
void args_refer( argument_list* );
|
||||
|
||||
@@ -17,30 +17,30 @@
|
||||
*
|
||||
* 12/26/93 (seiwald) - bump buf in yylex to 10240 - yuk.
|
||||
* 09/16/94 (seiwald) - check for overflows, unmatched {}'s, etc.
|
||||
* Also handle tokens abutting EOF by remembering
|
||||
* to return EOF now matter how many times yylex()
|
||||
* reinvokes yyline().
|
||||
* Also handle tokens abutting EOF by remembering
|
||||
* to return EOF now matter how many times yylex()
|
||||
* reinvokes yyline().
|
||||
* 02/11/95 (seiwald) - honor only punctuation keywords if SCAN_PUNCT.
|
||||
* 07/27/95 (seiwald) - Include jamgram.h after scan.h, so that YYSTYPE is
|
||||
* defined before Linux's yacc tries to redefine it.
|
||||
* defined before Linux's yacc tries to redefine it.
|
||||
*/
|
||||
|
||||
struct keyword {
|
||||
char *word;
|
||||
int type;
|
||||
char *word;
|
||||
int type;
|
||||
} keywords[] = {
|
||||
# include "jamgramtab.h"
|
||||
{ 0, 0 }
|
||||
{ 0, 0 }
|
||||
} ;
|
||||
|
||||
struct include {
|
||||
struct include *next; /* next serial include file */
|
||||
char *string; /* pointer into current line */
|
||||
char **strings; /* for yyfparse() -- text to parse */
|
||||
FILE *file; /* for yyfparse() -- file being read */
|
||||
char *fname; /* for yyfparse() -- file name */
|
||||
int line; /* line counter for error messages */
|
||||
char buf[ 512 ]; /* for yyfparse() -- line buffer */
|
||||
struct include *next; /* next serial include file */
|
||||
char *string; /* pointer into current line */
|
||||
char **strings; /* for yyfparse() -- text to parse */
|
||||
FILE *file; /* for yyfparse() -- file being read */
|
||||
char *fname; /* for yyfparse() -- file name */
|
||||
int line; /* line counter for error messages */
|
||||
char buf[ 512 ]; /* for yyfparse() -- line buffer */
|
||||
} ;
|
||||
|
||||
static struct include *incp = 0; /* current file; head of chain */
|
||||
@@ -49,54 +49,54 @@ static int scanmode = SCAN_NORMAL;
|
||||
static int anyerrors = 0;
|
||||
static char *symdump( YYSTYPE *s );
|
||||
|
||||
# define BIGGEST_TOKEN 10240 /* no single token can be larger */
|
||||
# define BIGGEST_TOKEN 10240 /* no single token can be larger */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Set parser mode: normal, string, or keyword
|
||||
*/
|
||||
|
||||
void
|
||||
yymode( int n )
|
||||
{
|
||||
scanmode = n;
|
||||
scanmode = n;
|
||||
}
|
||||
|
||||
void
|
||||
yyerror( char *s )
|
||||
{
|
||||
if( incp )
|
||||
printf( "%s:%d: ", incp->fname, incp->line );
|
||||
if( incp )
|
||||
printf( "%s:%d: ", incp->fname, incp->line );
|
||||
|
||||
printf( "%s at %s\n", s, symdump( &yylval ) );
|
||||
printf( "%s at %s\n", s, symdump( &yylval ) );
|
||||
|
||||
++anyerrors;
|
||||
++anyerrors;
|
||||
}
|
||||
|
||||
int
|
||||
yyanyerrors()
|
||||
{
|
||||
return anyerrors != 0;
|
||||
return anyerrors != 0;
|
||||
}
|
||||
|
||||
void
|
||||
yyfparse( char *s )
|
||||
{
|
||||
struct include *i = (struct include *)BJAM_MALLOC( sizeof( *i ) );
|
||||
struct include *i = (struct include *)BJAM_MALLOC( sizeof( *i ) );
|
||||
|
||||
/* Push this onto the incp chain. */
|
||||
/* Push this onto the incp chain. */
|
||||
|
||||
i->string = "";
|
||||
i->strings = 0;
|
||||
i->file = 0;
|
||||
i->fname = copystr( s );
|
||||
i->line = 0;
|
||||
i->next = incp;
|
||||
incp = i;
|
||||
i->string = "";
|
||||
i->strings = 0;
|
||||
i->file = 0;
|
||||
i->fname = copystr( s );
|
||||
i->line = 0;
|
||||
i->next = incp;
|
||||
incp = i;
|
||||
|
||||
/* If the filename is "+", it means use the internal jambase. */
|
||||
/* If the filename is "+", it means use the internal jambase. */
|
||||
|
||||
if( !strcmp( s, "+" ) )
|
||||
i->strings = jambase;
|
||||
if( !strcmp( s, "+" ) )
|
||||
i->strings = jambase;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -109,68 +109,68 @@ yyfparse( char *s )
|
||||
int
|
||||
yyline()
|
||||
{
|
||||
struct include *i = incp;
|
||||
struct include *i = incp;
|
||||
|
||||
if( !incp )
|
||||
return EOF;
|
||||
if( !incp )
|
||||
return EOF;
|
||||
|
||||
/* Once we start reading from the input stream, we reset the */
|
||||
/* include insertion point so that the next include file becomes */
|
||||
/* the head of the list. */
|
||||
/* Once we start reading from the input stream, we reset the */
|
||||
/* include insertion point so that the next include file becomes */
|
||||
/* the head of the list. */
|
||||
|
||||
/* If there is more data in this line, return it. */
|
||||
/* If there is more data in this line, return it. */
|
||||
|
||||
if( *i->string )
|
||||
return *i->string++;
|
||||
if( *i->string )
|
||||
return *i->string++;
|
||||
|
||||
/* If we're reading from an internal string list, go to the */
|
||||
/* next string. */
|
||||
/* If we're reading from an internal string list, go to the */
|
||||
/* next string. */
|
||||
|
||||
if( i->strings )
|
||||
{
|
||||
if( !*i->strings )
|
||||
goto next;
|
||||
if( i->strings )
|
||||
{
|
||||
if( !*i->strings )
|
||||
goto next;
|
||||
|
||||
i->line++;
|
||||
i->string = *(i->strings++);
|
||||
return *i->string++;
|
||||
}
|
||||
i->line++;
|
||||
i->string = *(i->strings++);
|
||||
return *i->string++;
|
||||
}
|
||||
|
||||
/* If necessary, open the file */
|
||||
/* If necessary, open the file */
|
||||
|
||||
if( !i->file )
|
||||
{
|
||||
FILE *f = stdin;
|
||||
if( !i->file )
|
||||
{
|
||||
FILE *f = stdin;
|
||||
|
||||
if( strcmp( i->fname, "-" ) && !( f = fopen( i->fname, "r" ) ) )
|
||||
perror( i->fname );
|
||||
if( strcmp( i->fname, "-" ) && !( f = fopen( i->fname, "r" ) ) )
|
||||
perror( i->fname );
|
||||
|
||||
i->file = f;
|
||||
}
|
||||
i->file = f;
|
||||
}
|
||||
|
||||
/* If there's another line in this file, start it. */
|
||||
/* If there's another line in this file, start it. */
|
||||
|
||||
if( i->file && fgets( i->buf, sizeof( i->buf ), i->file ) )
|
||||
{
|
||||
i->line++;
|
||||
i->string = i->buf;
|
||||
return *i->string++;
|
||||
}
|
||||
if( i->file && fgets( i->buf, sizeof( i->buf ), i->file ) )
|
||||
{
|
||||
i->line++;
|
||||
i->string = i->buf;
|
||||
return *i->string++;
|
||||
}
|
||||
|
||||
next:
|
||||
/* This include is done. */
|
||||
/* Free it up and return EOF so yyparse() returns to parse_file(). */
|
||||
/* This include is done. */
|
||||
/* Free it up and return EOF so yyparse() returns to parse_file(). */
|
||||
|
||||
incp = i->next;
|
||||
incp = i->next;
|
||||
|
||||
/* Close file, free name */
|
||||
/* Close file, free name */
|
||||
|
||||
if( i->file && i->file != stdin )
|
||||
fclose( i->file );
|
||||
freestr( i->fname );
|
||||
BJAM_FREE( (char *)i );
|
||||
if( i->file && i->file != stdin )
|
||||
fclose( i->file );
|
||||
freestr( i->fname );
|
||||
BJAM_FREE( (char *)i );
|
||||
|
||||
return EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -178,8 +178,8 @@ yyline()
|
||||
*
|
||||
* Macros to move things along:
|
||||
*
|
||||
* yychar() - return and advance character; invalid after EOF
|
||||
* yyprev() - back up one character; invalid before yychar()
|
||||
* yychar() - return and advance character; invalid after EOF
|
||||
* yyprev() - back up one character; invalid before yychar()
|
||||
*
|
||||
* yychar() returns a continuous stream of characters, until it hits
|
||||
* the EOF of the current include file.
|
||||
@@ -191,80 +191,80 @@ yyline()
|
||||
int
|
||||
yylex()
|
||||
{
|
||||
int c;
|
||||
char buf[BIGGEST_TOKEN];
|
||||
char *b = buf;
|
||||
int c;
|
||||
char buf[BIGGEST_TOKEN];
|
||||
char *b = buf;
|
||||
|
||||
if( !incp )
|
||||
goto eof;
|
||||
if( !incp )
|
||||
goto eof;
|
||||
|
||||
/* Get first character (whitespace or of token) */
|
||||
/* Get first character (whitespace or of token) */
|
||||
|
||||
c = yychar();
|
||||
c = yychar();
|
||||
|
||||
if( scanmode == SCAN_STRING )
|
||||
{
|
||||
/* If scanning for a string (action's {}'s), look for the */
|
||||
/* closing brace. We handle matching braces, if they match! */
|
||||
if( scanmode == SCAN_STRING )
|
||||
{
|
||||
/* If scanning for a string (action's {}'s), look for the */
|
||||
/* closing brace. We handle matching braces, if they match! */
|
||||
|
||||
int nest = 1;
|
||||
int nest = 1;
|
||||
|
||||
while( c != EOF && b < buf + sizeof( buf ) )
|
||||
{
|
||||
if( c == '{' )
|
||||
nest++;
|
||||
while( c != EOF && b < buf + sizeof( buf ) )
|
||||
{
|
||||
if( c == '{' )
|
||||
nest++;
|
||||
|
||||
if( c == '}' && !--nest )
|
||||
break;
|
||||
if( c == '}' && !--nest )
|
||||
break;
|
||||
|
||||
*b++ = c;
|
||||
*b++ = c;
|
||||
|
||||
c = yychar();
|
||||
c = yychar();
|
||||
|
||||
/* turn trailing "\r\n" sequences into plain "\n"
|
||||
* for Cygwin
|
||||
*/
|
||||
if (c == '\n' && b[-1] == '\r')
|
||||
--b;
|
||||
}
|
||||
}
|
||||
|
||||
/* We ate the ending brace -- regurgitate it. */
|
||||
/* We ate the ending brace -- regurgitate it. */
|
||||
|
||||
if( c != EOF )
|
||||
yyprev();
|
||||
if( c != EOF )
|
||||
yyprev();
|
||||
|
||||
/* Check obvious errors. */
|
||||
/* Check obvious errors. */
|
||||
|
||||
if( b == buf + sizeof( buf ) )
|
||||
{
|
||||
yyerror( "action block too big" );
|
||||
goto eof;
|
||||
}
|
||||
if( b == buf + sizeof( buf ) )
|
||||
{
|
||||
yyerror( "action block too big" );
|
||||
goto eof;
|
||||
}
|
||||
|
||||
if( nest )
|
||||
{
|
||||
yyerror( "unmatched {} in action block" );
|
||||
goto eof;
|
||||
}
|
||||
if( nest )
|
||||
{
|
||||
yyerror( "unmatched {} in action block" );
|
||||
goto eof;
|
||||
}
|
||||
|
||||
*b = 0;
|
||||
yylval.type = STRING;
|
||||
yylval.string = newstr( buf );
|
||||
*b = 0;
|
||||
yylval.type = STRING;
|
||||
yylval.string = newstr( buf );
|
||||
yylval.file = incp->fname;
|
||||
yylval.line = incp->line;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
char *b = buf;
|
||||
struct keyword *k;
|
||||
int inquote = 0;
|
||||
int notkeyword;
|
||||
|
||||
/* Eat white space */
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
char *b = buf;
|
||||
struct keyword *k;
|
||||
int inquote = 0;
|
||||
int notkeyword;
|
||||
|
||||
/* Eat white space */
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Skip past white space */
|
||||
|
||||
while( c != EOF && isspace( c ) )
|
||||
@@ -276,134 +276,134 @@ yylex()
|
||||
break;
|
||||
while( ( c = yychar() ) != EOF && c != '\n' )
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/* c now points to the first character of a token. */
|
||||
/* c now points to the first character of a token. */
|
||||
|
||||
if( c == EOF )
|
||||
goto eof;
|
||||
if( c == EOF )
|
||||
goto eof;
|
||||
|
||||
yylval.file = incp->fname;
|
||||
yylval.line = incp->line;
|
||||
|
||||
/* While scanning the word, disqualify it for (expensive) */
|
||||
/* keyword lookup when we can: $anything, "anything", \anything */
|
||||
|
||||
notkeyword = c == '$';
|
||||
/* While scanning the word, disqualify it for (expensive) */
|
||||
/* keyword lookup when we can: $anything, "anything", \anything */
|
||||
|
||||
/* look for white space to delimit word */
|
||||
/* "'s get stripped but preserve white space */
|
||||
/* \ protects next character */
|
||||
notkeyword = c == '$';
|
||||
|
||||
while(
|
||||
c != EOF &&
|
||||
b < buf + sizeof( buf ) &&
|
||||
( inquote || !isspace( c ) ) )
|
||||
{
|
||||
if( c == '"' )
|
||||
{
|
||||
/* begin or end " */
|
||||
inquote = !inquote;
|
||||
notkeyword = 1;
|
||||
}
|
||||
else if( c != '\\' )
|
||||
{
|
||||
/* normal char */
|
||||
*b++ = c;
|
||||
}
|
||||
else if( ( c = yychar()) != EOF )
|
||||
{
|
||||
/* \c */
|
||||
*b++ = c;
|
||||
notkeyword = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* \EOF */
|
||||
break;
|
||||
}
|
||||
/* look for white space to delimit word */
|
||||
/* "'s get stripped but preserve white space */
|
||||
/* \ protects next character */
|
||||
|
||||
c = yychar();
|
||||
}
|
||||
while(
|
||||
c != EOF &&
|
||||
b < buf + sizeof( buf ) &&
|
||||
( inquote || !isspace( c ) ) )
|
||||
{
|
||||
if( c == '"' )
|
||||
{
|
||||
/* begin or end " */
|
||||
inquote = !inquote;
|
||||
notkeyword = 1;
|
||||
}
|
||||
else if( c != '\\' )
|
||||
{
|
||||
/* normal char */
|
||||
*b++ = c;
|
||||
}
|
||||
else if( ( c = yychar()) != EOF )
|
||||
{
|
||||
/* \c */
|
||||
*b++ = c;
|
||||
notkeyword = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* \EOF */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check obvious errors. */
|
||||
c = yychar();
|
||||
}
|
||||
|
||||
if( b == buf + sizeof( buf ) )
|
||||
{
|
||||
yyerror( "string too big" );
|
||||
goto eof;
|
||||
}
|
||||
/* Check obvious errors. */
|
||||
|
||||
if( inquote )
|
||||
{
|
||||
yyerror( "unmatched \" in string" );
|
||||
goto eof;
|
||||
}
|
||||
if( b == buf + sizeof( buf ) )
|
||||
{
|
||||
yyerror( "string too big" );
|
||||
goto eof;
|
||||
}
|
||||
|
||||
/* We looked ahead a character - back up. */
|
||||
if( inquote )
|
||||
{
|
||||
yyerror( "unmatched \" in string" );
|
||||
goto eof;
|
||||
}
|
||||
|
||||
if( c != EOF )
|
||||
yyprev();
|
||||
/* We looked ahead a character - back up. */
|
||||
|
||||
/* scan token table */
|
||||
/* don't scan if it's obviously not a keyword or if its */
|
||||
/* an alphabetic when were looking for punctuation */
|
||||
if( c != EOF )
|
||||
yyprev();
|
||||
|
||||
*b = 0;
|
||||
yylval.type = ARG;
|
||||
/* scan token table */
|
||||
/* don't scan if it's obviously not a keyword or if its */
|
||||
/* an alphabetic when were looking for punctuation */
|
||||
|
||||
if( !notkeyword && !( isalpha( *buf ) && scanmode == SCAN_PUNCT ) )
|
||||
{
|
||||
for( k = keywords; k->word; k++ )
|
||||
if( *buf == *k->word && !strcmp( k->word, buf ) )
|
||||
{
|
||||
yylval.type = k->type;
|
||||
yylval.string = k->word; /* used by symdump */
|
||||
break;
|
||||
}
|
||||
}
|
||||
*b = 0;
|
||||
yylval.type = ARG;
|
||||
|
||||
if( yylval.type == ARG )
|
||||
yylval.string = newstr( buf );
|
||||
}
|
||||
if( !notkeyword && !( isalpha( *buf ) && scanmode == SCAN_PUNCT ) )
|
||||
{
|
||||
for( k = keywords; k->word; k++ )
|
||||
if( *buf == *k->word && !strcmp( k->word, buf ) )
|
||||
{
|
||||
yylval.type = k->type;
|
||||
yylval.string = k->word; /* used by symdump */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( DEBUG_SCAN )
|
||||
printf( "scan %s\n", symdump( &yylval ) );
|
||||
if( yylval.type == ARG )
|
||||
yylval.string = newstr( buf );
|
||||
}
|
||||
|
||||
return yylval.type;
|
||||
if( DEBUG_SCAN )
|
||||
printf( "scan %s\n", symdump( &yylval ) );
|
||||
|
||||
return yylval.type;
|
||||
|
||||
eof:
|
||||
yylval.file = "end-of-input"; /* just in case */
|
||||
yylval.line = 0;
|
||||
|
||||
yylval.type = EOF;
|
||||
return yylval.type;
|
||||
|
||||
yylval.type = EOF;
|
||||
return yylval.type;
|
||||
}
|
||||
|
||||
static char *
|
||||
symdump( YYSTYPE *s )
|
||||
{
|
||||
static char buf[ BIGGEST_TOKEN + 20 ];
|
||||
static char buf[ BIGGEST_TOKEN + 20 ];
|
||||
|
||||
switch( s->type )
|
||||
{
|
||||
case EOF:
|
||||
sprintf( buf, "EOF" );
|
||||
break;
|
||||
case 0:
|
||||
sprintf( buf, "unknown symbol %s", s->string );
|
||||
break;
|
||||
case ARG:
|
||||
sprintf( buf, "argument %s", s->string );
|
||||
break;
|
||||
case STRING:
|
||||
sprintf( buf, "string \"%s\"", s->string );
|
||||
break;
|
||||
default:
|
||||
sprintf( buf, "keyword %s", s->string );
|
||||
break;
|
||||
}
|
||||
return buf;
|
||||
switch( s->type )
|
||||
{
|
||||
case EOF:
|
||||
sprintf( buf, "EOF" );
|
||||
break;
|
||||
case 0:
|
||||
sprintf( buf, "unknown symbol %s", s->string );
|
||||
break;
|
||||
case ARG:
|
||||
sprintf( buf, "argument %s", s->string );
|
||||
break;
|
||||
case STRING:
|
||||
sprintf( buf, "string \"%s\"", s->string );
|
||||
break;
|
||||
default:
|
||||
sprintf( buf, "keyword %s", s->string );
|
||||
break;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Get information about the current file and line, for those epsilon
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
*
|
||||
* External functions:
|
||||
*
|
||||
* yyerror( char *s ) - print a parsing error message
|
||||
* yyfparse( char *s ) - scan include file s
|
||||
* yylex() - parse the next token, returning its type
|
||||
* yymode() - adjust lexicon of scanner
|
||||
* yyparse() - declaration for yacc parser
|
||||
* yyanyerrors() - indicate if any parsing errors occured
|
||||
* yyerror( char *s ) - print a parsing error message
|
||||
* yyfparse( char *s ) - scan include file s
|
||||
* yylex() - parse the next token, returning its type
|
||||
* yymode() - adjust lexicon of scanner
|
||||
* yyparse() - declaration for yacc parser
|
||||
* yyanyerrors() - indicate if any parsing errors occured
|
||||
*
|
||||
* The yymode() function is for the parser to adjust the lexicon of the
|
||||
* scanner. Aside from normal keyword scanning, there is a mode to
|
||||
* handle action strings (look only for the closing }) and a mode to
|
||||
* ignore most keywords when looking for a punctuation keyword. This
|
||||
* handle action strings (look only for the closing }) and a mode to
|
||||
* ignore most keywords when looking for a punctuation keyword. This
|
||||
* allows non-punctuation keywords to be used in lists without quoting.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,6 @@ int yylex();
|
||||
int yyparse();
|
||||
void yyinput_stream( char** name, int* line );
|
||||
|
||||
# define SCAN_NORMAL 0 /* normal parsing */
|
||||
# define SCAN_STRING 1 /* look only for matching } */
|
||||
# define SCAN_PUNCT 2 /* only punctuation keywords */
|
||||
# define SCAN_NORMAL 0 /* normal parsing */
|
||||
# define SCAN_STRING 1 /* look only for matching } */
|
||||
# define SCAN_PUNCT 2 /* only punctuation keywords */
|
||||
|
||||
@@ -40,7 +40,7 @@ void call_bind_rule(
|
||||
/* No guarantee that target is an allocated string, so be on the
|
||||
* safe side */
|
||||
char* target = copystr( target_ );
|
||||
|
||||
|
||||
/* Likewise, don't rely on implementation details of newstr.c: allocate
|
||||
* a copy of boundname */
|
||||
char* boundname = copystr( boundname_ );
|
||||
@@ -49,14 +49,14 @@ void call_bind_rule(
|
||||
/* Prepare the argument list */
|
||||
FRAME frame[1];
|
||||
frame_init( frame );
|
||||
|
||||
|
||||
/* First argument is the target name */
|
||||
lol_add( frame->args, list_new( L0, target ) );
|
||||
|
||||
|
||||
lol_add( frame->args, list_new( L0, boundname ) );
|
||||
if( lol_get( frame->args, 1 ) )
|
||||
evaluate_rule( bind_rule->string, frame );
|
||||
|
||||
|
||||
/* Clean up */
|
||||
frame_free( frame );
|
||||
}
|
||||
@@ -71,14 +71,14 @@ void call_bind_rule(
|
||||
}
|
||||
|
||||
/*
|
||||
* search.c - find a target along $(SEARCH) or $(LOCATE)
|
||||
* search.c - find a target along $(SEARCH) or $(LOCATE)
|
||||
* First, check if LOCATE is set. If so, use it to determine
|
||||
* the location of target and return, regardless of whether anything
|
||||
* exists on that location.
|
||||
*
|
||||
* Second, examine all directories in SEARCH. If there's file already
|
||||
* or there's another target with the same name which was placed
|
||||
* to this location via LOCATE setting, stop and return the location.
|
||||
* to this location via LOCATE setting, stop and return the location.
|
||||
* In case of previous target, return it's name via the third argument.
|
||||
*
|
||||
* This bevahiour allow to handle dependency on generated files. If
|
||||
@@ -87,14 +87,14 @@ void call_bind_rule(
|
||||
*/
|
||||
|
||||
char *
|
||||
search(
|
||||
search(
|
||||
char *target,
|
||||
time_t *time,
|
||||
char **another_target,
|
||||
int file
|
||||
)
|
||||
{
|
||||
PATHNAME f[1];
|
||||
PATHNAME f[1];
|
||||
LIST *varlist;
|
||||
string buf[1];
|
||||
int found = 0;
|
||||
@@ -106,13 +106,13 @@ search(
|
||||
*another_target = 0;
|
||||
|
||||
if (! explicit_bindings )
|
||||
explicit_bindings = hashinit( sizeof(BINDING),
|
||||
explicit_bindings = hashinit( sizeof(BINDING),
|
||||
"explicitly specified locations");
|
||||
|
||||
string_new( buf );
|
||||
/* Parse the filename */
|
||||
|
||||
path_parse( target, f );
|
||||
path_parse( target, f );
|
||||
|
||||
f->f_grist.ptr = 0;
|
||||
f->f_grist.len = 0;
|
||||
@@ -122,7 +122,7 @@ search(
|
||||
f->f_root.ptr = varlist->string;
|
||||
f->f_root.len = strlen( varlist->string );
|
||||
|
||||
path_build( f, buf, 1 );
|
||||
path_build( f, buf, 1 );
|
||||
|
||||
if( DEBUG_SEARCH )
|
||||
printf( "locate %s: %s\n", target, buf->value );
|
||||
@@ -152,16 +152,16 @@ search(
|
||||
timestamp( buf->value, time );
|
||||
|
||||
b.binding = buf->value;
|
||||
|
||||
|
||||
if( hashcheck( explicit_bindings, (HASHDATA**)&ba ) )
|
||||
{
|
||||
if( DEBUG_SEARCH )
|
||||
printf(" search %s: found explicitly located target %s\n",
|
||||
printf(" search %s: found explicitly located target %s\n",
|
||||
target, ba->target);
|
||||
if( another_target )
|
||||
*another_target = ba->target;
|
||||
found = 1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else if( ff && ff->time )
|
||||
{
|
||||
@@ -207,7 +207,7 @@ search(
|
||||
compatibility, though. */
|
||||
hashenter(explicit_bindings, (HASHDATA**)&ba);
|
||||
}
|
||||
|
||||
|
||||
/* prepare a call to BINDRULE if the variable is set */
|
||||
call_bind_rule( target, boundname );
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* search.h - find a target along $(SEARCH) or $(LOCATE)
|
||||
* search.h - find a target along $(SEARCH) or $(LOCATE)
|
||||
*/
|
||||
|
||||
char *search( char *target, time_t *time, char **another_target, int file );
|
||||
|
||||
@@ -24,7 +24,7 @@ static void assert_invariants( string* self )
|
||||
assert( self->opt[0] == 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
assert( self->size < self->capacity );
|
||||
assert( ( self->capacity <= sizeof(self->opt) ) == ( self->value == self->opt ) );
|
||||
assert( strlen( self->value ) == self->size );
|
||||
@@ -106,10 +106,10 @@ void string_append( string* self, char const* rhs )
|
||||
char* p = self->value + self->size;
|
||||
char* end = self->value + self->capacity;
|
||||
assert_invariants( self );
|
||||
|
||||
|
||||
while ( *rhs && p != end)
|
||||
*p++ = *rhs++;
|
||||
|
||||
|
||||
if ( p != end )
|
||||
{
|
||||
*p = 0;
|
||||
@@ -127,10 +127,10 @@ void string_append_range( string* self, char const* start, char const* finish )
|
||||
char* p = self->value + self->size;
|
||||
char* end = self->value + self->capacity;
|
||||
assert_invariants( self );
|
||||
|
||||
|
||||
while ( p != end && start != finish )
|
||||
*p++ = *start++;
|
||||
|
||||
|
||||
if ( p != end )
|
||||
{
|
||||
*p = 0;
|
||||
@@ -182,7 +182,7 @@ void string_unit_test()
|
||||
int limit = sizeof(buffer) > 254 ? 254 : sizeof(buffer);
|
||||
|
||||
string_new(s);
|
||||
|
||||
|
||||
for (i = 0; i < limit; ++i)
|
||||
{
|
||||
string_push_back( s, (char)(i + 1) );
|
||||
@@ -195,7 +195,7 @@ void string_unit_test()
|
||||
}
|
||||
|
||||
string_free(s);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -22,13 +22,13 @@ regexp* regex_compile( const char* pattern )
|
||||
{
|
||||
regex_entry entry, *e = &entry;
|
||||
entry.pattern = pattern;
|
||||
|
||||
|
||||
if ( !regex_hash )
|
||||
regex_hash = hashinit(sizeof(regex_entry), "regex");
|
||||
|
||||
|
||||
if ( hashenter( regex_hash, (HASHDATA **)&e ) )
|
||||
e->regex = regcomp( (char*)pattern );
|
||||
|
||||
|
||||
return e->regex;
|
||||
}
|
||||
|
||||
@@ -36,13 +36,13 @@ LIST*
|
||||
builtin_subst(
|
||||
PARSE *parse,
|
||||
FRAME *frame )
|
||||
{
|
||||
{
|
||||
LIST* result = L0;
|
||||
LIST* arg1 = lol_get( frame->args, 0 );
|
||||
|
||||
if ( arg1 && list_next(arg1) && list_next(list_next(arg1)) )
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
const char* source = arg1->string;
|
||||
const char* pattern = list_next(arg1)->string;
|
||||
regexp* repat = regex_compile( pattern );
|
||||
@@ -50,7 +50,7 @@ builtin_subst(
|
||||
if ( regexec( repat, (char*)source) )
|
||||
{
|
||||
LIST* subst = list_next(arg1);
|
||||
|
||||
|
||||
while ((subst = list_next(subst)) != L0)
|
||||
{
|
||||
# define BUFLEN 4096
|
||||
@@ -88,7 +88,7 @@ builtin_subst(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,20 +32,20 @@
|
||||
typedef struct _binding BINDING;
|
||||
|
||||
struct _binding {
|
||||
char *name;
|
||||
short flags;
|
||||
char *name;
|
||||
short flags;
|
||||
|
||||
# define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
|
||||
# define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
|
||||
|
||||
short progress;
|
||||
short progress;
|
||||
|
||||
# define BIND_INIT 0 /* never seen */
|
||||
# define BIND_NOENTRY 1 /* timestamp requested but file never found */
|
||||
# define BIND_SPOTTED 2 /* file found but not timed yet */
|
||||
# define BIND_MISSING 3 /* file found but can't get timestamp */
|
||||
# define BIND_FOUND 4 /* file found and time stamped */
|
||||
# define BIND_INIT 0 /* never seen */
|
||||
# define BIND_NOENTRY 1 /* timestamp requested but file never found */
|
||||
# define BIND_SPOTTED 2 /* file found but not timed yet */
|
||||
# define BIND_MISSING 3 /* file found but can't get timestamp */
|
||||
# define BIND_FOUND 4 /* file found and time stamped */
|
||||
|
||||
time_t time; /* update time - 0 if not exist */
|
||||
time_t time; /* update time - 0 if not exist */
|
||||
} ;
|
||||
|
||||
static struct hash *bindhash = 0;
|
||||
@@ -53,11 +53,11 @@ static void time_enter( void *, char *, int , time_t );
|
||||
|
||||
static char *time_progress[] =
|
||||
{
|
||||
"INIT",
|
||||
"NOENTRY",
|
||||
"SPOTTED",
|
||||
"MISSING",
|
||||
"FOUND"
|
||||
"INIT",
|
||||
"NOENTRY",
|
||||
"SPOTTED",
|
||||
"MISSING",
|
||||
"FOUND"
|
||||
} ;
|
||||
|
||||
|
||||
@@ -66,159 +66,159 @@ static char *time_progress[] =
|
||||
*/
|
||||
|
||||
void
|
||||
timestamp(
|
||||
char *target,
|
||||
time_t *time )
|
||||
timestamp(
|
||||
char *target,
|
||||
time_t *time )
|
||||
{
|
||||
PROFILE_ENTER(timestamp);
|
||||
|
||||
PATHNAME f1, f2;
|
||||
BINDING binding, *b = &binding;
|
||||
string buf[1];
|
||||
string path;
|
||||
char *p;
|
||||
|
||||
PATHNAME f1, f2;
|
||||
BINDING binding, *b = &binding;
|
||||
string buf[1];
|
||||
string path;
|
||||
char *p;
|
||||
|
||||
# ifdef DOWNSHIFT_PATHS
|
||||
|
||||
string_copy( &path, target );
|
||||
p = path.value;
|
||||
|
||||
do
|
||||
do
|
||||
{
|
||||
*p = tolower( *p );
|
||||
# ifdef NT
|
||||
/* On NT, we must use backslashes or the file won't be found. */
|
||||
if (*p == '/')
|
||||
*p = PATH_DELIM;
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
while( *p++ );
|
||||
while( *p++ );
|
||||
|
||||
target = path.value;
|
||||
target = path.value;
|
||||
# endif
|
||||
string_new( buf );
|
||||
|
||||
if( !bindhash )
|
||||
bindhash = hashinit( sizeof( BINDING ), "bindings" );
|
||||
if( !bindhash )
|
||||
bindhash = hashinit( sizeof( BINDING ), "bindings" );
|
||||
|
||||
/* Quick path - is it there? */
|
||||
/* Quick path - is it there? */
|
||||
|
||||
b->name = target;
|
||||
b->time = b->flags = 0;
|
||||
b->progress = BIND_INIT;
|
||||
b->name = target;
|
||||
b->time = b->flags = 0;
|
||||
b->progress = BIND_INIT;
|
||||
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( target ); /* never freed */
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( target ); /* never freed */
|
||||
|
||||
if( b->progress != BIND_INIT )
|
||||
goto afterscanning;
|
||||
if( b->progress != BIND_INIT )
|
||||
goto afterscanning;
|
||||
|
||||
b->progress = BIND_NOENTRY;
|
||||
b->progress = BIND_NOENTRY;
|
||||
|
||||
/* Not found - have to scan for it */
|
||||
/* Not found - have to scan for it */
|
||||
|
||||
path_parse( target, &f1 );
|
||||
path_parse( target, &f1 );
|
||||
|
||||
/* Scan directory if not already done so */
|
||||
/* Scan directory if not already done so */
|
||||
|
||||
{
|
||||
BINDING binding, *b = &binding;
|
||||
{
|
||||
BINDING binding, *b = &binding;
|
||||
|
||||
f2 = f1;
|
||||
f2.f_grist.len = 0;
|
||||
path_parent( &f2 );
|
||||
path_build( &f2, buf, 0 );
|
||||
f2 = f1;
|
||||
f2.f_grist.len = 0;
|
||||
path_parent( &f2 );
|
||||
path_build( &f2, buf, 0 );
|
||||
|
||||
b->name = buf->value;
|
||||
b->time = b->flags = 0;
|
||||
b->progress = BIND_INIT;
|
||||
b->name = buf->value;
|
||||
b->time = b->flags = 0;
|
||||
b->progress = BIND_INIT;
|
||||
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( buf->value ); /* never freed */
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( buf->value ); /* never freed */
|
||||
|
||||
if( !( b->flags & BIND_SCANNED ) )
|
||||
{
|
||||
file_dirscan( buf->value, time_enter, bindhash );
|
||||
b->flags |= BIND_SCANNED;
|
||||
}
|
||||
}
|
||||
if( !( b->flags & BIND_SCANNED ) )
|
||||
{
|
||||
file_dirscan( buf->value, time_enter, bindhash );
|
||||
b->flags |= BIND_SCANNED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan archive if not already done so */
|
||||
/* Scan archive if not already done so */
|
||||
|
||||
if( f1.f_member.len )
|
||||
{
|
||||
BINDING binding, *b = &binding;
|
||||
if( f1.f_member.len )
|
||||
{
|
||||
BINDING binding, *b = &binding;
|
||||
|
||||
f2 = f1;
|
||||
f2.f_grist.len = 0;
|
||||
f2.f_member.len = 0;
|
||||
f2 = f1;
|
||||
f2.f_grist.len = 0;
|
||||
f2.f_member.len = 0;
|
||||
string_truncate( buf, 0 );
|
||||
path_build( &f2, buf, 0 );
|
||||
path_build( &f2, buf, 0 );
|
||||
|
||||
b->name = buf->value;
|
||||
b->time = b->flags = 0;
|
||||
b->progress = BIND_INIT;
|
||||
b->name = buf->value;
|
||||
b->time = b->flags = 0;
|
||||
b->progress = BIND_INIT;
|
||||
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( buf->value ); /* never freed */
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( buf->value ); /* never freed */
|
||||
|
||||
if( !( b->flags & BIND_SCANNED ) )
|
||||
{
|
||||
file_archscan( buf->value, time_enter, bindhash );
|
||||
b->flags |= BIND_SCANNED;
|
||||
}
|
||||
}
|
||||
if( !( b->flags & BIND_SCANNED ) )
|
||||
{
|
||||
file_archscan( buf->value, time_enter, bindhash );
|
||||
b->flags |= BIND_SCANNED;
|
||||
}
|
||||
}
|
||||
|
||||
afterscanning:
|
||||
|
||||
if( b->progress == BIND_SPOTTED )
|
||||
{
|
||||
if( file_time( b->name, &b->time ) < 0 )
|
||||
b->progress = BIND_MISSING;
|
||||
else
|
||||
b->progress = BIND_FOUND;
|
||||
}
|
||||
if( b->progress == BIND_SPOTTED )
|
||||
{
|
||||
if( file_time( b->name, &b->time ) < 0 )
|
||||
b->progress = BIND_MISSING;
|
||||
else
|
||||
b->progress = BIND_FOUND;
|
||||
}
|
||||
|
||||
*time = b->progress == BIND_FOUND ? b->time : 0;
|
||||
*time = b->progress == BIND_FOUND ? b->time : 0;
|
||||
string_free( buf );
|
||||
# ifdef DOWNSHIFT_PATHS
|
||||
string_free( &path );
|
||||
#endif
|
||||
|
||||
|
||||
PROFILE_EXIT(timestamp);
|
||||
}
|
||||
|
||||
static void
|
||||
time_enter(
|
||||
void *closure,
|
||||
char *target,
|
||||
int found,
|
||||
time_t time )
|
||||
time_enter(
|
||||
void *closure,
|
||||
char *target,
|
||||
int found,
|
||||
time_t time )
|
||||
{
|
||||
BINDING binding, *b = &binding;
|
||||
struct hash *bindhash = (struct hash *)closure;
|
||||
BINDING binding, *b = &binding;
|
||||
struct hash *bindhash = (struct hash *)closure;
|
||||
|
||||
# ifdef DOWNSHIFT_PATHS
|
||||
char path[ MAXJPATH ];
|
||||
char *p = path;
|
||||
char path[ MAXJPATH ];
|
||||
char *p = path;
|
||||
|
||||
do *p++ = tolower( *target );
|
||||
while( *target++ );
|
||||
do *p++ = tolower( *target );
|
||||
while( *target++ );
|
||||
|
||||
target = path;
|
||||
target = path;
|
||||
# endif
|
||||
|
||||
b->name = target;
|
||||
b->flags = 0;
|
||||
b->name = target;
|
||||
b->flags = 0;
|
||||
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( target ); /* never freed */
|
||||
if( hashenter( bindhash, (HASHDATA **)&b ) )
|
||||
b->name = newstr( target ); /* never freed */
|
||||
|
||||
b->time = time;
|
||||
b->progress = found ? BIND_FOUND : BIND_SPOTTED;
|
||||
b->time = time;
|
||||
b->progress = found ? BIND_FOUND : BIND_SPOTTED;
|
||||
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "time ( %s ) : %s\n", target, time_progress[b->progress] );
|
||||
if( DEBUG_BINDSCAN )
|
||||
printf( "time ( %s ) : %s\n", target, time_progress[b->progress] );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -228,5 +228,5 @@ time_enter(
|
||||
void
|
||||
donestamps()
|
||||
{
|
||||
hashdone( bindhash );
|
||||
hashdone( bindhash );
|
||||
}
|
||||
|
||||
@@ -30,17 +30,17 @@
|
||||
*
|
||||
* External routines:
|
||||
*
|
||||
* var_defines() - load a bunch of variable=value settings
|
||||
* var_string() - expand a string with variables in it
|
||||
* var_get() - get value of a user defined symbol
|
||||
* var_set() - set a variable in jam's user defined symbol table
|
||||
* var_swap() - swap a variable's value with the given one
|
||||
* var_done() - free variable tables
|
||||
* var_defines() - load a bunch of variable=value settings
|
||||
* var_string() - expand a string with variables in it
|
||||
* var_get() - get value of a user defined symbol
|
||||
* var_set() - set a variable in jam's user defined symbol table
|
||||
* var_swap() - swap a variable's value with the given one
|
||||
* var_done() - free variable tables
|
||||
*
|
||||
* Internal routines:
|
||||
*
|
||||
* var_enter() - make new var symbol table entry, returning var ptr
|
||||
* var_dump() - dump a variable to stdout
|
||||
* var_enter() - make new var symbol table entry, returning var ptr
|
||||
* var_dump() - dump a variable to stdout
|
||||
*
|
||||
* 04/13/94 (seiwald) - added shorthand L0 for null list pointer
|
||||
* 08/23/94 (seiwald) - Support for '+=' (append to variable)
|
||||
@@ -58,8 +58,8 @@ static struct hash *varhash = 0;
|
||||
typedef struct _variable VARIABLE ;
|
||||
|
||||
struct _variable {
|
||||
char *symbol;
|
||||
LIST *value;
|
||||
char *symbol;
|
||||
LIST *value;
|
||||
} ;
|
||||
|
||||
static VARIABLE *var_enter( char *symbol );
|
||||
@@ -99,34 +99,34 @@ var_defines( char *const* e, int preprocess )
|
||||
|
||||
string_new( buf );
|
||||
|
||||
for( ; *e; e++ )
|
||||
{
|
||||
char *val;
|
||||
for( ; *e; e++ )
|
||||
{
|
||||
char *val;
|
||||
|
||||
# ifdef OS_MAC
|
||||
/* On the mac (MPW), the var=val is actually var\0val */
|
||||
/* Think different. */
|
||||
|
||||
if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )
|
||||
/* On the mac (MPW), the var=val is actually var\0val */
|
||||
/* Think different. */
|
||||
|
||||
if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )
|
||||
# else
|
||||
if( val = strchr( *e, '=' ) )
|
||||
if( val = strchr( *e, '=' ) )
|
||||
# endif
|
||||
{
|
||||
LIST *l = L0;
|
||||
char *pp, *p;
|
||||
{
|
||||
LIST *l = L0;
|
||||
char *pp, *p;
|
||||
# ifdef OPT_NO_EXTERNAL_VARIABLE_SPLIT
|
||||
char split = '\0';
|
||||
# else
|
||||
# ifdef OS_MAC
|
||||
char split = ',';
|
||||
char split = ',';
|
||||
# else
|
||||
char split = ' ';
|
||||
char split = ' ';
|
||||
# endif
|
||||
# endif
|
||||
size_t len = strlen(val + 1);
|
||||
|
||||
int quoted = val[1] == '"' && val[len] == '"' && len > 1;
|
||||
|
||||
|
||||
if ( quoted && preprocess )
|
||||
{
|
||||
string_append_range( buf, val + 2, val + len );
|
||||
@@ -142,7 +142,7 @@ var_defines( char *const* e, int preprocess )
|
||||
if( !strncmp( val - 4, "PATH", 4 ) ||
|
||||
!strncmp( val - 4, "Path", 4 ) ||
|
||||
!strncmp( val - 4, "path", 4 ) )
|
||||
split = SPLITPATH;
|
||||
split = SPLITPATH;
|
||||
}
|
||||
|
||||
/* Do the split */
|
||||
@@ -160,12 +160,12 @@ var_defines( char *const* e, int preprocess )
|
||||
l = list_new( l, newstr( pp ) );
|
||||
}
|
||||
|
||||
/* Get name */
|
||||
/* Get name */
|
||||
string_append_range( buf, *e, val );
|
||||
var_set( buf->value, l, VAR_SET );
|
||||
var_set( buf->value, l, VAR_SET );
|
||||
string_truncate( buf, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
string_free( buf );
|
||||
}
|
||||
|
||||
@@ -187,8 +187,8 @@ var_string(
|
||||
|
||||
while( *in )
|
||||
{
|
||||
char *lastword;
|
||||
int dollar = 0;
|
||||
char *lastword;
|
||||
int dollar = 0;
|
||||
|
||||
/* Copy white space */
|
||||
|
||||
@@ -220,9 +220,9 @@ var_string(
|
||||
int depth = 1;
|
||||
char *ine = in + 2;
|
||||
char *split = 0;
|
||||
|
||||
|
||||
/* Scan the content of the response file @() section. */
|
||||
|
||||
|
||||
while( *ine && depth > 0 )
|
||||
{
|
||||
switch( *ine )
|
||||
@@ -242,7 +242,7 @@ var_string(
|
||||
}
|
||||
++ine;
|
||||
}
|
||||
|
||||
|
||||
if (!split)
|
||||
{
|
||||
/* the @() reference doesn't match the @(foo:E=bar) format.
|
||||
@@ -257,13 +257,13 @@ var_string(
|
||||
if ( out+1 >= oute ) return -1;
|
||||
*(out++) = ')';
|
||||
}
|
||||
|
||||
|
||||
else if ( depth == 0 )
|
||||
{
|
||||
string file_name_v;
|
||||
int file_name_l = 0;
|
||||
const char * file_name_s = 0;
|
||||
|
||||
|
||||
/* expand the temporary file name var inline */
|
||||
#if 0
|
||||
string_copy(&file_name_v,"$(");
|
||||
@@ -277,7 +277,7 @@ var_string(
|
||||
string_free(&file_name_v);
|
||||
if ( file_name_l < 0 ) return -1;
|
||||
file_name_s = out;
|
||||
|
||||
|
||||
/* for stdout/stderr we will create a temp file and generate
|
||||
a command that outputs the content as needed. */
|
||||
if ( strcmp( "STDOUT", out ) == 0 || strcmp( "STDERR", out ) == 0 )
|
||||
@@ -301,14 +301,14 @@ var_string(
|
||||
get nuked eventually. */
|
||||
file_remove_atexit( file_name_s );
|
||||
}
|
||||
|
||||
|
||||
/* expand the file value into the file reference */
|
||||
var_string_to_file( split+3, ine-split-4, file_name_s, lol );
|
||||
|
||||
|
||||
/* continue on with the expansion */
|
||||
out += strlen(out);
|
||||
}
|
||||
|
||||
|
||||
/* and continue with the parsing just past the @() reference */
|
||||
in = ine;
|
||||
}
|
||||
@@ -324,7 +324,7 @@ var_string(
|
||||
return -1;
|
||||
/* Don't increment, intentionally. */
|
||||
*out= '\0';
|
||||
|
||||
|
||||
/* If a variable encountered, expand it and and embed the */
|
||||
/* space-separated members of the list in the output. */
|
||||
|
||||
@@ -460,7 +460,7 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
|
||||
if ( out_file ) fwrite(output_0,output_1-output_0,1,out_file);
|
||||
if ( out_debug ) fwrite(output_0,output_1-output_0,1,stdout);
|
||||
}
|
||||
|
||||
|
||||
in = output_1;
|
||||
}
|
||||
|
||||
@@ -509,9 +509,9 @@ var_get( char *symbol )
|
||||
#endif
|
||||
{
|
||||
VARIABLE var, *v = &var;
|
||||
|
||||
|
||||
v->symbol = symbol;
|
||||
|
||||
|
||||
if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
|
||||
{
|
||||
if( DEBUG_VARGET )
|
||||
@@ -535,36 +535,36 @@ var_get( char *symbol )
|
||||
|
||||
void
|
||||
var_set(
|
||||
char *symbol,
|
||||
LIST *value,
|
||||
int flag )
|
||||
char *symbol,
|
||||
LIST *value,
|
||||
int flag )
|
||||
{
|
||||
VARIABLE *v = var_enter( symbol );
|
||||
VARIABLE *v = var_enter( symbol );
|
||||
|
||||
if( DEBUG_VARSET )
|
||||
var_dump( symbol, value, "set" );
|
||||
|
||||
switch( flag )
|
||||
{
|
||||
case VAR_SET:
|
||||
/* Replace value */
|
||||
list_free( v->value );
|
||||
v->value = value;
|
||||
break;
|
||||
if( DEBUG_VARSET )
|
||||
var_dump( symbol, value, "set" );
|
||||
|
||||
case VAR_APPEND:
|
||||
/* Append value */
|
||||
v->value = list_append( v->value, value );
|
||||
break;
|
||||
switch( flag )
|
||||
{
|
||||
case VAR_SET:
|
||||
/* Replace value */
|
||||
list_free( v->value );
|
||||
v->value = value;
|
||||
break;
|
||||
|
||||
case VAR_DEFAULT:
|
||||
/* Set only if unset */
|
||||
if( !v->value )
|
||||
v->value = value;
|
||||
else
|
||||
list_free( value );
|
||||
break;
|
||||
}
|
||||
case VAR_APPEND:
|
||||
/* Append value */
|
||||
v->value = list_append( v->value, value );
|
||||
break;
|
||||
|
||||
case VAR_DEFAULT:
|
||||
/* Set only if unset */
|
||||
if( !v->value )
|
||||
v->value = value;
|
||||
else
|
||||
list_free( value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -573,18 +573,18 @@ var_set(
|
||||
|
||||
LIST *
|
||||
var_swap(
|
||||
char *symbol,
|
||||
LIST *value )
|
||||
char *symbol,
|
||||
LIST *value )
|
||||
{
|
||||
VARIABLE *v = var_enter( symbol );
|
||||
LIST *oldvalue = v->value;
|
||||
VARIABLE *v = var_enter( symbol );
|
||||
LIST *oldvalue = v->value;
|
||||
|
||||
if( DEBUG_VARSET )
|
||||
var_dump( symbol, value, "set" );
|
||||
if( DEBUG_VARSET )
|
||||
var_dump( symbol, value, "set" );
|
||||
|
||||
v->value = value;
|
||||
v->value = value;
|
||||
|
||||
return oldvalue;
|
||||
return oldvalue;
|
||||
}
|
||||
|
||||
|
||||
@@ -594,20 +594,20 @@ var_swap(
|
||||
*/
|
||||
|
||||
static VARIABLE *
|
||||
var_enter( char *symbol )
|
||||
var_enter( char *symbol )
|
||||
{
|
||||
VARIABLE var, *v = &var;
|
||||
VARIABLE var, *v = &var;
|
||||
|
||||
if( !varhash )
|
||||
varhash = hashinit( sizeof( VARIABLE ), "variables" );
|
||||
if( !varhash )
|
||||
varhash = hashinit( sizeof( VARIABLE ), "variables" );
|
||||
|
||||
v->symbol = symbol;
|
||||
v->value = 0;
|
||||
v->symbol = symbol;
|
||||
v->value = 0;
|
||||
|
||||
if( hashenter( varhash, (HASHDATA **)&v ) )
|
||||
v->symbol = newstr( symbol ); /* never freed */
|
||||
if( hashenter( varhash, (HASHDATA **)&v ) )
|
||||
v->symbol = newstr( symbol ); /* never freed */
|
||||
|
||||
return v;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -616,13 +616,13 @@ var_enter( char *symbol )
|
||||
|
||||
static void
|
||||
var_dump(
|
||||
char *symbol,
|
||||
LIST *value,
|
||||
char *what )
|
||||
char *symbol,
|
||||
LIST *value,
|
||||
char *what )
|
||||
{
|
||||
printf( "%s %s = ", what, symbol );
|
||||
list_print( value );
|
||||
printf( "\n" );
|
||||
printf( "%s %s = ", what, symbol );
|
||||
list_print( value );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -639,5 +639,5 @@ void
|
||||
var_done()
|
||||
{
|
||||
hashenumerate( varhash, delete_var_, (void*)0 );
|
||||
hashdone( varhash );
|
||||
hashdone( varhash );
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
|
||||
struct hash;
|
||||
|
||||
void var_defines( char* const *e, int preprocess );
|
||||
int var_string( char *in, char *out, int outsize, LOL *lol );
|
||||
LIST * var_get( char *symbol );
|
||||
void var_set( char *symbol, LIST *value, int flag );
|
||||
LIST * var_swap( char *symbol, LIST *value );
|
||||
void var_done();
|
||||
void var_defines( char* const *e, int preprocess );
|
||||
int var_string( char *in, char *out, int outsize, LOL *lol );
|
||||
LIST * var_get( char *symbol );
|
||||
void var_set( char *symbol, LIST *value, int flag );
|
||||
LIST * var_swap( char *symbol, LIST *value );
|
||||
void var_done();
|
||||
void var_hash_swap( struct hash** );
|
||||
|
||||
/** Expands the "in" expression directly into the "out" file.
|
||||
@@ -29,7 +29,7 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
|
||||
* Defines for var_set().
|
||||
*/
|
||||
|
||||
# define VAR_SET 0 /* override previous value */
|
||||
# define VAR_APPEND 1 /* append to previous value */
|
||||
# define VAR_DEFAULT 2 /* set only if no previous value */
|
||||
# define VAR_SET 0 /* override previous value */
|
||||
# define VAR_APPEND 1 /* append to previous value */
|
||||
# define VAR_DEFAULT 2 /* set only if no previous value */
|
||||
|
||||
|
||||
@@ -65,23 +65,23 @@ builtin_system_registry(
|
||||
char const* path = lol_get(frame->args, 0)->string;
|
||||
LIST* result = L0;
|
||||
HKEY key = get_key(&path);
|
||||
|
||||
|
||||
if (
|
||||
key != 0
|
||||
&& ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key)
|
||||
&& ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key)
|
||||
)
|
||||
{
|
||||
DWORD type;
|
||||
BYTE data[MAX_REGISTRY_DATA_LENGTH];
|
||||
DWORD len = sizeof(data);
|
||||
LIST const* const field = lol_get(frame->args, 1);
|
||||
|
||||
|
||||
if ( ERROR_SUCCESS ==
|
||||
RegQueryValueEx(key, field ? field->string : 0, 0, &type, data, &len) )
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
||||
|
||||
case REG_EXPAND_SZ:
|
||||
{
|
||||
long len;
|
||||
@@ -101,7 +101,7 @@ builtin_system_registry(
|
||||
string_free( expanded );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case REG_MULTI_SZ:
|
||||
{
|
||||
char* s;
|
||||
@@ -111,7 +111,7 @@ builtin_system_registry(
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case REG_DWORD:
|
||||
{
|
||||
char buf[100];
|
||||
@@ -133,9 +133,9 @@ builtin_system_registry(
|
||||
static LIST* get_subkey_names(HKEY key, char const* path)
|
||||
{
|
||||
LIST* result = 0;
|
||||
|
||||
if ( ERROR_SUCCESS ==
|
||||
RegOpenKeyEx(key, path, 0, KEY_ENUMERATE_SUB_KEYS, &key)
|
||||
|
||||
if ( ERROR_SUCCESS ==
|
||||
RegOpenKeyEx(key, path, 0, KEY_ENUMERATE_SUB_KEYS, &key)
|
||||
)
|
||||
{
|
||||
char name[MAX_REGISTRY_KEYNAME_LENGTH];
|
||||
@@ -143,47 +143,47 @@ static LIST* get_subkey_names(HKEY key, char const* path)
|
||||
DWORD index;
|
||||
FILETIME last_write_time;
|
||||
|
||||
for ( index = 0;
|
||||
for ( index = 0;
|
||||
ERROR_SUCCESS == RegEnumKeyEx(
|
||||
key, index, name, &name_size, 0, 0, 0, &last_write_time);
|
||||
++index,
|
||||
++index,
|
||||
name_size = sizeof(name)
|
||||
)
|
||||
{
|
||||
name[name_size] = 0;
|
||||
result = list_append(result, list_new(0, newstr(name)));
|
||||
}
|
||||
|
||||
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static LIST* get_value_names(HKEY key, char const* path)
|
||||
{
|
||||
LIST* result = 0;
|
||||
|
||||
|
||||
if ( ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key) )
|
||||
{
|
||||
char name[MAX_REGISTRY_VALUENAME_LENGTH];
|
||||
DWORD name_size = sizeof(name);
|
||||
DWORD index;
|
||||
|
||||
for ( index = 0;
|
||||
for ( index = 0;
|
||||
ERROR_SUCCESS == RegEnumValue(
|
||||
key, index, name, &name_size, 0, 0, 0, 0);
|
||||
++index,
|
||||
++index,
|
||||
name_size = sizeof(name)
|
||||
)
|
||||
{
|
||||
name[name_size] = 0;
|
||||
result = list_append(result, list_new(0, newstr(name)));
|
||||
}
|
||||
|
||||
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ builtin_system_registry_names(
|
||||
{
|
||||
char const* path = lol_get(frame->args, 0)->string;
|
||||
char const* result_type = lol_get(frame->args, 1)->string;
|
||||
|
||||
|
||||
HKEY key = get_key(&path);
|
||||
|
||||
if ( !strcmp(result_type, "subkeys") )
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
/*
|
||||
# yyacc - yacc wrapper
|
||||
#
|
||||
# Allows tokens to be written as `literal` and then automatically
|
||||
# Allows tokens to be written as `literal` and then automatically
|
||||
# substituted with #defined tokens.
|
||||
#
|
||||
# Usage:
|
||||
# yyacc file.y filetab.h file.yy
|
||||
# yyacc file.y filetab.h file.yy
|
||||
#
|
||||
# inputs:
|
||||
# file.yy yacc grammar with ` literals
|
||||
@@ -59,7 +59,7 @@ int main(int argc, char ** argv)
|
||||
FILE * token_output_f = 0;
|
||||
FILE * grammar_output_f = 0;
|
||||
FILE * grammar_source_f = 0;
|
||||
|
||||
|
||||
grammar_source_f = fopen(argv[3],"r");
|
||||
if (grammar_source_f == 0) { result = 1; }
|
||||
if (result == 0)
|
||||
@@ -223,7 +223,7 @@ char * tokenize_string(char * s)
|
||||
char * literal = s;
|
||||
int l;
|
||||
int c;
|
||||
|
||||
|
||||
if (strcmp(s,":") == 0) literal = "_colon";
|
||||
else if (strcmp(s,"!") == 0) literal = "_bang";
|
||||
else if (strcmp(s,"!=") == 0) literal = "_bang_equals";
|
||||
|
||||
Reference in New Issue
Block a user