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:
@@ -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 )
|
||||
|
||||
@@ -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) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
127
src/engine/debug.c
Normal 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
53
src/engine/debug.h
Normal 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
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -127,6 +127,8 @@ static state *alloc_state()
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( DEBUG_PROFILE )
|
||||
profile_memory( sizeof(state) );
|
||||
return (state *)malloc(sizeof(state));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_ )
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ); */
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) ;
|
||||
|
||||
@@ -140,7 +140,7 @@ rule reverse ( path )
|
||||
#
|
||||
local rule join-imp ( elements + )
|
||||
{
|
||||
return [ NORMALIZE_PATH $(elements:J="/") ] ;
|
||||
return [ NORMALIZE_PATH $(elements) ] ;
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -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) ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user