2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-02 20:52:13 +00:00

Variety of performance improvements.

* bjam; bump to version 3.1.12
* bjam; make it possible to build in MinGW/MSYS shell
* bjam; move profile code to debug.h/c to make it available for use everywhere
* bjam; cache all filesystem query operations, Unix and Windows only, include PWD and scanning
* bjam; add memory profile info, and sprinkle throught code
* bbv2; rewrite some while() loops into for() loops to reduce time and memory
* bbv2; keep a single instance counter instead of one per type to reduce memory use
* bjam+bbv2; change NORMALIZE_PATH builtin to join path parts to reduce memory use


[SVN r31177]
This commit is contained in:
Rene Rivera
2005-10-03 00:47:36 +00:00
parent 1fa3a7afab
commit eed0cf6cc3
40 changed files with 738 additions and 304 deletions

View File

@@ -541,28 +541,20 @@ class generator
{
# We process each source one-by-one, trying to convert it to
# a usable type.
local failed ;
while $(sources) && ! $(failed)
for local source in $(sources)
{
local _c ;
local _b ;
# TODO: need to check for failure on each source.
convert-to-consumable-types $(project) : $(property-set)
: $(sources[1]) : true : _c _b ;
: $(source) : true : _c _b ;
if ! $(_c)
{
generators.dout [ indent ] " failed to convert " $(sources[1]) ;
# failed = true ;
generators.dout [ indent ] " failed to convert " $(source) ;
}
$(consumed-var) += $(_c) ;
$(bypassed-var) += $(_b) ;
sources = $(sources[2-]) ;
}
if $(failed)
{
$(consumed-var) = ;
$(bypassed-var) = ;
}
}
rule consume-directly ( source : consumed-var : missing-types-var )

View File

@@ -293,17 +293,22 @@ rule set-target-variables ( rule-or-module targets + : property-set )
}
.stv.$(key) = $(settings) ;
}
if $(settings) != none
{
while $(settings)
local var-name = ;
for local name-or-value in $(settings)
{
# Here, $(settings[1]) is the name of variable to assign
# and $(settings[2]) is the value.
$(settings[1]) on $(targets) += $(settings[2]) ;
settings = $(settings[3-]) ;
}
if $(var-name)
{
$(var-name) on $(targets) += $(name-or-value) ;
var-name = ;
}
else
{
var-name = $(name-or-value) ;
}
}
}
}

View File

@@ -1,5 +1,5 @@
Name: boost-jam
Version: 3.1.11
Version: 3.1.12
Summary: Build tool
Release: 1
Source: %{name}-%{version}.tgz
@@ -33,6 +33,7 @@ Copyright:
Also:
Copyright 2001-2004 David Abrahams.
Copyright 2002-2005 Rene Rivera.
Copyright 2003-2005 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)

View File

@@ -312,7 +312,7 @@ echo ###
set YYACC_SOURCES=yyacc.c
set MKJAMBASE_SOURCES=mkjambase.c
set BJAM_SOURCES=
set BJAM_SOURCES=%BJAM_SOURCES% command.c compile.c execnt.c expand.c filent.c glob.c hash.c
set BJAM_SOURCES=%BJAM_SOURCES% command.c compile.c debug.c execnt.c expand.c filent.c glob.c hash.c
set BJAM_SOURCES=%BJAM_SOURCES% hdrmacro.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c
set BJAM_SOURCES=%BJAM_SOURCES% newstr.c option.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

View File

@@ -13,7 +13,7 @@ else { . = "." ; }
# Info about what we are building.
NAME = boost-jam ;
VERSION = 3$(.)1$(.)11 ;
VERSION = 3$(.)1$(.)12 ;
RELEASE = 1 ;
LICENSE = 1_0 ;
@@ -98,10 +98,10 @@ toolset darwin cc : "-o " : -D
:
[ opt --release : -Wl,-x -O3 -finline-functions ]
[ opt --debug : -g -O0 -fno-inline -pg ] ;
## GCC 2.x, 3.x
## GCC 2.x, 3.x, 4.x
toolset gcc gcc : "-o " : -D
: -pedantic
[ opt --release : [ opt --symbols : -g : -s ] -O3 -finline-functions ]
[ opt --release : [ opt --symbols : -g : -s ] -O3 ]
[ opt --debug : -g -O0 -fno-inline ] ;
## GCC 2.x, 3.x on CYGWIN but without cygwin1.dll
toolset gcc-nocygwin gcc : "-o " : -D
@@ -277,7 +277,7 @@ else
# We have some different files for UNIX, VMS, and NT.
jam.source =
command.c compile.c expand.c glob.c
command.c compile.c debug.c expand.c glob.c
hash.c hcache.c headers.c hdrmacro.c
jam.c jambase.c jamgram.c
lists.c make.c make1.c newstr.c

View File

@@ -30,7 +30,7 @@ error_exit ()
echo "###"
echo "### Toolsets supported by this script are:"
echo "### acc, como, darwin, gcc, intel-linux, kcc, kylix, mipspro,"
echo "### sunpro, tru64cxx, vacpp"
echo "### sunpro, tru64cxx, vacpp, mingw(msys)"
echo "###"
echo "### A special toolset; cc, is available which is used as a fallback"
echo "### when a more specific toolset is not found and the cc command is"
@@ -61,7 +61,10 @@ test_uname ()
# Try and guess the toolset to bootstrap the build with...
Guess_Toolset ()
{
if test_uname Darwin ; then BOOST_JAM_TOOLSET=darwin
if test -r /mingw/bin/gcc ; then
BOOST_JAM_TOOLSET=mingw
BOOST_JAM_TOOLSET_ROOT=/mingw/
elif test_uname Darwin ; then BOOST_JAM_TOOLSET=darwin
elif test_uname IRIX ; then BOOST_JAM_TOOLSET=mipspro
elif test_uname IRIX64 ; then BOOST_JAM_TOOLSET=mipspro
elif test_uname OSF1 ; then BOOST_JAM_TOOLSET=tru64cxx
@@ -108,6 +111,13 @@ BOOST_JAM_OPT_JAM="-o bootstrap/jam0"
BOOST_JAM_OPT_MKJAMBASE="-o bootstrap/mkjambase0"
BOOST_JAM_OPT_YYACC="-o bootstrap/yyacc0"
case $BOOST_JAM_TOOLSET in
mingw)
if test -r ${BOOST_JAM_TOOLSET_ROOT}bin/gcc -r ; then
export PATH=${BOOST_JAM_TOOLSET_ROOT}bin:$PATH
fi
BOOST_JAM_CC="gcc -DNT"
;;
gcc)
BOOST_JAM_CC=gcc
;;
@@ -188,13 +198,14 @@ echo "###"
YYACC_SOURCES="yyacc.c"
MKJAMBASE_SOURCES="mkjambase.c"
BJAM_SOURCES="\
command.c compile.c execunix.c expand.c fileunix.c glob.c hash.c\
command.c compile.c debug.c execunix.c expand.c fileunix.c glob.c hash.c\
hdrmacro.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c\
newstr.c option.c parse.c pathunix.c pathvms.c regexp.c\
rules.c scan.c search.c subst.c timestamp.c variable.c modules.c\
strings.c filesys.c builtins.c pwd.c class.c native.c w32_getreg.c\
modules/set.c modules/path.c modules/regex.c modules/property-set.c\
modules/sequence.c modules/order.c"
modules/sequence.c modules/order.c\
execnt.c filent.c"
BJAM_UPDATE=
if test "$1" = "--update" -o "$2" = "--update" -o "$3" = "--update" -o "$4" = "--update" ; then

