📄 builtins.c
字号:
/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */# include "jam.h"# include "lists.h"# include "parse.h"# include "builtins.h"# include "rules.h"# include "filesys.h"# include "newstr.h"# include "regexp.h"# include "frames.h"# include "hash.h"# include "strings.h"# include "pwd.h"# include "pathsys.h"# include "make.h"# include "hdrmacro.h"# include "compile.h"# include "native.h"# include "variable.h"# include "timestamp.h"# include <ctype.h>/* * builtins.c - builtin jam rules * * External routines: * * load_builtin() - define builtin rules * * Internal routines: * * builtin_depends() - DEPENDS/INCLUDES rule * builtin_echo() - ECHO rule * builtin_exit() - EXIT rule * builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule * builtin_glob() - GLOB rule * builtin_match() - MATCH rule * * 01/10/01 (seiwald) - split from compile.c *//* * compile_builtin() - define builtin rules */# define P0 (PARSE *)0# define C0 (char *)0# if defined( OS_NT ) || defined( OS_CYGWIN )LIST* builtin_system_registry( PARSE *parse, FRAME *frame );LIST* builtin_system_registry_names( PARSE *parse, FRAME *frame );# endifint glob( char *s, char *c );void backtrace( FRAME *frame );void backtrace_line( FRAME *frame );void print_source_line( PARSE* p );RULE* bind_builtin( char* name, LIST*(*f)(PARSE*, FRAME*), int flags, char** args ){ argument_list* arg_list = 0; if ( args ) { arg_list = args_new(); lol_build( arg_list->data, args ); } return new_rule_body( root_module(), name, arg_list, parse_make( f, P0, P0, P0, C0, C0, flags ), 1 );}RULE* duplicate_rule( char* name, RULE* other ){ return import_rule( other, root_module(), name );}voidload_builtins(){ duplicate_rule( "Always" , bind_builtin( "ALWAYS" , builtin_flags, T_FLAG_TOUCHED, 0 ) ); duplicate_rule( "Depends" , bind_builtin( "DEPENDS" , builtin_depends, 0, 0 ) ); duplicate_rule( "echo" , duplicate_rule( "Echo" , bind_builtin( "ECHO" , builtin_echo, 0, 0 ) ) ); { char * args[] = { "message", "*", ":", "result-value", "?", 0 }; duplicate_rule( "exit" , duplicate_rule( "Exit" , bind_builtin( "EXIT" , builtin_exit, 0, args ) ) ); } { char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 }; duplicate_rule( "Glob" , bind_builtin( "GLOB" , builtin_glob, 0, args ) ); } { char * args[] = { "patterns", "*", 0 }; bind_builtin( "GLOB-RECURSIVELY" , builtin_glob_recursive, 0, args ); } duplicate_rule( "Includes" , bind_builtin( "INCLUDES" , builtin_depends, 1, 0 ) ); { char * args[] = { "targets", "*", ":", "targets-to-rebuild", "*", 0 }; bind_builtin( "REBUILDS" , builtin_rebuilds, 0, args ); } duplicate_rule( "Leaves" , bind_builtin( "LEAVES" , builtin_flags, T_FLAG_LEAVES, 0 ) ); duplicate_rule( "Match" , bind_builtin( "MATCH" , builtin_match, 0, 0 ) ); duplicate_rule( "NoCare" , bind_builtin( "NOCARE" , builtin_flags, T_FLAG_NOCARE, 0 ) ); duplicate_rule( "NOTIME" , duplicate_rule( "NotFile" , bind_builtin( "NOTFILE" , builtin_flags, T_FLAG_NOTFILE, 0 ) ) ); duplicate_rule( "NoUpdate" , bind_builtin( "NOUPDATE" , builtin_flags, T_FLAG_NOUPDATE, 0 ) ); duplicate_rule( "Temporary" , bind_builtin( "TEMPORARY" , builtin_flags, T_FLAG_TEMP, 0 ) ); { char * args[] = { "targets", "*", 0 }; bind_builtin( "ISFILE", builtin_flags, T_FLAG_ISFILE, 0 ); } duplicate_rule( "HdrMacro" , bind_builtin( "HDRMACRO" , builtin_hdrmacro, 0, 0 ) ); /* FAIL_EXPECTED is used to indicate that the result of a target build */ /* action should be inverted (ok <=> fail) this can be useful when */ /* performing test runs from Jamfiles.. */ bind_builtin( "FAIL_EXPECTED" , builtin_flags, T_FLAG_FAIL_EXPECTED, 0 ); bind_builtin( "RMOLD" , builtin_flags, T_FLAG_RMOLD, 0 ); { char * args[] = { "targets", "*", 0 }; bind_builtin( "UPDATE", builtin_update, 0, args ); } { char * args[] = { "string", "pattern", "replacements", "+", 0 }; duplicate_rule( "subst" , bind_builtin( "SUBST" , builtin_subst, 0, args ) ); } { char * args[] = { "module", "?", 0 }; bind_builtin( "RULENAMES" , builtin_rulenames, 0, args ); } { char * args[] = { "module", "?", 0 }; bind_builtin( "VARNAMES" , builtin_varnames, 0, args ); } { char * args[] = { "module", "?", 0 }; bind_builtin( "DELETE_MODULE" , builtin_delete_module, 0, args ); } { char * args[] = { "source_module", "?", ":", "source_rules", "*", ":", "target_module", "?", ":", "target_rules", "*", ":", "localize", "?", 0 }; bind_builtin( "IMPORT" , builtin_import, 0, args ); } { char * args[] = { "module", "?", ":", "rules", "*", 0 }; bind_builtin( "EXPORT" , builtin_export, 0, args ); } { char * args[] = { "levels", "?", 0 }; bind_builtin( "CALLER_MODULE" , builtin_caller_module, 0, args ); } { char * args[] = { "levels", "?", 0 }; bind_builtin( "BACKTRACE" , builtin_backtrace, 0, args ); } { char * args[] = { 0 }; bind_builtin( "PWD" , builtin_pwd, 0, args ); } { char * args[] = { "target", "*", ":", "path", "*", 0 }; bind_builtin( "SEARCH_FOR_TARGET", builtin_search_for_target, 0, args ); } { char * args[] = { "modules_to_import", "+", ":", "target_module", "?", 0 }; bind_builtin( "IMPORT_MODULE", builtin_import_module, 0, args ); } { char * args[] = { "module", "?", 0 }; bind_builtin( "IMPORTED_MODULES", builtin_imported_modules, 0, args ); } { char * args[] = { "instance_module", ":", "class_module", 0 }; bind_builtin( "INSTANCE", builtin_instance, 0, args ); } { char * args[] = { "sequence", "*", 0 }; bind_builtin( "SORT", builtin_sort, 0, args ); } { char * args[] = { "path_parts", "*", 0 }; bind_builtin( "NORMALIZE_PATH", builtin_normalize_path, 0, args ); } { char * args[] = { "args", "*", 0 }; bind_builtin( "CALC", builtin_calc, 0, args ); } { char * args[] = { "module", ":", "rule", 0 }; bind_builtin( "NATIVE_RULE", builtin_native_rule, 0, args ); } { char * args[] = { "module", ":", "rule", ":", "version", 0 }; bind_builtin( "HAS_NATIVE_RULE", builtin_has_native_rule, 0, args ); } { char * args[] = { "module", "*", 0 }; bind_builtin( "USER_MODULE", builtin_user_module, 0, args ); } { char * args[] = { 0 }; bind_builtin( "NEAREST_USER_LOCATION", builtin_nearest_user_location, 0, args ); } { char * args[] = { "file", 0 }; bind_builtin( "CHECK_IF_FILE", builtin_check_if_file, 0, args ); }#ifdef HAVE_PYTHON { char * args[] = { "python-module", ":", "function", ":", "jam-module", ":", "rule-name", 0 }; bind_builtin( "PYTHON_IMPORT_RULE", builtin_python_import_rule, 0, args ); }#endif# if defined( OS_NT ) || defined( OS_CYGWIN ) { char * args[] = { "key_path", ":", "data", "?", 0 }; bind_builtin( "W32_GETREG", builtin_system_registry, 0, args ); } { char * args[] = { "key_path", ":", "result-type", 0 }; bind_builtin( "W32_GETREGNAMES", builtin_system_registry_names, 0, args ); }# endif { char * args[] = { "command", ":", "*", 0 }; bind_builtin( "SHELL", builtin_shell, 0, args ); bind_builtin( "COMMAND", builtin_shell, 0, args ); } /* Initialize builtin modules */ init_set(); init_path(); init_regex(); init_property_set(); init_sequence(); init_order();}/** builtin_calc() - CALC rule** The CALC rule performs simple mathematical operations on two arguments.*/LIST *builtin_calc( PARSE *parse, FRAME *frame ){ LIST *arg = lol_get( frame->args, 0 ); LIST *result = 0; long lhs_value; long rhs_value; long result_value; char buffer [16]; const char* lhs; const char* op; const char* rhs; if (arg == 0) return L0; lhs = arg->string; arg = list_next( arg ); if (arg == 0) return L0; op = arg->string; arg = list_next( arg ); if (arg == 0) return L0; rhs = arg->string; lhs_value = atoi (lhs); rhs_value = atoi (rhs); if (strcmp ("+", op) == 0) { result_value = lhs_value + rhs_value; } else if (strcmp ("-", op) == 0) { result_value = lhs_value - rhs_value; } else { return L0; } sprintf (buffer, "%ld", result_value); result = list_new( result, newstr( buffer ) ); return result;}/* * builtin_depends() - DEPENDS/INCLUDES rule * * The DEPENDS builtin rule appends each of the listed sources on the * dependency list of each of the listed targets. It binds both the * targets and sources as TARGETs. */LIST *builtin_depends( PARSE *parse, FRAME *frame ){ LIST *targets = lol_get( frame->args, 0 ); LIST *sources = lol_get( frame->args, 1 ); LIST *l; for( l = targets; l; l = list_next( l ) ) { TARGET *t = bindtarget( l->string ); /* If doing INCLUDES, switch to the TARGET's include */ /* TARGET, creating it if needed. The internal include */ /* TARGET shares the name of its parent. */ if( parse->num ) { if( !t->includes ) { t->includes = copytarget( t ); t->includes->original_target = t; } t = t->includes; } t->depends = targetlist( t->depends, sources ); } /* Enter reverse links */ for( l = sources; l; l = list_next( l ) ) { TARGET *s = bindtarget( l->string ); s->dependents = targetlist( s->dependents, targets ); } return L0;}/* * builtin_rebuilds() - REBUILDS rule * * The REBUILDS builtin rule appends each of the listed * rebuild-targets in its 2nd argument on the rebuilds list of each of * the listed targets in its first argument. */LIST *builtin_rebuilds( PARSE *parse, FRAME *frame ){ LIST *targets = lol_get( frame->args, 0 ); LIST *rebuilds = lol_get( frame->args, 1 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -