diff options
Diffstat (limited to 'jam-files/engine/jam.c')
-rw-r--r-- | jam-files/engine/jam.c | 632 |
1 files changed, 0 insertions, 632 deletions
diff --git a/jam-files/engine/jam.c b/jam-files/engine/jam.c deleted file mode 100644 index e11d082b..00000000 --- a/jam-files/engine/jam.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * /+\ - * +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * \+/ - * - * This file is part of jam. - * - * License is hereby granted to use this software and distribute it - * freely, as long as this copyright notice is retained and modifications - * are clearly marked. - * - * ALL WARRANTIES ARE HEREBY DISCLAIMED. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -/* - * jam.c - make redux - * - * See Jam.html for usage information. - * - * These comments document the code. - * - * The top half of the code is structured such: - * - * jam - * / | \ - * +---+ | \ - * / | \ - * jamgram option \ - * / | \ \ - * / | \ \ - * / | \ | - * scan | compile make - * | | / | \ / | \ - * | | / | \ / | \ - * | | / | \ / | \ - * jambase parse | rules search make1 - * | | | \ - * | | | \ - * | | | \ - * builtins timestamp command execute - * | - * | - * | - * filesys - * - * - * The support routines are called by all of the above, but themselves - * are layered thus: - * - * variable|expand - * / | | | - * / | | | - * / | | | - * lists | | pathsys - * \ | | - * \ | | - * \ | | - * newstr | - * \ | - * \ | - * \ | - * hash - * - * Roughly, the modules are: - * - * builtins.c - jam's built-in rules - * command.c - maintain lists of commands - * compile.c - compile parsed jam statements - * execunix.c - execute a shell script on UNIX - * execvms.c - execute a shell script, ala VMS - * expand.c - expand a buffer, given variable values - * file*.c - scan directories and archives on * - * hash.c - simple in-memory hashing routines - * hdrmacro.c - handle header file parsing for filename macro definitions - * headers.c - handle #includes in source files - * jambase.c - compilable copy of Jambase - * jamgram.y - jam grammar - * lists.c - maintain lists of strings - * make.c - bring a target up to date, once rules are in place - * make1.c - execute command to bring targets up to date - * newstr.c - string manipulation routines - * option.c - command line option processing - * parse.c - make and destroy parse trees as driven by the parser - * path*.c - manipulate file names on * - * hash.c - simple in-memory hashing routines - * regexp.c - Henry Spencer's regexp - * rules.c - access to RULEs, TARGETs, and ACTIONs - * scan.c - the jam yacc scanner - * search.c - find a target along $(SEARCH) or $(LOCATE) - * timestamp.c - get the timestamp of a file or archive member - * variable.c - handle jam multi-element variables - * - * 05/04/94 (seiwald) - async multiprocess (-j) support - * 02/08/95 (seiwald) - -n implies -d2. - * 02/22/95 (seiwald) - -v for version info. - * 09/11/00 (seiwald) - PATCHLEVEL folded into VERSION. - * 01/10/01 (seiwald) - pathsys.h split from filesys.h - */ - - -#include "jam.h" -#include "option.h" -#include "patchlevel.h" - -/* These get various function declarations. */ -#include "lists.h" -#include "parse.h" -#include "variable.h" -#include "compile.h" -#include "builtins.h" -#include "rules.h" -#include "newstr.h" -#include "scan.h" -#include "timestamp.h" -#include "make.h" -#include "strings.h" -#include "expand.h" -#include "filesys.h" -#include "output.h" - -/* Macintosh is "special" */ -#ifdef OS_MAC - #include <QuickDraw.h> -#endif - -/* And UNIX for this. */ -#ifdef unix - #include <sys/utsname.h> - #include <signal.h> -#endif - -struct globs globs = -{ - 0, /* noexec */ - 1, /* jobs */ - 0, /* quitquick */ - 0, /* newestfirst */ - 0, /* pipes action stdout and stderr merged to action output */ -#ifdef OS_MAC - { 0, 0 }, /* debug - suppress tracing output */ -#else - { 0, 1 }, /* debug ... */ -#endif - 0, /* output commands, not run them */ - 0 /* action timeout */ -}; - -/* Symbols to be defined as true for use in Jambase. */ -static char * othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 }; - - -/* Known for sure: - * mac needs arg_enviro - * OS2 needs extern environ - */ - -#ifdef OS_MAC - #define use_environ arg_environ - #ifdef MPW - QDGlobals qd; - #endif -#endif - -/* on Win32-LCC */ -#if defined( OS_NT ) && defined( __LCC__ ) - #define use_environ _environ -#endif - -# if defined( __MWERKS__) - #define use_environ _environ - extern char * * _environ; -#endif - -#ifndef use_environ - #define use_environ environ - #if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT ) - extern char **environ; - #endif -#endif - -#if YYDEBUG != 0 - extern int yydebug; -#endif - -#ifndef NDEBUG -static void run_unit_tests() -{ -#if defined( USE_EXECNT ) - extern void execnt_unit_test(); - execnt_unit_test(); -#endif - string_unit_test(); - var_expand_unit_test(); -} -#endif - -int anyhow = 0; - -#ifdef HAVE_PYTHON - extern PyObject * bjam_call ( PyObject * self, PyObject * args ); - extern PyObject * bjam_import_rule ( PyObject * self, PyObject * args ); - extern PyObject * bjam_define_action( PyObject * self, PyObject * args ); - extern PyObject * bjam_variable ( PyObject * self, PyObject * args ); - extern PyObject * bjam_backtrace ( PyObject * self, PyObject * args ); - extern PyObject * bjam_caller ( PyObject * self, PyObject * args ); -#endif - -char *saved_argv0; - -int main( int argc, char * * argv, char * * arg_environ ) -{ - int n; - char * s; - struct bjam_option optv[N_OPTS]; - char const * all = "all"; - int status; - int arg_c = argc; - char * * arg_v = argv; - char const * progname = argv[0]; - - saved_argv0 = argv[0]; - - BJAM_MEM_INIT(); - -# ifdef OS_MAC - InitGraf(&qd.thePort); -# endif - - --argc; - ++argv; - - if ( getoptions( argc, argv, "-:l:d:j:p:f:gs:t:ano:qv", optv ) < 0 ) - { - printf( "\nusage: %s [ options ] targets...\n\n", progname ); - - printf( "-a Build all targets, even if they are current.\n" ); - printf( "-dx Set the debug level to x (0-9).\n" ); - printf( "-fx Read x instead of Jambase.\n" ); - /* printf( "-g Build from newest sources first.\n" ); */ - printf( "-jx Run up to x shell commands concurrently.\n" ); - printf( "-lx Limit actions to x number of seconds after which they are stopped.\n" ); - printf( "-n Don't actually execute the updating actions.\n" ); - printf( "-ox Write the updating actions to file x.\n" ); - printf( "-px x=0, pipes action stdout and stderr merged into action output.\n" ); - printf( "-q Quit quickly as soon as a target fails.\n" ); - printf( "-sx=y Set variable x=y, overriding environment.\n" ); - printf( "-tx Rebuild x, even if it is up-to-date.\n" ); - printf( "-v Print the version of jam and exit.\n" ); - printf( "--x Option is ignored.\n\n" ); - - exit( EXITBAD ); - } - - /* Version info. */ - if ( ( s = getoptval( optv, 'v', 0 ) ) ) - { - printf( "Boost.Jam " ); - printf( "Version %s. %s.\n", VERSION, OSMINOR ); - printf( " Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. \n" ); - printf( " Copyright 2001 David Turner.\n" ); - printf( " Copyright 2001-2004 David Abrahams.\n" ); - printf( " Copyright 2002-2008 Rene Rivera.\n" ); - printf( " Copyright 2003-2008 Vladimir Prus.\n" ); - - return EXITOK; - } - - /* Pick up interesting options. */ - if ( ( s = getoptval( optv, 'n', 0 ) ) ) - globs.noexec++, globs.debug[2] = 1; - - if ( ( s = getoptval( optv, 'p', 0 ) ) ) - { - /* Undocumented -p3 (acts like both -p1 -p2) means separate pipe action - * stdout and stderr. - */ - globs.pipe_action = atoi( s ); - if ( ( 3 < globs.pipe_action ) || ( globs.pipe_action < 0 ) ) - { - printf( - "Invalid pipe descriptor '%d', valid values are -p[0..3].\n", - globs.pipe_action ); - exit( EXITBAD ); - } - } - - if ( ( s = getoptval( optv, 'q', 0 ) ) ) - globs.quitquick = 1; - - if ( ( s = getoptval( optv, 'a', 0 ) ) ) - anyhow++; - - if ( ( s = getoptval( optv, 'j', 0 ) ) ) - { - globs.jobs = atoi( s ); - if (globs.jobs == 0) - { - printf("Invalid value for the '-j' option.\n"); - exit(EXITBAD); - } - } - - if ( ( s = getoptval( optv, 'g', 0 ) ) ) - globs.newestfirst = 1; - - if ( ( s = getoptval( optv, 'l', 0 ) ) ) - globs.timeout = atoi( s ); - - /* Turn on/off debugging */ - for ( n = 0; ( s = getoptval( optv, 'd', n ) ); ++n ) - { - int i; - - /* First -d, turn off defaults. */ - if ( !n ) - for ( i = 0; i < DEBUG_MAX; ++i ) - globs.debug[i] = 0; - - i = atoi( s ); - - if ( ( i < 0 ) || ( i >= DEBUG_MAX ) ) - { - printf( "Invalid debug level '%s'.\n", s ); - continue; - } - - /* n turns on levels 1-n. */ - /* +n turns on level n. */ - if ( *s == '+' ) - globs.debug[i] = 1; - else while ( i ) - globs.debug[i--] = 1; - } - - { - PROFILE_ENTER( MAIN ); - -#ifdef HAVE_PYTHON - { - PROFILE_ENTER( MAIN_PYTHON ); - Py_Initialize(); - { - static PyMethodDef BjamMethods[] = { - {"call", bjam_call, METH_VARARGS, - "Call the specified bjam rule."}, - {"import_rule", bjam_import_rule, METH_VARARGS, - "Imports Python callable to bjam."}, - {"define_action", bjam_define_action, METH_VARARGS, - "Defines a command line action."}, - {"variable", bjam_variable, METH_VARARGS, - "Obtains a variable from bjam's global module."}, - {"backtrace", bjam_backtrace, METH_VARARGS, - "Returns bjam backtrace from the last call into Python."}, - {"caller", bjam_caller, METH_VARARGS, - "Returns the module from which the last call into Python is made."}, - {NULL, NULL, 0, NULL} - }; - - Py_InitModule( "bjam", BjamMethods ); - } - PROFILE_EXIT( MAIN_PYTHON ); - } -#endif - -#ifndef NDEBUG - run_unit_tests(); -#endif -#if YYDEBUG != 0 - if ( DEBUG_PARSE ) - yydebug = 1; -#endif - - /* Set JAMDATE. */ - var_set( "JAMDATE", list_new( L0, outf_time(time(0)) ), VAR_SET ); - - /* Set JAM_VERSION. */ - var_set( "JAM_VERSION", - list_new( list_new( list_new( L0, - newstr( VERSION_MAJOR_SYM ) ), - newstr( VERSION_MINOR_SYM ) ), - newstr( VERSION_PATCH_SYM ) ), - VAR_SET ); - - /* Set JAMUNAME. */ -#ifdef unix - { - struct utsname u; - - if ( uname( &u ) >= 0 ) - { - var_set( "JAMUNAME", - list_new( - list_new( - list_new( - list_new( - list_new( L0, - newstr( u.sysname ) ), - newstr( u.nodename ) ), - newstr( u.release ) ), - newstr( u.version ) ), - newstr( u.machine ) ), VAR_SET ); - } - } -#endif /* unix */ - - /* Load up environment variables. */ - - /* First into the global module, with splitting, for backward - * compatibility. - */ - var_defines( use_environ, 1 ); - - /* Then into .ENVIRON, without splitting. */ - enter_module( bindmodule(".ENVIRON") ); - var_defines( use_environ, 0 ); - exit_module( bindmodule(".ENVIRON") ); - - /* - * Jam defined variables OS & OSPLAT. We load them after environment, so - * that setting OS in environment does not change Jam's notion of the - * current platform. - */ - var_defines( othersyms, 1 ); - - /* Load up variables set on command line. */ - for ( n = 0; ( s = getoptval( optv, 's', n ) ); ++n ) - { - char *symv[2]; - symv[ 0 ] = s; - symv[ 1 ] = 0; - var_defines( symv, 1 ); - enter_module( bindmodule(".ENVIRON") ); - var_defines( symv, 0 ); - exit_module( bindmodule(".ENVIRON") ); - } - - /* Set the ARGV to reflect the complete list of arguments of invocation. - */ - for ( n = 0; n < arg_c; ++n ) - var_set( "ARGV", list_new( L0, newstr( arg_v[n] ) ), VAR_APPEND ); - - /* Initialize built-in rules. */ - load_builtins(); - - /* Add the targets in the command line to the update list. */ - for ( n = 1; n < arg_c; ++n ) - { - if ( arg_v[ n ][ 0 ] == '-' ) - { - char * f = "-:l:d:j:f:gs:t:ano:qv"; - for ( ; *f; ++f ) if ( *f == arg_v[ n ][ 1 ] ) break; - if ( ( f[ 1 ] == ':' ) && ( arg_v[ n ][ 2 ] == '\0' ) ) ++n; - } - else - { - mark_target_for_updating( arg_v[ n ] ); - } - } - - if (!targets_to_update()) - mark_target_for_updating("all"); - - /* Parse ruleset. */ - { - FRAME frame[ 1 ]; - frame_init( frame ); - for ( n = 0; ( s = getoptval( optv, 'f', n ) ); ++n ) - parse_file( s, frame ); - - if ( !n ) - parse_file( "+", frame ); - } - - status = yyanyerrors(); - - /* Manually touch -t targets. */ - for ( n = 0; ( s = getoptval( optv, 't', n ) ); ++n ) - touch_target( s ); - - /* If an output file is specified, set globs.cmdout to that. */ - if ( ( s = getoptval( optv, 'o', 0 ) ) ) - { - if ( !( globs.cmdout = fopen( s, "w" ) ) ) - { - printf( "Failed to write to '%s'\n", s ); - exit( EXITBAD ); - } - ++globs.noexec; - } - - /* The build system may set the PARALLELISM variable to override -j - options. */ - { - LIST *p = L0; - p = var_get ("PARALLELISM"); - if (p) - { - int j = atoi (p->string); - if (j == -1) - { - printf( "Invalid value of PARALLELISM: %s\n", p->string); - } - else - { - globs.jobs = j; - } - } - } - - /* KEEP_GOING overrides -q option. */ - { - LIST *p = L0; - p = var_get ("KEEP_GOING"); - if (p) - { - int v = atoi (p->string); - if (v == 0) - globs.quitquick = 1; - else - globs.quitquick = 0; - } - } - - /* Now make target. */ - { - PROFILE_ENTER( MAIN_MAKE ); - - LIST * targets = targets_to_update(); - if (targets) - { - int targets_count = list_length( targets ); - const char * * targets2 = (const char * *) - BJAM_MALLOC( targets_count * sizeof( char * ) ); - int n = 0; - for ( ; targets; targets = list_next( targets ) ) - targets2[ n++ ] = targets->string; - status |= make( targets_count, targets2, anyhow ); - free( targets ); - } - else - { - status = last_update_now_status; - } - - PROFILE_EXIT( MAIN_MAKE ); - } - - PROFILE_EXIT( MAIN ); - } - - if ( DEBUG_PROFILE ) - profile_dump(); - - /* Widely scattered cleanup. */ - var_done(); - file_done(); - rules_done(); - stamps_done(); - str_done(); - - /* Close cmdout. */ - if ( globs.cmdout ) - fclose( globs.cmdout ); - -#ifdef HAVE_PYTHON - Py_Finalize(); -#endif - - BJAM_MEM_CLOSE(); - - return status ? EXITBAD : EXITOK; -} - -#if defined(_WIN32) -#include <windows.h> -char *executable_path(char *argv0) { - char buf[1024]; - DWORD ret = GetModuleFileName(NULL, buf, sizeof(buf)); - if (ret == 0 || ret == sizeof(buf)) return NULL; - return strdup (buf); -} -#elif defined(__APPLE__) /* Not tested */ -#include <mach-o/dyld.h> -char *executable_path(char *argv0) { - char buf[1024]; - uint32_t size = sizeof(buf); - int ret = _NSGetExecutablePath(buf, &size); - if (ret != 0) return NULL; - return strdup(buf); -} -#elif defined(sun) || defined(__sun) /* Not tested */ -#include <stdlib.h> - -char *executable_path(char *argv0) { - return strdup(getexecname()); -} -#elif defined(__FreeBSD__) -#include <sys/sysctl.h> -char *executable_path(char *argv0) { - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - char buf[1024]; - size_t size = sizeof(buf); - sysctl(mib, 4, buf, &size, NULL, 0); - if (size == 0 || size == sizeof(buf)) return NULL; - return strndup(buf, size); -} -#elif defined(__linux__) -#include <unistd.h> -char *executable_path(char *argv0) { - char buf[1024]; - ssize_t ret = readlink("/proc/self/exe", buf, sizeof(buf)); - if (ret == 0 || ret == sizeof(buf)) return NULL; - return strndup(buf, ret); -} -#else -char *executable_path(char *argv0) { - /* If argv0 is absolute path, assume it's the right absolute path. */ - if (argv0[0] == "/") - return strdup(argv0); - return NULL; -} -#endif |