View File

@@ -5,6 +5,7 @@
*/
# include "jam.h"
# include "debug.h"
# include "lists.h"
# include "parse.h"
@@ -266,7 +267,7 @@ load_builtins()
}
{
char * args[] = { "path", 0 };
char * args[] = { "path_parts", "*", 0 };
bind_builtin( "NORMALIZE_PATH",
builtin_normalize_path, 0, args );
}
@@ -547,11 +548,13 @@ builtin_glob_back(
int status,
time_t time )
{
PROFILE_ENTER(BUILTIN_GLOB_BACK);
struct globbing *globbing = (struct globbing *)closure;
LIST *l;
PATHNAME f;
string buf[1];
/* Null out directory for matching. */
/* We wish we had file_dirscan() pass up a PATHNAME. */
@@ -565,7 +568,10 @@ builtin_glob_back(
"." and ".." won't work anywhere.
*/
if (strcmp(f.f_base.ptr, ".") == 0 || strcmp(f.f_base.ptr, "..") == 0)
{
PROFILE_EXIT(BUILTIN_GLOB_BACK);
return;
}
string_new( buf );
path_build( &f, buf, 0 );
@@ -584,6 +590,8 @@ builtin_glob_back(
}
string_free( buf );
PROFILE_EXIT(BUILTIN_GLOB_BACK);
}
static LIST* downcase_list( LIST *in )
@@ -1263,7 +1271,7 @@ builtin_sort( PARSE *parse, FRAME *frame )
LIST *builtin_normalize_path( PARSE *parse, FRAME *frame )
{
LIST* arg1 = lol_get( frame->args, 0 );
LIST* arg = lol_get( frame->args, 0 );
/* First, we iterate over all '/'-separated elements, starting from
the end of string. If we see '..', we remove previous path elements.
@@ -1276,14 +1284,20 @@ LIST *builtin_normalize_path( PARSE *parse, FRAME *frame )
char* end; /* Last character of the part of string still to be processed. */
char* current; /* Working pointer. */
int dotdots = 0; /* Number of '..' elements seen and not processed yet. */
int rooted = arg1->string[0] == '/';
int rooted = arg->string[0] == '/';
char* result;
/* Make a copy of input: we should not change it. */
string_new(in);
if (!rooted)
string_push_back(in, '/');
string_append(in, arg1->string);
while (arg)
{
string_append(in, arg->string);
arg = list_next(arg);
if (arg)
string_append(in, "/");
}
end = in->value + in->size - 1;

View File

@@ -20,6 +20,7 @@
# include "parse.h"
# include "variable.h"
# include "rules.h"
# include "debug.h"
# include "command.h"
# include <limits.h>
@@ -42,6 +43,9 @@ cmd_new(
int max_line = MAXLINE;
int allocated = -1;
if ( DEBUG_PROFILE )
profile_memory( sizeof( CMD ) );
cmd->rule = rule;
cmd->shell = shell;
cmd->next = 0;
@@ -56,6 +60,9 @@ cmd_new(
free(cmd->buf); /* free any buffer from previous iteration */
cmd->buf = (char*)malloc(max_line + 1);
if ( DEBUG_PROFILE )
profile_memory( max_line + 1 );
if (cmd->buf == 0)
break;

View File

@@ -11,6 +11,7 @@
*/
# include "jam.h"
# include "debug.h"
# include "lists.h"
# include "parse.h"
@@ -28,7 +29,6 @@
# include "builtins.h"
# include "class.h"
# include <time.h>
# include <assert.h>
# include <string.h>
# include <stdarg.h>
@@ -799,96 +799,6 @@ collect_arguments( RULE* rule, FRAME* frame )
return locals;
}
struct profile_info
{
char* name; /* name of rule being called */
clock_t cumulative; /* cumulative time spent in rule */
clock_t net; /* time spent in rule proper */
unsigned long num_entries; /* number of time rule was entered */
unsigned long stack_count; /* number of the times this function is present in stack */
};
typedef struct profile_info profile_info;
struct profile_frame
{
profile_info* info; /* permanent storage where data accumulates */
clock_t overhead; /* overhead for profiling in this call */
clock_t entry_time; /* time of last entry to rule */
struct profile_frame* caller; /* stack frame of caller */
clock_t subrules; /* time spent in subrules */
};
typedef struct profile_frame profile_frame;
static profile_frame* profile_stack = 0;
static struct hash* profile_hash = 0;
static void profile_enter( char* rulename, profile_frame* frame )
{
clock_t start = clock();
profile_info info, *p = &info;
if ( !profile_hash )
profile_hash = hashinit(sizeof(profile_info), "profile");
info.name = rulename;
if ( hashenter( profile_hash, (HASHDATA **)&p ) )
p->cumulative = p->net = p->num_entries = p->stack_count = 0;
++(p->num_entries);
++(p->stack_count);
frame->info = p;
frame->caller = profile_stack;
profile_stack = frame;
frame->entry_time = clock();
frame->overhead = 0;
frame->subrules = 0;
/* caller pays for the time it takes to play with the hash table */
if ( frame->caller )
frame->caller->overhead += frame->entry_time - start;
}
static void profile_exit(profile_frame* frame)
{
/* cumulative time for this call */
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)
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)
{
/* caller's cumulative time must account for this overhead */
frame->caller->overhead += frame->overhead;
frame->caller->subrules += t;
}
/* pop this stack frame */
--frame->info->stack_count;
profile_stack = frame->caller;
}
static void dump_profile_entry(void* p_, void* ignored)
{
profile_info* p = (profile_info*)p_;
printf("%10d %10d %10d %s\n", p->cumulative, p->net, p->num_entries, p->name);
}
void profile_dump()
{
if ( profile_hash )
{
printf("%10s %10s %10s %s\n", "gross", "net", "# entries", "name");
hashenumerate( profile_hash, dump_profile_entry, 0 );
}
}
static int python_instance_number = 0;
RULE *
@@ -1100,6 +1010,9 @@ evaluate_rule(
action = (ACTION *)malloc( sizeof( ACTION ) );
memset( (char *)action, '\0', sizeof( *action ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( ACTION ) );
action->rule = rule;
action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) );
action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) );

