From 3a5b1da9387dd4f1654c4322a16accf51af63e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Wed, 24 May 2000 19:18:35 -0700 Subject: [PATCH] module precompiler v0.1 added Rev: bin/precompile.pike:1.1 Rev: src/Makefile.in:1.193 Rev: src/builtin.cmod:1.1 Rev: src/builtin_functions.c:1.276 Rev: src/configure.in:1.376 Rev: src/error.c:1.51 Rev: src/error.h:1.42 Rev: src/fd_control.c:1.30 Rev: src/precompile.sh.in:1.1 --- bin/precompile.pike | 433 ++++++++++++++++++++++++++++++++++++++++ src/Makefile.in | 29 ++- src/builtin.cmod | 76 +++++++ src/builtin_functions.c | 69 +------ src/configure.in | 4 +- src/error.c | 15 +- src/error.h | 4 +- src/fd_control.c | 7 +- src/precompile.sh.in | 107 ++++++++++ 9 files changed, 671 insertions(+), 73 deletions(-) create mode 100644 bin/precompile.pike create mode 100644 src/builtin.cmod create mode 100644 src/precompile.sh.in diff --git a/bin/precompile.pike b/bin/precompile.pike new file mode 100644 index 0000000000..6a05a37fa3 --- /dev/null +++ b/bin/precompile.pike @@ -0,0 +1,433 @@ +#!/usr/local/bin/pike + +/* + * This script is used to process *.cmod files into *.c files, it + * reads Pike style prototypes and converts them into C code. + * + * The input can look something like this: + * + * PIKEFUNC int function_name (int x) + * attribute; + * attribute value; + * { + * C code using 'x'. + * + * RETURN x; + * } + * + * All the ADD_EFUN/ADD_FUNCTION calls will be inserted instead of the + * word INIT in your code. + * + * Currently, the following attributes are understood: + * efun; makes this function a global constant (no value) + * flags; ID_STATIC | ID_NOMASK etc. + * optflags; OPT_TRY_OPTIMIZE | OPT_SIDE_EFFECT etc. + * type; tInt, tMix etc. use this type instead of automatically + * generating type from the prototype + * + * + * BUGS/LIMITATIONS + * o Parenthesis must match, even within #if 0 + * o Not all Pike types are supported yet + */ + +#define PC Parser.C + +#ifdef OLD +import "."; +#define PC .C +#endif + +int parse_type(array x, int pos) +{ + while(1) + { + while(x[pos]=="!") pos++; + pos++; + if(arrayp(x[pos])) pos++; + switch(x[pos]) + { + default: + return pos; + + case "&": + case "|": + pos++; + } + } +} + +array(PC.Token) strip(array(PC.Token) t) +{ + array ret=({}); + foreach(t, mixed x) + { + if(objectp(x)) + { + switch(x->text[0]) + { + case ' ': + case '\t': + case '\n': + case '\r': + continue; + } + }else{ + x=strip(x); + } + ret+=({x}); + } + return ret; +} + +string merge(array x) +{ + string ret=""; + foreach(x,x) + ret+=arrayp(x)?merge(x):objectp(x)?x->text:x; + return ret; +} + +string cname(mixed type) +{ + mixed btype; + if(arrayp(type)) + btype=type[0]; + else + btype=type; + + switch(objectp(btype) ? btype->text : btype) + { + case "int": return "INT32"; + case "float": return "FLOAT_NUMBER"; + case "string": return "struct pike_string *"; + + case "array": + case "multiset": + case "mapping": + + case "object": + case "program": return "struct "+btype+" *"; + + case "function": + case "mixed": return "struct svalue *"; + + default: + werror("Unknown type %s\n",objectp(btype) ? btype->text : btype); + exit(1); + } +} + +string uname(mixed type) +{ + switch(objectp(type) ? type->text : type) + { + case "int": return "integer"; + case "float": + case "string": + + case "array": + case "multiset": + case "mapping": + + case "object": + case "program": return "struct "+type+" *"; + + case "function": + case "mixed": return "struct svalue *"; + + default: + werror("Unknown type %s\n",type); + exit(1); + } +} + +mapping(string:string) parse_arg(array x) +{ + mapping ret=(["name":x[-1]]); + ret->type=x[..sizeof(x)-2]; + ret->basetype=x[0]; + if(sizeof(ret->type/({"|"}))>1) + ret->basetype="mixed"; + ret->ctype=cname(ret->basetype); + return ret; +} + +/* FIXME: this is not finished yet */ +string convert_type(array s) +{ +// werror("%O\n",s); + switch(objectp(s[0])?s[0]->text:s[0]) + { + case "0": case "1": case "2": case "3": case "4": + case "5": case "6": case "7": case "8": case "9": + if(sizeof(s)>1 && s[1]=="=") + { + return sprintf("tSetvar(%s,%s)",s[0],convert_type(s[2..])); + }else{ + return sprintf("tVar(%s)",s[0]); + } + + case "int": return "tInt"; + case "float": return "tFlt"; + case "string": return "tStr"; + case "array": + if(sizeof(s)<2) return "tArray"; + return "tArr("+convert_type(s[1][1..sizeof(s[1])-2])+")"; + case "multiset": + if(sizeof(s)<2) return "tMultiset"; + return "tSet("+convert_type(s[1][1..sizeof(s[1])-2])+")"; + case "mapping": + if(sizeof(s)<2) return "tMapping"; + return "tMap("+ + convert_type((s[1]/({":"}))[0])+","+ + convert_type((s[1]/({":"}))[1])+")"; + case "object": + return "tObj"; + + case "program": + return "tProg"; + case "function": + return "tFunc"; + case "mixed": + return "tMix"; + } +} + +string make_pop(mixed howmany) +{ + switch(howmany) + { + default: + return "pop_n_elems("+howmany+");"; + + case "0": case 0: return ""; + case "1": case 1: return "pop_stack();"; + } +} + +array fix_return(array body, string rettype, string ctype, mixed args) +{ + int pos=0; + + while( (pos=search(body,PC.Token("RETURN",0),pos)) != -1) + { + int pos2=search(body,PC.Token(";",0),pos+1); + body[pos]=sprintf("do { %s ret_=(",ctype); + body[pos2]=sprintf("); %s push_%s(ret_); return; }while(0);",make_pop(args),rettype); + pos=pos2+1; + } + + pos=0; + while( (pos=search(body,PC.Token("REF_RETURN",0),pos)) != -1) + { + int pos2=search(body,PC.Token(";",0),pos+1); + body[pos]=sprintf("do { %s ret_=(",ctype); + body[pos2]=sprintf("); add_ref(ret_); %s push_%s(ret_); return; }while(0);",make_pop(args),rettype); + pos=pos2+1; + } + return body; +} + +array strip_type_assignments(array data) +{ + int pos; + + while( (pos=search(data,PC.Token("=",0))) != -1) + data=data[pos-2]+data[pos+1]; + return data; +} + +array recursive(mixed func, array data, mixed ... args) +{ + array ret=({}); + + data=func(data, @args); + + foreach(data, mixed foo) + { + if(arrayp(foo)) + { + ret+=({ recursive(func, foo, @args) }); + }else{ + ret+=({ foo }); + } + } + + return ret; +} + +int main(int argc, array(string) argv) +{ + mixed x; + string file=argv[1]; + x=Stdio.read_file(file); + x=PC.split(x); + x=PC.tokenize(x); + x=PC.group(x); + + x=x/({"PIKEFUN"}); + array ret=x[0]; + array addfuncs=({}); + + for(int f=1;f<sizeof(x);f++) + { + array func=x[f]; + int p; + for(p=0;p<sizeof(func);p++) + if(arrayp(func[p]) && func[p][0]=="{") + break; + + array proto=strip(func[..p-1]); + array body=func[p]; + array rest=func[p+1..]; + + p=parse_type(proto,0); + array rettype=proto[..p-1]; + string name=proto[p]->text; + array args=proto[p+1]; + + array attr=strip(proto[p+2..]); + + mapping attributes=([]); + foreach(attr/ ({";"}), attr) + { + switch(sizeof(attr)) + { + case 0: break; + case 1: + attributes[attr[0]->text]=1; + break; + default: + array tmp=attr[1..]; + if(sizeof(tmp) == 1 && arrayp(tmp[0]) && tmp[0][0]=="(") + tmp=tmp[0][1..sizeof(tmp[0])-2]; + + attributes[attr[0]->text]=merge(tmp); + } + } + +// werror("%O\n",attributes); + + + args=args[1..sizeof(args)-2]/({","}); + +// werror("FIX RETURN: %O\n",body); + body=recursive(fix_return,body, rettype[0], cname(rettype), sizeof(args)); + +// werror("name=%s\n",name); +// werror(" rettype=%O\n",rettype); +// werror(" args=%O\n",args); + + ret+=({ + sprintf("\n#line %d %O\n",rettype[0]->line,file), + sprintf("void f_%s(INT32 args)\n{\n",name), + }); + + args=map(args,parse_arg); + + foreach(args, mapping arg) + ret+=({ sprintf("%s%s;\n",arg->ctype, arg->name) }); + + + addfuncs+=({ + sprintf(" %s(%O,f_%s,tFunc(%s,%s),%s);\n", + attributes->efun ? "ADD_EFUN" : "ADD_FUNCTION", + name, + name, + attributes->type ? attributes->type : + Array.map(args->type,convert_type)*" ", + convert_type(rettype), + (attributes->efun ? attributes->optflags : + attributes->flags )|| "0" , + ) + }); + + int argnum; + + argnum=0; + ret+=({ + sprintf("if(args != %d) wrong_number_of_args_error(%O,args,%d);\n", + sizeof(args), + name, + sizeof(args)) + }); + + int sp=-sizeof(args); + foreach(args, mapping arg) + { + if(arg->basetype != "mixed") + { + ret+=({ + sprintf("if(sp[%d].type != PIKE_T_%s)\n", + sp,upper_case(arg->basetype->text)), + sprintf(" SIMPLE_BAD_ARG_ERROR(%O,%d,%O);\n", + name, + argnum+1, + merge(arg->type)), + }); + } + + switch(objectp(arg->basetype) ? arg->basetype->text : arg->basetype ) + { + case "int": + ret+=({ + sprintf("%s=sp[%d].integer;\n", + arg->name, + sp) + }); + break; + + case "float": + ret+=({ + sprintf("%s=sp[%d].float_number;\n", + arg->name, + sp) + }); + break; + + case "mixed": + ret+=({ + sprintf("%s=sp%+d;\n", + arg->name, + sp) + }); + break; + + default: + ret+=({ + sprintf("%s=sp[%d].u.%s;\n", + arg->name, + sp, + arg->basetype) + }); + + } + argnum++; + sp++; + } + + if(sizeof(body)) + { + ret+=({ + sprintf("#line %d %O\n",body[0]->line,file), + body, + }); + } + ret+=({ + "}\n" + }); + + if(sizeof(rest)) + { + ret+=({ + sprintf("#line %d %O\n",rest[0]->line,file), + })+ + recursive(replace,rest,PC.Token("INIT",0),addfuncs); + } + + } + + + write(merge(ret)); +} diff --git a/src/Makefile.in b/src/Makefile.in index 023a13b2fc..62ed0a8cd1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.192 2000/05/18 19:50:12 mast Exp $ +# $Id: Makefile.in,v 1.193 2000/05/25 02:18:35 hubbe Exp $ # # This line is needed on some machines. @@ -132,8 +132,14 @@ OBJ= \ threads.o \ version.o \ queue.o \ + builtin.o \ svalue.o @EXTRA_OBJS@ + +DEPEND= \ + $(SRCDIR)/language.c \ + $(SRCDIR)/builtin.c + # # The following objectfiles differ between tpike & pike: # @@ -253,7 +259,7 @@ hilfe: $(TMP_BINDIR)/hilfe Makefile @echo "Done." -.SUFFIXES: .c .o +.SUFFIXES: .c .o .cmod # Several optimizers have problems with interpret.c # First try compiling with optimization and if that doesn't work, without. @@ -269,6 +275,14 @@ hilfe: $(TMP_BINDIR)/hilfe Makefile NO_ULIMIT=yes $(CC) $(PREFLAGS) $(NOOPTFLAGS) -c $< -o $@ ;\ fi +# +# Please note that this must be accompanied by a dependency rule as +# The .c file will not be created in the SOURCE directory otherwise. +# -Hubbe +# +.cmod.c: + ./precompile.sh "$<" "$@" + force : @: @@ -472,7 +486,7 @@ stamp-tpike-predep: $(SRCDIR)/peep.in $(TMP_BINDIR)/mkpeep.pike peep.c $(SRCDIR) @echo foo > stamp-tpike-predep # make dependencies -depend: $(SRCDIR)/language.c +depend: $(DEPEND) gcc -MM -MG $(PREFLAGS) $(SRCDIR)/*.c | $(TMP_BINDIR)/fixdepends.sh $(SRCDIR) ( cd modules && $(MAKE) $(MAKE_FLAGS) depend ) ( cd post_modules && $(MAKE) $(MAKE_FLAGS) depend ) @@ -543,6 +557,12 @@ $(SRCDIR)/language.h: $(SRCDIR)/language.yacc $(SRCDIR)/language.c: $(SRCDIR)/language.h touch $(SRCDIR)/language.c + +# +# This rule makes sure that builtin.c is created in the source dir. +# +$(SRCDIR)/builtin.c: $(SRCDIR)/builtin.cmod ./precompile.sh $(TMP_BINDIR)/precompile.pike + # Internal testing target run_yacc: $(SRCDIR)/language.c @@ -572,6 +592,9 @@ Makefile: $(SRCDIR)/Makefile.in $(SRCDIR)/dependencies config.status @echo "Run make again" @exit 1 +precompile.sh: $(SRCDIR)/precompile.sh.in ./config.status + CONFIG_FILES=precompile.sh CONFIG_HEADERS="" ./config.status + $(SRCDIR)/machine.h.in: $(SRCDIR)/stamp-h.in @if test -f $(SRCDIR)/machine.h.in; then :; else \ rm $(SRCDIR)/stamp-h.in; $(MAKE) $(SRCDIR)/stamp-h.in; \ diff --git a/src/builtin.cmod b/src/builtin.cmod new file mode 100644 index 0000000000..0082d1ad23 --- /dev/null +++ b/src/builtin.cmod @@ -0,0 +1,76 @@ +#include "global.h" +#include "interpret.h" +#include "svalue.h" +#include "opcodes.h" +#include "pike_macros.h" +#include "object.h" +#include "program.h" +#include "array.h" +#include "error.h" +#include "constants.h" +#include "mapping.h" +#include "stralloc.h" +#include "multiset.h" +#include "pike_types.h" +#include "pike_memory.h" +#include "threads.h" +#include <math.h> +#include <ctype.h> +#include "module_support.h" +#include "cyclic.h" +#include "bignum.h" + + +PIKEFUN array column(array tmp, mixed val) + efun; + optflags OPT_TRY_OPTIMIZE; +{ + INT32 e; + struct array *a; + + DECLARE_CYCLIC(); + + /* Optimization */ + if(tmp->refs == 1) + { + /* An array with one ref cannot possibly be cyclic */ + struct svalue sval; + tmp->type_field = BIT_MIXED | BIT_UNFINISHED; + for(e=0;e<tmp->size;e++) + { + index_no_free(&sval, ITEM(tmp)+e, val); + free_svalue(ITEM(tmp)+e); + ITEM(tmp)[e]=sval; + } + pop_stack(); + return; + } + + if((a=(struct array *)BEGIN_CYCLIC(tmp,0))) + { + add_ref(a); + }else{ + push_array(a=allocate_array(tmp->size)); + SET_CYCLIC_RET(a); + + for(e=0;e<a->size;e++) + index_no_free(ITEM(a)+e, ITEM(tmp)+e, val); + + sp--; + } + END_CYCLIC(); + RETURN a; +} + +PIKEFUN multiset(1) mkmultiset(array(1=mixed) a) + efun; + optflags OPT_TRY_OPTIMIZE; +{ + RETURN mkmultiset(a); +} + + +void init_builtin(void) +{ + INIT; +} diff --git a/src/builtin_functions.c b/src/builtin_functions.c index d21d1dae5d..11cbe15543 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.275 2000/05/17 18:27:50 grubba Exp $"); +RCSID("$Id: builtin_functions.c,v 1.276 2000/05/25 02:18:35 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -2382,17 +2382,6 @@ void f_mkmapping(INT32 args) push_mapping(m); } -void f_mkmultiset(INT32 args) -{ - struct multiset *m; - struct array *a; - get_all_args("mkmultiset",args,"%a",&a); - - m=mkmultiset(sp[-args].u.array); - pop_n_elems(args); - push_multiset(m); -} - #define SETFLAG(FLAGS,FLAG,ONOFF) \ FLAGS = (FLAGS & ~FLAG) | ( ONOFF ? FLAG : 0 ) void f_set_weak_flag(INT32 args) @@ -2710,50 +2699,6 @@ void f_rows(INT32 args) push_array(a); } -void f_column(INT32 args) -{ - INT32 e; - struct array *a,*tmp; - struct svalue *val; - - DECLARE_CYCLIC(); - - get_all_args("column", args, "%a%*", &tmp, &val); - - /* Optimization */ - if(tmp->refs == 1) - { - /* An array with one ref cannot possibly be cyclic */ - struct svalue sval; - tmp->type_field = BIT_MIXED | BIT_UNFINISHED; - for(e=0;e<tmp->size;e++) - { - index_no_free(&sval, ITEM(tmp)+e, val); - free_svalue(ITEM(tmp)+e); - ITEM(tmp)[e]=sval; - } - pop_stack(); - return; - } - - if((a=(struct array *)BEGIN_CYCLIC(tmp,0))) - { - pop_n_elems(args); - ref_push_array(a); - }else{ - push_array(a=allocate_array(tmp->size)); - SET_CYCLIC_RET(a); - - for(e=0;e<a->size;e++) - index_no_free(ITEM(a)+e, ITEM(tmp)+e, val); - - sp--; - dmalloc_touch_svalue(sp); - pop_n_elems(args); - push_array(a); - } - END_CYCLIC(); -} #ifdef PIKE_DEBUG void f__verify_internals(INT32 args) @@ -5711,6 +5656,10 @@ void init_builtin_efuns(void) { struct program *pike___master_program; + extern init_builtin(void); + + init_builtin(); + ADD_EFUN("gethrtime", f_gethrtime, tFunc(tOr(tInt,tVoid),tInt), OPT_EXTERNAL_DEPEND); @@ -5813,9 +5762,6 @@ void init_builtin_efuns(void) tFunc(tNone,tArr(tArray)),OPT_EXTERNAL_DEPEND); -/* function(array,mixed:array) */ - ADD_EFUN("column",f_column,tFunc(tArray tMix,tArray),0); - /* function(string...:string) */ ADD_EFUN("combine_path",f_combine_path,tFuncV(tNone,tStr,tStr),0); @@ -5901,10 +5847,7 @@ void init_builtin_efuns(void) tFunc(tArr(tSetvar(1,tMix)) tArr(tSetvar(2,tMix)), tMap(tVar(1),tVar(2))),OPT_TRY_OPTIMIZE); - ADD_EFUN("mkmultiset",f_mkmultiset, - tFunc(tArr(tSetvar(1,tMix)), tSet(tVar(1))), - OPT_TRY_OPTIMIZE); - + /* function(1=mixed,int:1) */ ADD_EFUN("set_weak_flag",f_set_weak_flag, tFunc(tSetvar(1,tMix) tInt,tVar(1)),OPT_SIDE_EFFECT); diff --git a/src/configure.in b/src/configure.in index db7939f43b..82b532170a 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.375 2000/05/20 13:40:05 grubba Exp $") +AC_REVISION("$Id: configure.in,v 1.376 2000/05/25 02:18:35 hubbe Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -3638,6 +3638,6 @@ fi AC_SUBST(dmmsrc) -AC_OUTPUT(Makefile modules/static_module_makefile post_modules/static_module_makefile:modules/static_module_makefile.in modules/dynamic_module_makefile:$dmmsrc post_modules/dynamic_module_makefile:$dmmsrc,[echo foo >stamp-h]) +AC_OUTPUT(Makefile modules/static_module_makefile post_modules/static_module_makefile:modules/static_module_makefile.in modules/dynamic_module_makefile:$dmmsrc post_modules/dynamic_module_makefile:$dmmsrc precompile.sh,[echo foo >stamp-h ; chmod +x precompile.sh]) diff --git a/src/error.c b/src/error.c index 914f8635d8..bb0aa28d70 100644 --- a/src/error.c +++ b/src/error.c @@ -20,7 +20,7 @@ #include "threads.h" #include "gc.h" -RCSID("$Id: error.c,v 1.50 2000/04/19 21:26:19 mast Exp $"); +RCSID("$Id: error.c,v 1.51 2000/05/25 02:18:35 hubbe Exp $"); #undef ATTRIBUTE #define ATTRIBUTE(X) @@ -552,6 +552,19 @@ void permission_error( ERROR_DONE(generic); } +void wrong_number_of_args_error(char *name, int args, int expected) +{ + char *msg; + if(expected>args) + { + msg="Too few arguments"; + }else{ + msg="Too many arguments"; + } + + new_error(name, msg, sp-args, args, 0,0); +} + #ifdef PIKE_DEBUG static void gc_check_throw_value(struct callback *foo, void *bar, void *gazonk) { diff --git a/src/error.h b/src/error.h index 2aa412db11..9639d5e7d7 100644 --- a/src/error.h +++ b/src/error.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: error.h,v 1.41 2000/04/20 02:41:44 hubbe Exp $ + * $Id: error.h,v 1.42 2000/05/25 02:18:35 hubbe Exp $ */ #ifndef ERROR_H #define ERROR_H @@ -170,6 +170,7 @@ extern int throw_severity; /* Prototypes begin here */ void check_recovery_context(void); +void pike_gdb_breakpoint(void); JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS); void pike_throw(void) ATTRIBUTE((noreturn)); void push_error(char *description); @@ -224,6 +225,7 @@ void permission_error( struct svalue *base_sp, int args, char *permission_type, char *desc, ...) ATTRIBUTE((noreturn, format(printf, 5, 6))); +void wrong_number_of_args_error(char *name, int args, int expected); void init_error(void); void cleanup_error(void); /* Prototypes end here */ diff --git a/src/fd_control.c b/src/fd_control.c index dc76a178a2..07aaaba95a 100644 --- a/src/fd_control.c +++ b/src/fd_control.c @@ -10,7 +10,7 @@ #include "error.h" #include "fdlib.h" -RCSID("$Id: fd_control.c,v 1.29 2000/05/20 18:58:53 grubba Exp $"); +RCSID("$Id: fd_control.c,v 1.30 2000/05/25 02:18:35 hubbe Exp $"); #else /* TESTING */ @@ -141,11 +141,12 @@ int query_nonblocking(int fd) #ifdef HAVE_BROKEN_F_SETFD static int *fds_to_close; static int fds_to_close_size = 0; +static int num_fds_to_close=0; #define ASSURE_FDS_TO_CLOSE_SIZE(X) \ do{while(fds_to_close_size-1 < X) grow_fds_to_close();}while(0) -static void grow_fds_to_close( ) +static void grow_fds_to_close(void) { if(!fds_to_close_size) fds_to_close_size = 1; @@ -154,7 +155,7 @@ static void grow_fds_to_close( ) if(!fds_to_close) fatal("Out of memory in fd_control::grow_fds_to_close()\n" "Tried to allocate %d fd_datum structs\n", fds_to_close_size); - MEMSET( fds+(fds_to_close_size/2), 0, fds_to_close_size*sizeof(int)/2 ); + MEMSET( fds_to_close+(fds_to_close_size/2), 0, fds_to_close_size*sizeof(int)/2 ); } void do_close_on_exec(void) diff --git a/src/precompile.sh.in b/src/precompile.sh.in new file mode 100644 index 0000000000..177d538c8b --- /dev/null +++ b/src/precompile.sh.in @@ -0,0 +1,107 @@ +#!/bin/sh + +#set -x + +TMP_BUILDDIR="@BUILDDIR@" +TMP_BINDIR="@BINDIR@" +LIBDIR_SRC="@LIBDIR@" + +if test -f "$TMP_BUILDDIR/precompile-method" ; then + . "$TMP_BUILDDIR/precompile-method" +else + : +fi + +old_method="${method-}" + +retries=. +while test "$retries" != .......... ; do + +RUNPIKE= +case $method in + Q) + RUNPIKE="$TMP_BUILDDIR/pike -DNOT_INSTALLED -m$TMP_BUILDDIR/master.pike $PIKEOPTS" + ;; + QQ) + RUNPIKE="$TMP_BUILDDIR/tpike -DNOT_INSTALLED -m$TMP_BUILDDIR/master.pike $PIKEOPTS" + ;; + QQQ) + RUNPIKE=$TMP_BUILDDIR/test-pike + ;; + QQQQ) + LAST_PIKE=pike + method=QQQQQ + RUNPIKE="$LAST_PIKE -DOLD" + ;; + QQQQQ) + RUNPIKE="$LAST_PIKE -DOLD" + ;; + QQQQQQ) + ifs_save="${IFS- }" + IFS=" :" + for dir in $PATH + do + for p in pike pike7 pike07 pike06 + do + if [ -x $dir/$p ]; then + if [ "x$LAST_PIKE" = xpike ] ; then + LAST_PIKE=$dir/$p + RUNPIKE="$dir/$p -DOLD" + break + fi + + if [ "x$LAST_PIKE" = "x$dir/$p" ]; then + LAST_PIKE=pike + fi + fi + done + if [ "x$RUNPIKE" != x ]; then + method=QQQQQ + break + fi + done + IFS="${ifs_save}" + ;; + QQQQQQQ) + method= + ;; +esac + +# +# By linking these two files to the current directory I can make +# precompile.pike work with older versions of Pike - Hubbe +# + +if test -f ./precompile.pike ; then + : +else + ln -s "$TMP_BINDIR/precompile.pike" ./precompile.pike +fi + +if test -f ./C.pmod ; then + : +else + ln -s "$LIBDIR_SRC/modules/Parser.pmod/C.pmod" ./C.pmod +fi + + + +if test "x${RUNPIKE-}" != x ; then +echo "precompile: $RUNPIKE ./precompile.pike $1 >$2 (method=$method)" +if $RUNPIKE ./precompile.pike "$1" >"$2" ; then + +cat > "$TMP_BUILDDIR/precompile-method" <<EOF +LAST_PIKE=$LAST_PIKE +method=$method +EOF + +exit 0 +fi +fi + +method=Q$method +retries=.$retries + +done # retry +# Total failure +rm "$2" \ No newline at end of file -- GitLab