View File

@@ -48,8 +48,6 @@ LIST *call_rule( char *rulename, FRAME* caller_frame, ...);
regexp* regex_compile( const char* pattern );
void profile_dump();
/* Flags for compile_set(), etc */
# define ASSIGN_SET 0x00 /* = assign variable */

View File

@@ -1,3 +1,9 @@
bjam (3.1.12-1) unstable; urgency=low
* New upstream release.
-- Rene Rivera <grafik@redshift-software.com> Sat, 01 Oct 2005 00:00:00 +0000
bjam (3.1.11-1) unstable; urgency=low
* New upstream release.

View File

@@ -19,6 +19,7 @@ Some portions are also:
Copyright 2001-2004 David Abrahams.
Copyright 2002-2005 Rene Rivera.
Copyright 2003-2005 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)

127
src/engine/debug.c Normal file
View File

@@ -0,0 +1,127 @@
/*
Copyright Rene Rivera 2005.
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)
*/
# include "jam.h"
# include "debug.h"
# include "hash.h"
# include <time.h>
# include <assert.h>
static profile_frame* profile_stack = 0;
static struct hash* profile_hash = 0;
static profile_info profile_other = { "[OTHER]", 0, 0, 0, 0, 0 };
static profile_info profile_total = { "[TOTAL]", 0, 0, 0, 0, 0 };
profile_frame* profile_init( char* rulename, profile_frame* frame )
{
if ( DEBUG_PROFILE ) profile_enter(rulename,frame);
return frame;
}
void profile_enter( char* rulename, profile_frame* frame )
{
if ( DEBUG_PROFILE )
{
clock_t start = clock();
profile_info info, *p = &info;
if ( !rulename ) p = &profile_other;
if ( !profile_hash )
{
if ( rulename ) profile_hash = hashinit(sizeof(profile_info), "profile");
}
info.name = rulename;
if ( rulename && hashenter( profile_hash, (HASHDATA **)&p ) )
p->cumulative = p->net = p->num_entries = p->stack_count = p->memory = 0;
++(p->num_entries);
++(p->stack_count);
frame->info = p;
frame->caller = profile_stack;
profile_stack = frame;
frame->entry_time = clock();
frame->overhead = 0;
frame->subrules = 0;
/* caller pays for the time it takes to play with the hash table */
if ( frame->caller )
frame->caller->overhead += frame->entry_time - start;
}
}
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)
{
if ( DEBUG_PROFILE )
{
/* cumulative time for this call */
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)
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)
{
/* caller's cumulative time must account for this overhead */
frame->caller->overhead += frame->overhead;
frame->caller->subrules += t;
}
/* pop this stack frame */
--frame->info->stack_count;
profile_stack = frame->caller;
}
}
static void dump_profile_entry(void* p_, void* ignored)
{
profile_info* p = (profile_info*)p_;
unsigned long mem_each = (p->memory/(p->num_entries ? p->num_entries : 1));
double q = p->net; q /= (p->num_entries ? p->num_entries : 1);
if (!ignored)
{
profile_total.cumulative += p->net;
profile_total.memory += p->memory;
}
printf("%10d %10d %10d %12.6f %10d %10d %s\n",
p->num_entries, p->cumulative, p->net, q,
p->memory, mem_each,
p->name);
}
void profile_dump()
{
if ( profile_hash )
{
printf("%10s %10s %10s %12s %10s %10s %s\n",
"--count--", "--gross--", "--net--", "--each--",
"--mem--", "--each--",
"--name--");
hashenumerate( profile_hash, dump_profile_entry, 0 );
dump_profile_entry(&profile_other,0);
dump_profile_entry(&profile_total,(void*)1);
}
}

53
src/engine/debug.h Normal file
View File

@@ -0,0 +1,53 @@
/*
Copyright Rene Rivera 2005.
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)
*/
#ifndef BJAM_DEBUG_H
#define BJAM_DEBUG_H
# include "jam.h"
# include <time.h>
struct profile_info
{
/* name of rule being called */
char* name;
/* cumulative time spent in rule */
clock_t cumulative;
/* time spent in rule proper */
clock_t net;
/* number of time rule was entered */
unsigned long num_entries;
/* number of the times this function is present in stack */
unsigned long stack_count;
/* bytes of memory allocated by the call */
unsigned long memory;
};
typedef struct profile_info profile_info;
struct profile_frame
{
/* permanent storage where data accumulates */
profile_info* info;
/* overhead for profiling in this call */
clock_t overhead;
/* time of last entry to rule */
clock_t entry_time;
/* stack frame of caller */
struct profile_frame* caller;
/* time spent in subrules */
clock_t subrules;
};
typedef struct profile_frame profile_frame;
profile_frame * profile_init( char* rulename, profile_frame* frame );
void profile_enter( char* rulename, profile_frame* frame );
void profile_memory( long mem );
void profile_exit(profile_frame* frame);
void profile_dump();
#define PROFILE_ENTER(scope) profile_frame PROF_ ## scope, *PROF_ ## scope ## _p = profile_init(#scope,&PROF_ ## scope)
#define PROFILE_EXIT(scope) profile_exit(PROF_ ## scope ## _p)
#endif

View File

@@ -13,6 +13,7 @@
# include "jam.h"
# include "lists.h"
# include "execcmd.h"
# include "debug.h"
# include <errno.h>
# include <assert.h>
# include <ctype.h>
@@ -149,6 +150,9 @@ string_to_args( const char* string )
if (!line)
return 0;
if ( DEBUG_PROFILE )
profile_memory( src_len+1 );
/* allocate the argv array.
* element 0: stores the path to the executable
* element 1: stores the command-line arguments to the executable
@@ -160,6 +164,9 @@ string_to_args( const char* string )
free( line );
return 0;
}
if ( DEBUG_PROFILE )
profile_memory( 3 * sizeof(char*) );
/* Strip quotes from the first command-line argument and find
* where it ends. Quotes are illegal in Win32 pathnames, so we
@@ -279,6 +286,8 @@ process_del( char* command )
line = (char*)malloc( len+4+1 );
if (!line)
return 1;
if ( DEBUG_PROFILE )
profile_memory( len+4+1 );
strncpy( line, "del ", 4 );
strncpy( line+4, q, len );
@@ -572,6 +581,8 @@ execcmd(
/* SVA - allocate 64 other just to be safe */
cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 64 );
if ( DEBUG_PROFILE )
profile_memory( strlen( tempdir ) + 64 );
procID = GetCurrentProcessId();

View File

@@ -255,7 +255,11 @@ my_wait( int *status )
static HANDLE *active_handles = 0;
if (!active_handles)
{
active_handles = (HANDLE *)malloc(globs.jobs * sizeof(HANDLE) );
if ( DEBUG_PROFILE )
profile_memory( globs.jobs * sizeof(HANDLE) );
}
/* first see if any non-waited-for processes are dead,
* and return if so.

View File

@@ -6,14 +6,18 @@
/* This file is ALSO:
* Copyright 2001-2004 David Abrahams.
* Copyright 2005 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)
*/
# include "jam.h"
# include "debug.h"
# include "filesys.h"
# include "pathsys.h"
# include "strings.h"
# include "newstr.h"
# ifdef OS_NT
@@ -59,89 +63,152 @@ file_dirscan(
scanback func,
void *closure )
{
PATHNAME f;
string filespec[1];
string filename[1];
long handle;
int ret;
struct _finddata_t finfo[1];
PROFILE_ENTER(FILE_DIRSCAN);
file_info_t * d = 0;
dir = short_path_to_long_path( dir );
/* First enter directory itself */
memset( (char *)&f, '\0', sizeof( f ) );
d = file_query( dir );
if ( ! d || ! d->is_dir )
{
PROFILE_EXIT(FILE_DIRSCAN);
return;
}
f.f_dir.ptr = dir;
f.f_dir.len = strlen(dir);
if ( ! d->files )
{
PATHNAME f;
string filespec[1];
string filename[1];
long handle;
int ret;
struct _finddata_t finfo[1];
LIST* files = L0;
dir = *dir ? dir : ".";
memset( (char *)&f, '\0', sizeof( f ) );
f.f_dir.ptr = d->name;
f.f_dir.len = strlen(d->name);
/* Now enter contents of directory */
string_copy( filespec, *d->name ? d->name : "." );
string_append( filespec, "/*" );
if( DEBUG_BINDSCAN )
printf( "scan directory %s\n", dir );
# if defined(__BORLANDC__) && __BORLANDC__ < 0x550
if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) )
{
string_free( filespec );
PROFILE_EXIT(FILE_DIRSCAN);
return;
}
string_new( filename );
while( !ret )
{
file_info_t * ff = 0;
f.f_base.ptr = finfo->ff_name;
f.f_base.len = strlen( finfo->ff_name );
string_truncate( filename, 0 );
path_build( &f, filename );
files = list_new( files, newstr(filename->value) );
ff = file_info( filename->value );
ff->is_file = finfo->ff_attrib & FA_DIREC ? 0 : 1;
ff->is_dir = finfo->ff_attrib & FA_DIREC ? 1 : 0;
ff->size = finfo->ff_fsize;
ff->time = (finfo->ff_ftime << 16) | finfo->ff_ftime;
ret = findnext( finfo );
}
# else
handle = _findfirst( filespec->value, finfo );
if( ret = ( handle < 0L ) )
{
string_free( filespec );
PROFILE_EXIT(FILE_DIRSCAN);
return;
}
string_new( filename );
while( !ret )
{
file_info_t * ff = 0;
f.f_base.ptr = finfo->name;
f.f_base.len = strlen( finfo->name );
string_truncate( filename, 0 );
path_build( &f, filename, 0 );
files = list_new( files, newstr(filename->value) );
ff = file_info( filename->value );
ff->is_file = finfo->attrib & _A_SUBDIR ? 0 : 1;
ff->is_dir = finfo->attrib & _A_SUBDIR ? 1 : 0;
ff->size = finfo->size;
ff->time = finfo->time_write;
ret = _findnext( handle, finfo );
}
_findclose( handle );
# endif
string_free( filename );
string_free( filespec );
d->files = files;
}
/* Special case \ or d:\ : enter it */
if( f.f_dir.len == 1 && f.f_dir.ptr[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 );
{
unsigned long len = strlen(d->name);
if( len == 1 && d->name[0] == '\\' )
(*func)( closure, d->name, 1 /* stat()'ed */, d->time );
else if( len == 3 && d->name[1] == ':' )
(*func)( closure, d->name, 1 /* stat()'ed */, d->time );
}
/* Now enter contents of directory */
string_copy( filespec, dir );
string_append( filespec, "/*" );
if( DEBUG_BINDSCAN )
printf( "scan directory %s\n", dir );
# if defined(__BORLANDC__) && __BORLANDC__ < 0x550
if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) )
if ( d->files )
{
string_free( filespec );
return;
LIST * files = d->files;
while ( files )
{
file_info_t * ff = file_info( files->string );
(*func)( closure, ff->name, 1 /* stat()'ed */, ff->time );
files = list_next( files );
}
}
PROFILE_EXIT(FILE_DIRSCAN);
}
string_new( filename );
while( !ret )
file_info_t * file_query( char * filename )
{
file_info_t * ff = file_info( filename );
if ( ! ff->time )
{
time_t time_write = finfo->ff_fdate;
struct stat statbuf;
time_write = (time_write << 16) | finfo->ff_ftime;
f.f_base.ptr = finfo->ff_name;
f.f_base.len = strlen( finfo->ff_name );
if( stat( *filename ? filename : ".", &statbuf ) < 0 )
return 0;
string_truncate( filename, 0 );
path_build( &f, filename );
(*func)( closure, filename->value, 1 /* stat()'ed */, time_write );
ret = findnext( finfo );
ff->is_file = statbuf.st_mode & S_IFREG ? 1 : 0;
ff->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0;
ff->size = statbuf.st_size;
ff->time = statbuf.st_mtime ? statbuf.st_mtime : 1;
}
# else
handle = _findfirst( filespec->value, finfo );
if( ret = ( handle < 0L ) )
{
string_free( filespec );
return;
}
string_new( filename );
while( !ret )
{
f.f_base.ptr = finfo->name;
f.f_base.len = strlen( finfo->name );
string_truncate( filename, 0 );
path_build( &f, filename, 0 );
(*func)( closure, filename->value, 1 /* stat()'ed */, finfo->time_write );
ret = _findnext( handle, finfo );
}
_findclose( handle );
# endif
string_free( filename );
string_free( filespec );
return ff;
}
/*
@@ -153,29 +220,17 @@ file_time(
char *filename,
time_t *time )
{
/* On NT this is called only for C:/ */
struct stat statbuf;
if( stat( filename, &statbuf ) < 0 )
return -1;
*time = statbuf.st_mtime;
return 0;
file_info_t * ff = file_query( filename );
if ( !ff ) return -1;
*time = ff->time;
return 0;
}
int file_is_file(char* filename)
{
struct stat statbuf;
if( stat( filename, &statbuf ) < 0 )
return -1;
if (statbuf.st_mode & S_IFREG)
return 1;
else
return 0;
file_info_t * ff = file_query( filename );
if ( !ff ) return -1;
return ff->is_file;
}
@@ -252,6 +307,8 @@ file_archscan(
*/
string_table = malloc(lar_size+1);
if ( DEBUG_PROFILE )
profile_memory( lar_size+1 );
if (read(fd, string_table, lar_size) != lar_size)
printf("error reading string table\n");
string_table[lar_size] = '\0';

View File

@@ -1,6 +1,8 @@
# include "jam.h"
# include "pathsys.h"
# include "strings.h"
# include "newstr.h"
# include "filesys.h"
void
file_build1(
@@ -31,3 +33,32 @@ file_build1(
string_push_back( file, '>' );
}
}
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 ) )
{
/* printf( "file_info: %s\n", filename ); */
finfo->name = newstr( finfo->name );
finfo->is_file = 0;
finfo->is_dir = 0;
finfo->size = 0;
finfo->time = 0;
finfo->files = 0;
}
return finfo;
}
void file_done()
{
hashdone( filecache_hash );
}

View File

@@ -18,6 +18,8 @@
# define FILESYS_DWA20011025_H
# include "pathsys.h"
#include "hash.h"
#include "lists.h"
typedef void (*scanback)( void *closure, char *file, int found, time_t t );
@@ -29,4 +31,20 @@ int file_time( char *filename, time_t *time );
void file_build1(PATHNAME *f, string* file) ;
int file_is_file(char* filename);
struct file_info_t {
char * name;
short is_file;
short is_dir;
unsigned long size;
time_t time;
LIST * files;
} ;
typedef struct file_info_t file_info_t ;
file_info_t * file_info(char * filename);
file_info_t * file_query(char * filename);
void file_done();
#endif

View File

@@ -6,14 +6,17 @@
/* This file is ALSO:
* Copyright 2001-2004 David Abrahams.
* Copyright 2005 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)
*/
# include "jam.h"
# include "debug.h"
# include "filesys.h"
# include "strings.h"
# include "pathsys.h"
# include "newstr.h"
# include <stdio.h>
#if defined(sun) || defined(__sun)
@@ -127,52 +130,110 @@ file_dirscan(
scanback func,
void *closure )
{
PATHNAME f;
DIR *d;
STRUCT_DIRENT *dirent;
PROFILE_ENTER(FILE_DIRSCAN);
file_info_t * d = 0;
d = file_query( dir );
if ( ! d || ! d->is_dir )
{
PROFILE_EXIT(FILE_DIRSCAN);
return;
}
if ( ! d->files )
{
LIST* files = L0;
PATHNAME f;
DIR *dd;
STRUCT_DIRENT *dirent;
string filename[1];
/* First enter directory itself */
/* First enter directory itself */
memset( (char *)&f, '\0', sizeof( f ) );
memset( (char *)&f, '\0', sizeof( f ) );
f.f_dir.ptr = dir;
f.f_dir.len = strlen(dir);
f.f_dir.ptr = dir;
f.f_dir.len = strlen(dir);
dir = *dir ? dir : ".";
dir = *dir ? dir : ".";
/* Special case / : enter it */
/* Now enter contents of directory */
if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '/' )
(*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
if( !( dd = opendir( dir ) ) )
{
PROFILE_EXIT(FILE_DIRSCAN);
return;
}
/* Now enter contents of directory */
if( !( d = opendir( dir ) ) )
return;
if( DEBUG_BINDSCAN )
printf( "scan directory %s\n", dir );
if( DEBUG_BINDSCAN )
printf( "scan directory %s\n", dir );
string_new( filename );
while( dirent = readdir( d ) )
{
# ifdef old_sinix
/* Broken structure definition on sinix. */
f.f_base.ptr = dirent->d_name - 2;
# else
f.f_base.ptr = dirent->d_name;
# endif
f.f_base.len = strlen( f.f_base.ptr );
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;
# else
f.f_base.ptr = dirent->d_name;
# endif
f.f_base.len = strlen( f.f_base.ptr );
string_truncate( filename, 0 );
path_build( &f, filename, 0 );
path_build( &f, filename, 0 );
(*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
}
files = list_new( files, newstr(filename->value) );
file_query( filename->value );
}
string_free( filename );
closedir( d );
closedir( dd );
d->files = files;
}
/* Special case / : enter it */
{
unsigned long len = strlen(d->name);
if( len == 1 && d->name[0] == '/' )
(*func)( closure, d->name, 1 /* stat()'ed */, d->time );
}
/* Now enter contents of directory */
if ( d->files )
{
LIST * files = d->files;
while ( files )
{
file_info_t * ff = file_info( files->string );
(*func)( closure, ff->name, 1 /* stat()'ed */, ff->time );
files = list_next( files );
}
}
PROFILE_EXIT(FILE_DIRSCAN);
}
file_info_t * file_query( char * filename )
{
file_info_t * ff = file_info( filename );
if ( ! ff->time )
{
struct stat statbuf;
if( stat( *filename ? filename : ".", &statbuf ) < 0 )
return 0;
ff->is_file = statbuf.st_mode & S_IFREG ? 1 : 0;
ff->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0;
ff->size = statbuf.st_size;
ff->time = statbuf.st_mtime ? statbuf.st_mtime : 1;
}
return ff;
}
/*
@@ -184,32 +245,17 @@ file_time(
char *filename,
time_t *time )
{
struct stat statbuf;
if( stat( filename, &statbuf ) < 0 )
return -1;
/* Technically, existing files can have 0 as statbuf.st_mtime
--- in particular, the /cygdrive directory under cygwin. However,
though all the code jam assumes that timestamp of 0 means
"does not exist" and will try to create the "missing" target, causing
problems. Work around this problem by chanding 0 to 1.
*/
*time = statbuf.st_mtime ? statbuf.st_mtime : 1 ;
return 0;
file_info_t * ff = file_query( filename );
if ( !ff ) return -1;
*time = ff->time;
return 0;
}
int file_is_file(char* filename)
{
struct stat statbuf;
if( stat( filename, &statbuf ) < 0 )
return -1;
if (S_ISREG(statbuf.st_mode))
return 1;
else
return 0;
file_info_t * ff = file_query( filename );
if ( !ff ) return -1;
return ff->is_file;
}
@@ -281,6 +327,8 @@ file_archscan(
*/
string_table = (char *)malloc(lar_size);
if ( DEBUG_PROFILE )
profile_memory( lar_size );
lseek(fd, offset + SARHDR, 0);
if (read(fd, string_table, lar_size) != lar_size)
printf("error reading string table\n");

View File

@@ -6,6 +6,8 @@
# include "jam.h"
# include "hash.h"
# include "compile.h"
#include "debug.h"
# include <assert.h>
/*
@@ -24,6 +26,10 @@
* 4/29/93 - ensure ITEM's are aligned
*/
/* */
#define HASH_DEBUG_PROFILE 1
/* */
char *hashsccssid="@(#)hash.c 1.14 () 6/20/88";
/* Header attached to all data items entered into a hash table. */
@@ -144,12 +150,24 @@ hashitem(
register ITEM *i;
unsigned char *b = (unsigned char*)(*data)->key;
unsigned int keyval;
#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.nel )
{
#ifdef HASH_DEBUG_PROFILE
if ( DEBUG_PROFILE )
profile_exit( prof );
#endif
return 0;
}
keyval = *b;
@@ -163,6 +181,10 @@ hashitem(
!strcmp( i->data.key, (*data)->key ) )
{
*data = &i->data;
#ifdef HASH_DEBUG_PROFILE
if ( DEBUG_PROFILE )
profile_exit( prof );
#endif
return !0;
}
@@ -188,6 +210,10 @@ hashitem(
*data = &i->data;
}
#ifdef HASH_DEBUG_PROFILE
if ( DEBUG_PROFILE )
profile_exit( prof );
#endif
return 0;
}
@@ -198,10 +224,12 @@ 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 *)malloc( hp->items.more * hp->items.size );
hp->items.free = 0;
if ( DEBUG_PROFILE )
profile_memory( hp->items.more * hp->items.size );
hp->items.lists[i].nel = hp->items.more;
hp->items.lists[i].base = hp->items.next;
@@ -213,6 +241,9 @@ static void hashrehash( register struct hash *hp )
hp->tab.nel = hp->items.nel * hp->bloat;
hp->tab.base = (ITEM **)malloc( hp->tab.nel * sizeof(ITEM **) );
if ( DEBUG_PROFILE )
profile_memory( hp->tab.nel * sizeof(ITEM **) );
memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) );
for( i = 0; i < hp->items.list; i++ )
@@ -268,6 +299,9 @@ hashinit(
{
struct hash *hp = (struct hash *)malloc( sizeof( *hp ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( *hp ) );
hp->bloat = 3;
hp->tab.nel = 0;
hp->tab.base = (ITEM **)0;
@@ -277,7 +311,7 @@ hashinit(
hp->items.size = sizeof( struct hashhdr ) + ALIGNED( datalen );
hp->items.list = -1;
hp->items.nel = 0;
hp->inel = 11;
hp->inel = /* */ 11 /*/ 47 /* */;
hp->name = name;
return hp;

View File

@@ -7,6 +7,9 @@
/*
* hash.h - simple in-memory hashing routines
*/
#ifndef BOOST_JAM_HASH_H
#define BOOST_JAM_HASH_H
typedef struct hashdata HASHDATA;
@@ -18,3 +21,5 @@ int hash_free( struct hash *hp, HASHDATA *data);
# define hashenter( hp, data ) (!hashitem( hp, data, !0 ))
# define hashcheck( hp, data ) hashitem( hp, data, 0 )
#endif

View File

@@ -138,7 +138,7 @@
facilitate its use in the Boost Build System, but should be backward
compatible with Perforce Jam.</p>
<p>This is version 3.1.10 of BJam and is based on version 2.4 of
<p>This is version 3.1.12 of BJam and is based on version 2.4 of
Jam/MR:</p>
<pre>
/+\
@@ -1254,7 +1254,7 @@ if $(MESSAGE) { ECHO The message is: $(MESSAGE) ; }
18 November, 2004
<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p>Copyright 2003-2004 Rene Rivera, David Abrahams, Vladimir Prus.</p>
<p>Copyright 2003-2005 Rene Rivera, David Abrahams, Vladimir Prus.</p>
<p>Distributed under the Boost Software License, Version 1.0. (See
accompanying file LICENSE_1_0.txt or <a href=

View File

@@ -121,6 +121,8 @@
# include "make.h"
# include "strings.h"
# include "expand.h"
# include "debug.h"
# include "filesys.h"
/* Macintosh is "special" */
@@ -319,6 +321,8 @@ int main( int argc, char **argv, char **arg_environ )
globs.debug[i--] = 1;
}
{ PROFILE_ENTER(MAIN);
#ifndef NDEBUG
run_unit_tests();
#endif
@@ -344,16 +348,11 @@ int main( int argc, char **argv, char **arg_environ )
}
{
/* Pleace don't change the following line. The 'bump_version.py' script
expect a specific format of it. */
char *major_version = "03", *minor_version = "01", *changenum = "11";
var_set( "JAM_VERSION",
list_new( list_new( list_new( L0, newstr( major_version ) ),
newstr( minor_version ) ),
newstr( changenum ) ),
list_new( list_new( list_new( L0, newstr( VERSION_MAJOR_SYM ) ),
newstr( VERSION_MINOR_SYM ) ),
newstr( VERSION_PATCH_SYM ) ),
VAR_SET );
}
/* And JAMUNAME */
# ifdef unix
@@ -468,6 +467,8 @@ int main( int argc, char **argv, char **arg_environ )
/* Now make target */
{
PROFILE_ENTER(MAIN_MAKE);
LIST* targets = targets_to_update();
if ( !targets )
{
@@ -478,6 +479,8 @@ int main( int argc, char **argv, char **arg_environ )
int targets_count = list_length(targets);
const char **targets2 = (const char **)malloc(targets_count * sizeof(char *));
int n = 0;
if ( DEBUG_PROFILE )
profile_memory( targets_count * sizeof(char *) );
for ( ; targets; targets = list_next(targets) )
{
targets2[n++] = targets->string;
@@ -485,9 +488,13 @@ int main( int argc, char **argv, char **arg_environ )
status |= make( targets_count, targets2, anyhow );
free(targets);
}
PROFILE_EXIT(MAIN_MAKE);
}
PROFILE_EXIT(MAIN); }
if ( DEBUG_PROFILE )
profile_dump();
@@ -497,6 +504,7 @@ int main( int argc, char **argv, char **arg_environ )
donerules();
donestamps();
donestr();
file_done();
/* close cmdout */

View File

@@ -7,6 +7,7 @@
# include "jam.h"
# include "newstr.h"
# include "lists.h"
# include "debug.h"
/*
* lists.c - maintain lists of strings
@@ -80,7 +81,9 @@ list_new(
}
else
{
l = (LIST *)malloc( sizeof( *l ) );
l = (LIST *)malloc( sizeof( LIST ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( LIST ) );
}
/* If first on chain, head points here. */

View File

@@ -127,6 +127,8 @@ static state *alloc_state()
}
else
{
if ( DEBUG_PROFILE )
profile_memory( sizeof(state) );
return (state *)malloc(sizeof(state));
}
}

View File

@@ -3,8 +3,10 @@
* 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)
*/
#include "modules.h"
#include "jam.h"
#include "debug.h"
#include "modules.h"
#include "string.h"
#include "hash.h"
#include "newstr.h"
@@ -30,6 +32,8 @@ static char* new_module_str( module_t* m, char* suffix )
module_t* bindmodule( char* name )
{
PROFILE_ENTER(BINDMODULE);
string s;
module_t m_, *m = &m_;
@@ -56,6 +60,9 @@ module_t* bindmodule( char* name )
m->user_module = 0;
}
string_free( &s );
PROFILE_EXIT(BINDMODULE);
return m;
}
@@ -115,9 +122,11 @@ void exit_module( module_t* m )
}
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");
h = target_module->imported_modules;
@@ -129,6 +138,8 @@ void import_module(LIST* module_names, module_t* target_module)
hashenter(h, (HASHDATA**)&ss);
}
PROFILE_EXIT(IMPORT_MODULE);
}
static void add_module_name( void* r_, void* result_ )

View File

@@ -7,6 +7,7 @@
#include "../strings.h"
#include "../newstr.h"
#include "../variable.h"
#include "../debug.h"
/* Use quite klugy approach: when we add order dependency from 'a' to 'b',
@@ -62,6 +63,8 @@ void topological_sort(int** graph, int num_vertices, int* result)
{
int i;
int* colors = (int*)calloc(num_vertices, sizeof(int));
if ( DEBUG_PROFILE )
profile_memory( num_vertices*sizeof(int) );
for (i = 0; i < num_vertices; ++i)
colors[i] = white;
@@ -86,6 +89,8 @@ LIST *order( PARSE *parse, FRAME *frame )
int length = list_length(arg);
int** graph = (int**)calloc(length, sizeof(int*));
int* order = (int*)malloc((length+1)*sizeof(int));
if ( DEBUG_PROFILE )
profile_memory( length*sizeof(int*) + (length+1)*sizeof(int) );
for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) {
/* For all object this one depend upon, add elements
@@ -94,6 +99,8 @@ LIST *order( PARSE *parse, FRAME *frame )
int index = 0;
graph[src] = (int*)calloc(list_length(dependencies)+1, sizeof(int));
if ( DEBUG_PROFILE )
profile_memory( (list_length(dependencies)+1)*sizeof(int) );
for(; dependencies; dependencies = dependencies->next) {
int dst = list_index(arg, dependencies->string);
if (dst != -1)

View File

@@ -7,6 +7,7 @@
# include "jam.h"
# include "newstr.h"
# include "hash.h"
# include "compile.h"
# include <stddef.h>
# include <stdlib.h>
@@ -34,6 +35,8 @@ typedef char *STRING;
static struct hash *strhash = 0;
static int strtotal = 0;
static int strcount_in = 0;
static int strcount_out = 0;
/*
* Immortal string allocator implementation speeds string allocation
@@ -53,11 +56,20 @@ static strblock* strblock_chain = 0;
static char* storage_start = 0;
static char* storage_finish = 0;
/* */
#define SIMPLE_ALLOC 0
/*/
#define SIMPLE_ALLOC 1
/* */
/*
* allocate() - Allocate n bytes of immortal string storage
*/
static char* allocate(size_t n)
{
#if SIMPLE_ALLOC
return (char*)malloc(n);
#else
/* See if we can grab storage from an existing block */
size_t remaining = storage_finish - storage_start;
if ( remaining >= n )
@@ -88,6 +100,7 @@ static char* allocate(size_t n)
}
return new_block->data;
}
#endif
}
/*
@@ -112,8 +125,12 @@ newstr( char *string )
strtotal += l + 1;
memcpy( m, string, l + 1 );
*s = m;
if ( DEBUG_PROFILE )
profile_memory( l+1 );
}
strcount_in += 1;
return *s;
}
@@ -124,6 +141,7 @@ newstr( char *string )
char *
copystr( char *s )
{
strcount_in += 1;
return s;
}
@@ -134,6 +152,7 @@ copystr( char *s )
void
freestr( char *s )
{
strcount_out += 1;
}
/*
@@ -155,4 +174,6 @@ donestr()
if( DEBUG_MEM )
printf( "%dK in strings\n", strtotal / 1024 );
/* printf( "--- %d strings of %d dangling\n", strcount_in-strcount_out, strcount_in ); */
}

View File

@@ -17,6 +17,7 @@
# include "newstr.h"
# include "modules.h"
# include "frames.h"
# include "debug.h"
/*
* parse.c - make and destroy parse trees as driven by the parser
@@ -78,6 +79,8 @@ parse_make(
int num )
{
PARSE *p = (PARSE *)malloc( sizeof( PARSE ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( PARSE ) );
p->func = func;
p->left = left;

View File

@@ -7,5 +7,11 @@
/* Keep JAMVERSYM in sync with VERSION. */
/* It can be accessed as $(JAMVERSION) in the Jamfile. */
#define VERSION "3.1.11"
#define VERSION_MAJOR 3
#define VERSION_MINOR 1
#define VERSION_PATCH 12
#define VERSION_MAJOR_SYM "03"
#define VERSION_MINOR_SYM "1"
#define VERSION_PATCH_SYM "12"
#define VERSION "3.1.12"
#define JAMVERSYM "JAMVERSION=3.1"

View File

@@ -1,4 +1,4 @@
/* Copyright Vladimir Prus 2002. Distributed under the Boost */
/* Copyright Vladimir Prus 2002, Rene Rivera 2005. 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) */
@@ -21,24 +21,32 @@
#endif
#endif
/* The current directory can't change in bjam, so optimize this to cache
** the result.
*/
static char pwd_buffer[PATH_MAX];
static char * pwd_result = NULL;
LIST*
pwd(void)
{
char buffer[PATH_MAX];
if (getcwd(buffer, sizeof(buffer)) == NULL)
{
perror("can not get current directory");
return L0;
}
else
if (!pwd_result)
{
if (getcwd(pwd_buffer, sizeof(pwd_buffer)) == NULL)
{
perror("can not get current directory");
return L0;
}
else
{
#ifdef NT
return list_new(L0, short_path_to_long_path(buffer));
pwd_result = short_path_to_long_path(pwd_buffer);
#else
return list_new(L0, newstr(buffer));
pwd_result = newstr(pwd_buffer);
#endif
}
}
return list_new(L0, pwd_result);
}

View File

@@ -42,6 +42,7 @@
* regular-expression syntax might require a total rethink.
*/
#include "regexp.h"
#include "debug.h"
#include <stdio.h>
#include <ctype.h>
#ifndef ultrix
@@ -241,6 +242,8 @@ regcomp( char *exp )
r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
if (r == NULL)
FAIL("out of space");
if ( DEBUG_PROFILE )
profile_memory( sizeof(regexp) + (unsigned)regsize );
/* Second pass: emit code. */
regparse = (char *)exp;

View File

@@ -16,6 +16,7 @@
# include "lists.h"
# include "pathsys.h"
# include "timestamp.h"
# include "debug.h"
/* This file is ALSO:
* Copyright 2001-2004 David Abrahams.
@@ -265,6 +266,8 @@ copytarget( const TARGET *ot )
TARGET *t;
t = (TARGET *)malloc( sizeof( *t ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( *t ) );
memset( (char *)t, '\0', sizeof( *t ) );
t->name = copystr( ot->name );
t->boundname = t->name;
@@ -319,6 +322,8 @@ targetentry(
TARGETS *c;
c = (TARGETS *)malloc( sizeof( TARGETS ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( TARGETS ) );
c->target = target;
if( !chain ) chain = c;
@@ -365,6 +370,8 @@ actionlist(
ACTION *action )
{
ACTIONS *actions = (ACTIONS *)malloc( sizeof( ACTIONS ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( ACTIONS ) );
actions->action = action;
@@ -413,7 +420,11 @@ addsettings(
if ( v )
settings_freelist = v->next;
else
{
v = (SETTINGS *)malloc( sizeof( *v ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( *v ) );
}
v->symbol = newstr( symbol );
v->value = value;
@@ -553,6 +564,8 @@ donerules()
argument_list* args_new()
{
argument_list* r = (argument_list*)malloc( sizeof(argument_list) );
if ( DEBUG_PROFILE )
profile_memory( sizeof(argument_list) );
r->reference_count = 0;
lol_init(r->data);
return r;
@@ -690,6 +703,8 @@ static void set_rule_actions( RULE* rule, rule_actions* actions )
static rule_actions* actions_new( char* command, LIST* bindlist, int flags )
{
rule_actions* result = (rule_actions*)malloc(sizeof(rule_actions));
if ( DEBUG_PROFILE )
profile_memory( sizeof(rule_actions) );
result->command = copystr( command );
result->bindlist = bindlist;
result->flags = flags;

View File

@@ -11,6 +11,7 @@
# include "jamgram.h"
# include "jambase.h"
# include "newstr.h"
# include "debug.h"
/*
* scan.c - the jam yacc scanner
@@ -82,6 +83,8 @@ void
yyfparse( char *s )
{
struct include *i = (struct include *)malloc( sizeof( *i ) );
if ( DEBUG_PROFILE )
profile_memory( sizeof( *i ) );
/* Push this onto the incp chain. */

View File

@@ -3,6 +3,7 @@
/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
#include "strings.h"
#include "debug.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
@@ -55,6 +56,8 @@ static void string_reserve_internal( string* self, size_t capacity )
if ( self->value == self->opt )
{
self->value = (char*)malloc( capacity + JAM_STRING_MAGIC_SIZE );
if ( DEBUG_PROFILE )
profile_memory( capacity + JAM_STRING_MAGIC_SIZE );
self->value[0] = 0;
strncat( self->value, self->opt, sizeof(self->opt) );
assert( strlen( self->value ) <= self->capacity ); /* This is a regression test */

View File

@@ -11,6 +11,8 @@
*/
# include "jam.h"
# include "debug.h"
# include "hash.h"
# include "filesys.h"
# include "pathsys.h"
@@ -69,13 +71,15 @@ timestamp(
char *target,
time_t *time )
{
PROFILE_ENTER(timestamp);
PATHNAME f1, f2;
BINDING binding, *b = &binding;
string buf[1];
string path;
char *p;
# ifdef DOWNSHIFT_PATHS
string path;
char *p;
string_copy( &path, target );
p = path.value;
@@ -181,6 +185,8 @@ timestamp(
# ifdef DOWNSHIFT_PATHS
string_free( &path );
#endif
PROFILE_EXIT(timestamp);
}
static void

View File

@@ -82,17 +82,17 @@ rule xinit ( instance : class )
rule new ( class args * : * )
{
.next-instance.$(class) ?= 1 ;
local id = object($(class))@$(.next-instance.$(class)) ;
.next-instance ?= 1 ;
local id = object($(class))@$(.next-instance) ;
xinit $(id) : $(class) ;
xinit $(id) : $(class) ;
INSTANCE $(id) : class@$(class) ;
IMPORT_MODULE $(id) : ;
$(id).__init__ $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
# bump the next unique object name
.next-instance.$(class) = [ numbers.increment $(.next-instance.$(class)) ] ;
.next-instance = [ numbers.increment $(.next-instance) ] ;
# Return the name of the new instance.
return $(id) ;

View File

@@ -140,7 +140,7 @@ rule reverse ( path )
#
local rule join-imp ( elements + )
{
return [ NORMALIZE_PATH $(elements:J="/") ] ;
return [ NORMALIZE_PATH $(elements) ] ;
}
#

View File

@@ -342,7 +342,7 @@ rule text (
text-body on $(output-target) = ;
text-suffix on $(output-target) = ;
text-action $(output-target) ;
text-front-section.$(soutput-target) = ;
text-front-section.$(output-target) = ;
}
if $(overwrite)
{
@@ -368,10 +368,9 @@ rule text (
text-front-section.$(output-target) = $(prefix-body-suffix) ;
strings = $(strings[2-]) ;
}
while $(strings)
for local string-n in $(strings)
{
text-$(prefix-body-suffix) on $(output-target) += [ echo-cmd $(strings[1]) ] ;
strings = $(strings[2-]) ;
text-$(prefix-body-suffix) on $(output-target) += [ echo-cmd $(string-n) ] ;
}
}
}