Merge pull request #18 from kernigh/pr-util-ack

util/ack: use DEFAULT_PLATFORM, allow non-ASCII filenames, other changes
This commit is contained in:
David Given 2016-11-30 22:00:55 +01:00 committed by GitHub
commit d94c326465
18 changed files with 429 additions and 372 deletions

View file

@ -88,6 +88,7 @@ $(BUILDDIR)/build.$(BUILDSYSTEM): first/ackbuilder.lua Makefile $(BUILD_FILES) $
@$(LUA) first/ackbuilder.lua \ @$(LUA) first/ackbuilder.lua \
first/build.lua build.lua \ first/build.lua build.lua \
--$(BUILDSYSTEM) \ --$(BUILDSYSTEM) \
DEFAULT_PLATFORM=$(DEFAULT_PLATFORM) \
OBJDIR=$(OBJDIR) \ OBJDIR=$(OBJDIR) \
BINDIR=$(BINDIR) \ BINDIR=$(BINDIR) \
LIBDIR=$(LIBDIR) \ LIBDIR=$(LIBDIR) \

View file

@ -100,7 +100,7 @@ Note: \fIack\fP refuses to overwrite argument \fI.e\fP files.
.IP \-t .IP \-t
Preserve all intermediate files. Preserve all intermediate files.
If two \fB\-t\fP are used, If two \fB\-t\fP are used,
\fIack\fP also preserves core dumps and output of failed transformations. \fIack\fP also preserves output of failed transformations.
.IP \-w .IP \-w
Suppress all warning messages. Suppress all warning messages.

View file

@ -6,6 +6,8 @@
#define RCS_ACK "$Id$" #define RCS_ACK "$Id$"
#endif #endif
#include <stdlib.h> /* size_t, free() */
/****************************************************************************/ /****************************************************************************/
/* User settable options */ /* User settable options */
/****************************************************************************/ /****************************************************************************/
@ -61,20 +63,29 @@ typedef struct {
#define p_cont(elem) ((path *)l_content(elem)) #define p_cont(elem) ((path *)l_content(elem))
/* Return values of setpath() */
enum f_path { F_OK, F_NOMATCH, F_NOPATH } ;
/* Own routines */ /* Own routines */
enum f_path getpath();
enum f_path scan_end(); /* rmach.c */
extern void noodstop(); void setlist(char *);
extern char *getvar();
extern char *keeps(); /* svars.c */
extern char *basename(); void setsvar(char *, char *);
extern char *skipblank(); void setpvar(char *, char *(*)(void));
extern char *firstblank(); char *getvar(const char *);
extern char *getcore();
extern char *changecore(); /* util.c */
char *ack_basename(const char *);
char *skipblank(char *);
char *firstblank(char *);
void fatal(const char *, ...);
void vprint(const char *, ...);
void fuerror(const char *, ...);
void werror(const char *, ...);
void quit(int);
char *keeps(const char *);
#define throws(str) free(str)
void *getcore(size_t);
void *changecore(void *, size_t);
#define freecore(area) free(area) #define freecore(area) free(area)
#define DEBUG 1 /* Allow debugging of Ack */ #define DEBUG 1 /* Allow debugging of Ack */

View file

@ -18,12 +18,28 @@ normalrule {
cprogram { cprogram {
name = "ack", name = "ack",
srcs = { srcs = {
"./*.c", "./data.c",
"./files.c",
"./grows.c",
"./list.c",
"./main.c",
"./rmach.c",
"./run.c",
"./scan.c",
"./svars.c",
"./trans.c",
"./util.c",
"+tables", "+tables",
}, },
deps = { deps = {
"h+emheaders", "h+emheaders",
"h+local", "h+local",
"./ack.h",
"./data.h",
"./dmach.h",
"./grows.h",
"./list.h",
"./trans.h",
} }
} }

View file

@ -48,4 +48,4 @@ EXTERN path in; /* The current single input pathname */
EXTERN path out; /* The current output pathname */ EXTERN path out; /* The current output pathname */
EXTERN path orig; /* The original input path */ EXTERN path orig; /* The original input path */
EXTERN char *p_basename; /* The current basename */ EXTERN char *p_basename; /* The current basename */
EXTERN char *p_suffix; /* The current input suffix */ EXTERN const char *p_suffix; /* The current input suffix */

View file

@ -16,7 +16,7 @@
static char rcs_id[] = "$Id$" ; static char rcs_id[] = "$Id$" ;
#endif #endif
char *add_u(part,ptr) char *ptr ; { static char *add_u(int part, char *ptr) {
if ( part>=26 ) { if ( part>=26 ) {
ptr=add_u(part/26-1,ptr) ; ptr=add_u(part/26-1,ptr) ;
} }
@ -24,7 +24,7 @@ char *add_u(part,ptr) char *ptr ; {
return ptr+1 ; return ptr+1 ;
} }
char *unique() { static char *unique(void) {
/* Get the next unique part of the internal filename */ /* Get the next unique part of the internal filename */
static int u_next = 0 ; static int u_next = 0 ;
static char buf[10] ; static char buf[10] ;
@ -36,7 +36,7 @@ char *unique() {
return buf ; return buf ;
} }
setfiles(phase) register trf *phase ; { int setfiles(trf *phase) {
/* Set the out structure according to the in structure, /* Set the out structure according to the in structure,
the transformation and some global data */ the transformation and some global data */
growstring pathname ; growstring pathname ;
@ -94,18 +94,7 @@ setfiles(phase) register trf *phase ; {
return 1 ; return 1 ;
} }
disc_files(phase) trf *phase ; { static void file_final(path *file) {
path temp ;
if ( !phase->t_combine ) {
file_final(&in) ;
} else {
disc_inputs(phase) ;
}
temp=in ; in=out ; out=temp ;
}
file_final(file) path *file ; {
if ( file->p_path ) { if ( file->p_path ) {
if ( !file->p_keep && t_flag<=1 ) { if ( !file->p_keep && t_flag<=1 ) {
if ( unlink(file->p_path)!=0 ) { if ( unlink(file->p_path)!=0 ) {
@ -119,7 +108,18 @@ file_final(file) path *file ; {
file->p_keep=NO ; file->p_keep=NO ;
} }
disc_inputs(phase) trf *phase ; { void disc_files(trf *phase) {
path temp ;
if ( !phase->t_combine ) {
file_final(&in) ;
} else {
disc_inputs(phase) ;
}
temp=in ; in=out ; out=temp ;
}
void disc_inputs(trf *phase) {
/* Remove all the input files of this phase */ /* Remove all the input files of this phase */
/* Only for combiners */ /* Only for combiners */
register path *l_in ; register path *l_in ;
@ -132,7 +132,7 @@ disc_inputs(phase) trf *phase ; {
l_clear(&phase->t_inputs) ; l_clear(&phase->t_inputs) ;
} }
rmfile(file) path *file ; { void rmfile(path *file) {
/* Remove a file, do not complain when is does not exist */ /* Remove a file, do not complain when is does not exist */
if ( file->p_path ) { if ( file->p_path ) {
if ( t_flag<=1 ) unlink(file->p_path) ; if ( t_flag<=1 ) unlink(file->p_path) ;
@ -143,8 +143,7 @@ rmfile(file) path *file ; {
} }
} }
void void rmtemps(void) {
rmtemps() {
/* Called in case of disaster, always remove the current output file! /* Called in case of disaster, always remove the current output file!
*/ */
register list_elem *elem ; register list_elem *elem ;
@ -159,7 +158,7 @@ rmtemps() {
} }
} }
add_input(file,phase) path *file ; trf *phase ; { void add_input(path *file, trf *phase) {
register path *store ; register path *store ;
#ifdef DEBUG #ifdef DEBUG
if ( debug ) { if ( debug ) {

View file

@ -19,7 +19,7 @@ static char rcs_id[] = "$Id$" ;
static char rcs_grows[] = RCS_GROWS ; static char rcs_grows[] = RCS_GROWS ;
#endif #endif
gr_add(id,c) register growstring *id ; char c ; { int gr_add(growstring *id, int c) {
if ( id->gr_size==id->gr_max) { if ( id->gr_size==id->gr_max) {
if ( id->gr_size==0 ) { /* The first time */ if ( id->gr_size==0 ) { /* The first time */
id->gr_max= 2*GR_MORE ; id->gr_max= 2*GR_MORE ;
@ -32,8 +32,8 @@ gr_add(id,c) register growstring *id ; char c ; {
*(id->gr_string+id->gr_size++)= c ; *(id->gr_string+id->gr_size++)= c ;
} }
gr_cat(id,string) growstring *id ; char *string ; { int gr_cat(growstring *id, const char *string) {
register char *ptr ; const char *ptr ;
#ifdef DEBUG #ifdef DEBUG
if ( id->gr_size && *(id->gr_string+id->gr_size-1) ) { if ( id->gr_size && *(id->gr_string+id->gr_size-1) ) {
@ -50,8 +50,7 @@ gr_cat(id,string) growstring *id ; char *string ; {
} }
} }
void void gr_throw(growstring *id) {
gr_throw(id) register growstring *id ; {
/* Throw the string away */ /* Throw the string away */
if ( id->gr_max==0 ) return ; if ( id->gr_max==0 ) return ;
freecore(id->gr_string) ; freecore(id->gr_string) ;
@ -60,11 +59,11 @@ gr_throw(id) register growstring *id ; {
id->gr_size=0 ; id->gr_size=0 ;
} }
gr_init(id) growstring *id ; { void gr_init(growstring *id) {
id->gr_size=0 ; id->gr_max=0 ; id->gr_size=0 ; id->gr_max=0 ;
} }
char *gr_final(id) growstring *id ; { char *gr_final(growstring *id) {
/* Throw away the bookkeeping, adjust the string to its final /* Throw away the bookkeeping, adjust the string to its final
length and return a pointer to a string to be get rid of with length and return a pointer to a string to be get rid of with
throws throws

View file

@ -20,8 +20,8 @@ typedef struct {
/* Routines used */ /* Routines used */
extern void gr_throw() ; /* To free the core */ void gr_throw(growstring *) ; /* To free the core */
extern int gr_add() ; /* To add one character */ int gr_add(growstring *, int) ; /* To add one character */
extern int gr_cat() ; /* concatenate the contents and the string */ int gr_cat(growstring *, const char *) ; /* To append a string */
extern int gr_init() ; /* Initialize the bookkeeping */ void gr_init(growstring *) ; /* Initialize the bookkeeping */
extern char *gr_final() ; /* Transform to a stable storage string */ char *gr_final(growstring *) ; /* Move to a stable storage string */

View file

@ -33,7 +33,7 @@ Routines:
*/ */
l_add(header,string) list_head *header ; char *string ; { void l_add(list_head *header, char *string) {
register list_elem *new; register list_elem *new;
/* NOSTRICT */ /* NOSTRICT */
@ -49,7 +49,7 @@ l_add(header,string) list_head *header ; char *string ; {
header->ca_last= new ; header->ca_last= new ;
} }
l_clear(header) list_head *header ; { void l_clear(list_head *header) {
register list_elem *old, *next; register list_elem *old, *next;
for ( old=header->ca_first ; old ; old= next ) { for ( old=header->ca_first ; old ; old= next ) {
next= old->ca_next ; next= old->ca_next ;
@ -59,7 +59,7 @@ l_clear(header) list_head *header ; {
header->ca_last = (list_elem *) 0 ; header->ca_last = (list_elem *) 0 ;
} }
l_throw(header) list_head *header ; { void l_throw(list_head *header) {
register list_elem *old, *next; register list_elem *old, *next;
for ( old=header->ca_first ; old ; old= next ) { for ( old=header->ca_first ; old ; old= next ) {
throws(l_content(*old)) ; throws(l_content(*old)) ;

View file

@ -29,3 +29,7 @@ typedef struct ca_elem list_elem ; /* The decl. for elements */
/* To be used for scanning lists, ptr is the running variable */ /* To be used for scanning lists, ptr is the running variable */
#define scanlist(elem,ptr) \ #define scanlist(elem,ptr) \
for ( ptr= elem ; ptr; ptr= l_next(*ptr) ) for ( ptr= elem ; ptr; ptr= l_next(*ptr) )
void l_add(list_head *, char *);
void l_clear(list_head *);
void l_throw(list_head *);

View file

@ -22,11 +22,20 @@ static char rcs_ack[] = RCS_ACK ;
static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ; static int sigs[] = { SIGINT, SIGHUP, SIGTERM, 0 } ;
static int arg_count; static int arg_count;
extern char *getenv(); static char *srcvar(void);
static char *getsuffix(void);
static void varinit(void);
static void vieuwargs(int, char **);
static void firstarg(char *);
static int process(char *);
static int startrf(trf *);
static void block(trf *);
static int mayprep(void);
static void scanneeds(void);
static void setneeds(const char *, int);
static void noodstop(int);
void vieuwargs(); int main(int argc, char **argv) {
main(argc,argv) char **argv ; {
register list_elem *elem ; register list_elem *elem ;
register char *frontend ; register char *frontend ;
register int *n_sig ; register int *n_sig ;
@ -102,7 +111,7 @@ main(argc,argv) char **argv ; {
orig.p_path=phase->t_origname ; orig.p_path=phase->t_origname ;
if ( p_basename ) throws(p_basename) ; if ( p_basename ) throws(p_basename) ;
if ( orig.p_path ) { if ( orig.p_path ) {
p_basename= keeps(basename(orig.p_path)) ; p_basename= keeps(ack_basename(orig.p_path)) ;
} else { } else {
p_basename=0 ; p_basename=0 ;
} }
@ -115,15 +124,15 @@ main(argc,argv) char **argv ; {
exit(0) ; exit(0) ;
} }
char *srcvar() { static char *srcvar(void) {
return orig.p_path ; return orig.p_path ;
} }
char *getsuffix() { static char *getsuffix(void) {
return strrchr(orig.p_path, SUFCHAR) ; return strrchr(orig.p_path, SUFCHAR) ;
} }
varinit() { static void varinit(void) {
/* initialize the string variables */ /* initialize the string variables */
register char *envstr ; register char *envstr ;
extern char *em_dir; extern char *em_dir;
@ -138,8 +147,7 @@ varinit() {
/************************* flag processing ***********************/ /************************* flag processing ***********************/
void void vieuwargs(int argc, char **argv) {
vieuwargs(argc,argv) char **argv ; {
register char *argp; register char *argp;
register int nextarg ; register int nextarg ;
register int eaten ; register int eaten ;
@ -206,14 +214,16 @@ vieuwargs(argc,argv) char **argv ; {
case 'r': if ( argp[2]!=SUFCHAR ) { case 'r': if ( argp[2]!=SUFCHAR ) {
error("-r must be followed by %c",SUFCHAR) ; error("-r must be followed by %c",SUFCHAR) ;
} }
keeptail(&argp[2]); eaten=1 ; l_add(&tail_list, &argp[2]) ;
eaten=1 ;
break ; break ;
case '.': if ( rts ) { case '.': if ( rts ) {
if ( strcmp(rts,&argp[1])!=0 ) if ( strcmp(rts,&argp[1])!=0 )
fuerror("Two run-time systems?") ; fuerror("Two run-time systems?") ;
} else { } else {
rts= &argp[1] ; rts= &argp[1] ;
keephead(rts) ; keeptail(rts) ; l_add(&head_list, rts) ;
l_add(&tail_list, rts) ;
} }
eaten=1 ; eaten=1 ;
break ; break ;
@ -238,7 +248,7 @@ vieuwargs(argc,argv) char **argv ; {
register char *tokeep ; register char *tokeep ;
tokeep=keeps(argp) ; tokeep=keeps(argp) ;
if ( argp[1]=='R' ) { if ( argp[1]=='R' ) {
do_Rflag(tokeep); l_add(&R_list, tokeep) ;
} else { } else {
*tokeep |= NO_SCAN ; *tokeep |= NO_SCAN ;
} }
@ -251,7 +261,7 @@ vieuwargs(argc,argv) char **argv ; {
return ; return ;
} }
firstarg(argp) register char *argp ; { static void firstarg(char *argp) {
register char *name ; register char *name ;
name=strrchr(argp,'/') ; name=strrchr(argp,'/') ;
@ -265,7 +275,7 @@ firstarg(argp) register char *argp ; {
/************************* argument processing ***********************/ /************************* argument processing ***********************/
process(arg) char *arg ; { static int process(char *arg) {
/* Process files & library arguments */ /* Process files & library arguments */
trf *phase ; trf *phase ;
register trf *tmp ; register trf *tmp ;
@ -282,7 +292,7 @@ process(arg) char *arg ; {
return 1 ; return 1 ;
} }
if ( p_basename ) throws(p_basename) ; if ( p_basename ) throws(p_basename) ;
p_basename= keeps(basename(arg)) ; p_basename= keeps(ack_basename(arg)) ;
/* Try to find a path through the transformations */ /* Try to find a path through the transformations */
switch( getpath(&phase) ) { switch( getpath(&phase) ) {
case F_NOPATH : case F_NOPATH :
@ -325,7 +335,7 @@ process(arg) char *arg ; {
return startrf(phase) ; return startrf(phase) ;
} }
int startrf(first) trf *first ; { static int startrf(trf *first) {
/* Start the transformations at the indicated phase */ /* Start the transformations at the indicated phase */
register trf *phase ; register trf *phase ;
@ -397,7 +407,7 @@ if ( debug ) vprint("Transformation sequence complete for %s\n",
return 1 ; return 1 ;
} }
block(first) trf *first ; { static void block(trf *first) {
/* One of the input files of this phase could not be produced, /* One of the input files of this phase could not be produced,
block all combiners taking their input from this one. block all combiners taking their input from this one.
*/ */
@ -406,7 +416,8 @@ block(first) trf *first ; {
if ( phase->t_combine ) phase->t_blocked=YES ; if ( phase->t_combine ) phase->t_blocked=YES ;
} }
} }
mayprep() {
static int mayprep(void) {
int file ; int file ;
char fc ; char fc ;
file=open(in.p_path,0); file=open(in.p_path,0);
@ -416,15 +427,7 @@ mayprep() {
return fc=='#' ; return fc=='#' ;
} }
keephead(suffix) char *suffix ; { static void scanneeds(void) {
l_add(&head_list, suffix) ;
}
keeptail(suffix) char *suffix ; {
l_add(&tail_list, suffix) ;
}
scanneeds() {
register list_elem *elem ; register list_elem *elem ;
scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; } scanlist(l_first(head_list), elem) { setneeds(l_content(*elem),0) ; }
l_clear(&head_list) ; l_clear(&head_list) ;
@ -432,7 +435,7 @@ scanneeds() {
l_clear(&tail_list) ; l_clear(&tail_list) ;
} }
setneeds(suffix,tail) char *suffix ; { static void setneeds(const char *suffix, int tail) {
trf *phase ; trf *phase ;
p_suffix= suffix ; p_suffix= suffix ;
@ -456,3 +459,7 @@ setneeds(suffix,tail) char *suffix ; {
break ; break ;
} }
} }
static void noodstop(int sig) {
quit(-3) ;
}

View file

@ -47,19 +47,17 @@ static char rcs_dmach[] = RCS_DMACH ;
#define CALL "callname" #define CALL "callname"
#define END "end" #define END "end"
extern growstring scanb(); static void intrf(void) ;
extern growstring scanvars(); static void open_in(char *) ;
static void close_in(void) ;
static int getinchar(void) ;
static int getln(void) ;
int getln() ;
int getinchar() ;
static char *ty_name ; static char *ty_name ;
static char *bol ; static char *bol ;
void open_in();
static char *inname ; static char *inname ;
setlist(name) char *name ; { void setlist(char *name) {
/* Name is sought in the internal tables, /* Name is sought in the internal tables,
if not present, the a file of that name is sought if not present, the a file of that name is sought
in first the current and then the EM Lib directory in first the current and then the EM Lib directory
@ -92,9 +90,7 @@ setlist(name) char *name ; {
#endif #endif
} }
static int inoptlist(nm) static int inoptlist(char *nm) {
char *nm ;
{
register char *p=Optlist ; register char *p=Optlist ;
while ( p && *p ) { while ( p && *p ) {
@ -107,9 +103,9 @@ static int inoptlist(nm)
return 0; return 0;
} }
intrf() { static void intrf(void) {
/* Read in trf (transformation) */
register trf *new ; register trf *new ;
growstring bline ;
int twice ; int twice ;
int name_seen=0 ; int name_seen=0 ;
@ -130,20 +126,14 @@ intrf() {
} else } else
if ( strcmp(ty_name,PROG)==0 ) { if ( strcmp(ty_name,PROG)==0 ) {
if ( new->t_prog ) twice=YES ; if ( new->t_prog ) twice=YES ;
bline= scanb(bol); /* Scan for \ */ new->t_prog= keeps(bol);
new->t_prog= gr_final(&bline);
} else } else
if ( strcmp(ty_name,MAPF)==0 ) { if ( strcmp(ty_name,MAPF)==0 ) {
/* First read the mapflags line l_add(&new->t_mapf,keeps(bol)) ;
and scan for backslashes */
bline= scanb(bol) ;
l_add(&new->t_mapf,gr_final(&bline)) ;
} else } else
if ( strcmp(ty_name,ARGS)==0 ) { if ( strcmp(ty_name,ARGS)==0 ) {
if ( new->t_argd ) twice=YES ; if ( new->t_argd ) twice=YES ;
bline= scanb(bol) ; new->t_argd= keeps(bol) ;
new->t_argd= keeps(gr_start(bline)) ;
gr_throw(&bline) ;
} else } else
if ( strcmp(ty_name,STD_IN)==0 ) { if ( strcmp(ty_name,STD_IN)==0 ) {
if ( new->t_stdin ) twice=YES ; if ( new->t_stdin ) twice=YES ;
@ -234,14 +224,15 @@ intrf() {
rts, new->t_rts) ; rts, new->t_rts) ;
} }
rts= new->t_rts ; rts= new->t_rts ;
keephead(rts) ; keeptail(rts) ; l_add(&head_list, rts) ;
l_add(&tail_list, rts) ;
} }
#ifdef DEBUG #ifdef DEBUG
if ( debug>=3 ) { if ( debug>=3 ) {
register list_elem *elem ; register list_elem *elem ;
vprint("%s: from %s to %s '%s'\n", vprint("%s: from %s to %s '%s'\n",
new->t_name,new->t_in ? new->t_in : "(null)",new->t_out,new->t_prog) ; new->t_name,new->t_in ? new->t_in : "(null)",new->t_out,new->t_prog) ;
vprint("\targs: ") ; prns(new->t_argd) ; vprint("\targs: %s",new->t_argd) ;
scanlist( l_first(new->t_mapf), elem ) { scanlist( l_first(new->t_mapf), elem ) {
vprint("\t%s\n",l_content(*elem)) ; vprint("\t%s\n",l_content(*elem)) ;
} }
@ -264,8 +255,7 @@ static FILE *infile ;
static char *inptr ; static char *inptr ;
char *em_dir = EM_DIR; char *em_dir = EM_DIR;
void static void open_in(char *name) {
open_in(name) register char *name ; {
register dmach *cmac ; register dmach *cmac ;
gr_init(&rline) ; gr_init(&rline) ;
@ -298,12 +288,12 @@ open_in(name) register char *name ; {
} }
} }
close_in() { static void close_in(void) {
if ( !incore ) fclose(infile) ; if ( !incore ) fclose(infile) ;
gr_throw(&rline) ; gr_throw(&rline) ;
} }
char *readline() { static char *readline(void) {
/* Get a line from the input, /* Get a line from the input,
return 0 if at end, return 0 if at end,
The line is stored in a volatile buffer, The line is stored in a volatile buffer,
@ -355,7 +345,7 @@ char *readline() {
} }
} }
int getinchar() { static int getinchar(void) {
register int token ; register int token ;
if ( incore ) { if ( incore ) {
@ -369,7 +359,7 @@ int getinchar() {
return token ; return token ;
} }
int getln() { static int getln(void) {
register char *c_ptr ; register char *c_ptr ;
do { do {

View file

@ -5,6 +5,7 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include "ack.h" #include "ack.h"
#include "list.h" #include "list.h"
@ -19,19 +20,18 @@ static char rcs_id[] = "$Id$" ;
#define ARG_MORE 40 /* The size of args chunks to allocate */ #define ARG_MORE 40 /* The size of args chunks to allocate */
extern growstring scanvars(); static int run_exec(trf *, const char *);
static void x_arg(char *);
static char **arglist ; /* The first argument */ static char **arglist ; /* The first argument */
static unsigned argcount ; /* The current number of arguments */ static unsigned argcount ; /* The current number of arguments */
static unsigned argmax; /* The maximum number of arguments so far */ static unsigned argmax; /* The maximum number of arguments so far */
int runphase(phase) register trf *phase ; { int runphase(trf *phase) {
register list_elem *elem ; register list_elem *elem ;
char *prog ; int result ; char *prog ; int result ;
growstring bline ;
bline=scanvars(phase->t_prog) ; prog=phase->t_prog ;
prog=gr_final(&bline) ;
if ( v_flag || debug ) { if ( v_flag || debug ) {
if ( v_flag==1 && !debug ) { if ( v_flag==1 && !debug ) {
vprint("%s",phase->t_name) ; vprint("%s",phase->t_name) ;
@ -66,15 +66,18 @@ int runphase(phase) register trf *phase ; {
} }
x_arg( (char *)0 ) ; x_arg( (char *)0 ) ;
result=run_exec(phase,prog) ; result=run_exec(phase,prog) ;
throws(prog) ;
return result ; return result ;
} }
int run_exec(phase,prog) trf *phase ; char *prog ; { static int run_exec(trf *phase, const char *prog) {
int status, child, waitchild ; int status, child, waitchild ;
do_flush(); fflush(stdout) ;
while ( (child=fork())== -1 ) ; fflush(stderr) ;
child= fork() ;
if ( child== - 1) {
fatal("Cannot fork %s", prog) ;
}
if ( child ) { if ( child ) {
/* The parent */ /* The parent */
do { do {
@ -84,8 +87,6 @@ int run_exec(phase,prog) trf *phase ; char *prog ; {
} }
} while ( waitchild!=child) ; } while ( waitchild!=child) ;
if ( status ) { if ( status ) {
if ( status&0200 && (status&0177)!=SIGQUIT &&
t_flag<=1 ) unlink("core") ;
switch ( status&0177 ) { switch ( status&0177 ) {
case 0 : case 0 :
break ; break ;
@ -136,7 +137,7 @@ int run_exec(phase,prog) trf *phase ; char *prog ; {
/*NOTREACHED*/ /*NOTREACHED*/
} }
x_arg(string) char *string ; { static void x_arg(char *string) {
/* Add one execute argument to the argument vector */ /* Add one execute argument to the argument vector */
if ( argcount==argmax ) { if ( argcount==argmax ) {
if ( argmax==0 ) { if ( argmax==0 ) {

View file

@ -15,9 +15,14 @@
static char rcs_id[] = "$Id$" ; static char rcs_id[] = "$Id$" ;
#endif #endif
void try(); static void start_scan(void);
static void try(list_elem *, const char *);
static void scan_found(void);
static int satisfy(trf *, const char *);
static enum f_path scan_end(trf **);
static void find_cpp(void);
enum f_path getpath(first) register trf **first ; { enum f_path getpath(trf **first) {
/* Try to find a transformation path */ /* Try to find a transformation path */
start_scan(); start_scan();
@ -49,7 +54,7 @@ static int suf_found; /* Was the suffix at least recognized ? */
/******************** The hard work ********************/ /******************** The hard work ********************/
start_scan() { static void start_scan(void) {
register list_elem *scan ; register list_elem *scan ;
scanlist(l_first(tr_list),scan) { scanlist(l_first(tr_list),scan) {
@ -63,8 +68,7 @@ start_scan() {
last_ocount= 0 ; last_ocount= 0 ;
} }
void static void try(list_elem *f_scan, const char *suffix) {
try(f_scan,suffix) list_elem *f_scan; char *suffix; {
register list_elem *scan ; register list_elem *scan ;
register trf *trafo ; register trf *trafo ;
/* Try to find a transformation path starting at f_scan for a /* Try to find a transformation path starting at f_scan for a
@ -134,7 +138,7 @@ try(f_scan,suffix) list_elem *f_scan; char *suffix; {
} }
} }
scan_found() { static void scan_found(void) {
register list_elem *scan; register list_elem *scan;
int ncount, ocount, pcount ; int ncount, ocount, pcount ;
@ -182,7 +186,7 @@ scan_found() {
} }
} }
int satisfy(trafo,suffix) register trf *trafo; char *suffix ; { static int satisfy(trf *trafo, const char *suffix) {
register char *f_char, *l_char ; register char *f_char, *l_char ;
/* Check whether this transformation is present for /* Check whether this transformation is present for
the current machine and the parameter suffix is among the current machine and the parameter suffix is among
@ -207,7 +211,7 @@ int satisfy(trafo,suffix) register trf *trafo; char *suffix ; {
return 0 ; return 0 ;
} }
enum f_path scan_end(first) trf **first ; { /* Finalization */ static enum f_path scan_end(trf **first) { /* Finalization */
/* Return value indicating whether a transformation was found */ /* Return value indicating whether a transformation was found */
/* Set the flags for the transformation up to, but not including, /* Set the flags for the transformation up to, but not including,
the combiner the combiner
@ -248,7 +252,7 @@ enum f_path scan_end(first) trf **first ; { /* Finalization */
return F_OK ; return F_OK ;
} }
find_cpp() { static void find_cpp(void) {
register list_elem *elem ; register list_elem *elem ;
scanlist( l_first(tr_list), elem ) { scanlist( l_first(tr_list), elem ) {
if ( t_cont(*elem)->t_isprep ) { if ( t_cont(*elem)->t_isprep ) {

View file

@ -4,6 +4,7 @@
* *
*/ */
#include <string.h>
#include "ack.h" #include "ack.h"
#ifndef NORCSID #ifndef NORCSID
@ -44,9 +45,6 @@ static char rcs_id[] = "$Id$" ;
*/ */
extern char *getcore();
extern fatal();
struct vars { struct vars {
char *v_name; char *v_name;
enum { routine, string } v_type; enum { routine, string } v_type;
@ -60,7 +58,7 @@ struct vars {
static struct vars *v_first ; static struct vars *v_first ;
static struct vars *newvar(name) char *name; { static struct vars *newvar(char *name) {
register struct vars *new ; register struct vars *new ;
for ( new=v_first ; new ; new= new->v_next ) { for ( new=v_first ; new ; new= new->v_next ) {
@ -72,36 +70,36 @@ static struct vars *newvar(name) char *name; {
return new ; return new ;
} }
} }
new= (struct vars *)getcore( (unsigned)sizeof (struct vars)); new= (struct vars *)getcore(sizeof (struct vars));
new->v_name= name ; new->v_name= name ;
new->v_next= v_first ; new->v_next= v_first ;
v_first= new ; v_first= new ;
return new ; return new ;
} }
setsvar(name,str) char *name, *str ; { void setsvar(char *name, char *str) {
register struct vars *new ; register struct vars *new ;
new= newvar(name); new= newvar(name);
#ifdef DEBUG #ifdef DEBUG
if ( debug>=2 ) vprint("%s=%s\n", name, str) ; if ( debug>=2 ) vprint("%s=%s\n", new->v_name, str) ;
#endif #endif
new->v_type= string; new->v_type= string;
new->v_value.v_string= str; new->v_value.v_string= str;
} }
setpvar(name,rout) char *name, *(*rout)() ; { void setpvar(char *name, char *(*rout)(void)) {
register struct vars *new ; register struct vars *new ;
new= newvar(name); new= newvar(name);
#ifdef DEBUG #ifdef DEBUG
if ( debug>=2 ) vprint("%s= (*%o)()\n",name,rout) ; if ( debug>=2 ) vprint("%s= (*%o)()\n", new->v_name, rout) ;
#endif #endif
new->v_type= routine; new->v_type= routine;
new->v_value.v_routine= rout; new->v_value.v_routine= rout;
} }
char *getvar(name) char *name ; { char *getvar(const char *name) {
register struct vars *scan ; register struct vars *scan ;
for ( scan=v_first ; scan ; scan= scan->v_next ) { for ( scan=v_first ; scan ; scan= scan->v_next ) {

View file

@ -26,13 +26,17 @@ static int touch_head= NO ;
static growstring tail ; static growstring tail ;
static int touch_tail= NO ; static int touch_tail= NO ;
char *headvar(),*tailvar() ; static char *headvar(void);
static char *tailvar(void);
static void set_Rflag(char *);
static void condit(growstring *, list_head *, list_head *, char *);
static int mapflag(list_head *, const char *);
static int mapexpand(char *, const char *);
static void getcallargs(trf *);
static growstring without_bslash(const char *);
static void getprogram(trf *);
void condit(); int transform(trf *phase) {
void doassign();
void set_Rflag();
int transform(phase) register trf *phase ; {
int ok ; int ok ;
if ( !setfiles(phase) ) { if ( !setfiles(phase) ) {
@ -40,17 +44,19 @@ int transform(phase) register trf *phase ; {
return 0 ; return 0 ;
} }
getcallargs(phase) ; getcallargs(phase) ;
getprogram(phase) ;
ok= runphase(phase) ; ok= runphase(phase) ;
if ( !ok ) rmfile(&out) ; if ( !ok ) rmfile(&out) ;
/* Free the space occupied by the arguments, /* Free the space occupied by the arguments,
except for the linker, since we are bound to exit soon except for the linker, since we are bound to exit soon
and do not foresee further need of memory space */ and do not foresee further need of memory space */
if ( !phase->t_linker ) discardargs(phase) ; if ( !phase->t_linker )
l_throw(&phase->t_args) ;
disc_files(phase) ; disc_files(phase) ;
return ok ; return ok ;
} }
getmapflags(phase) register trf *phase ; { void getmapflags(trf *phase) {
register path *l_in ; register path *l_in ;
register list_elem *elem ; register list_elem *elem ;
int scanned ; int scanned ;
@ -75,8 +81,9 @@ getmapflags(phase) register trf *phase ; {
scanlist(l_first(phase->t_inputs),elem) { scanlist(l_first(phase->t_inputs),elem) {
l_in = p_cont(*elem) ; l_in = p_cont(*elem) ;
if ( mapflag(&(phase->t_mapf),l_in->p_path) ) { if ( mapflag(&(phase->t_mapf),l_in->p_path) ) {
ptr= keeps(getvar(LIBVAR)) ; growstring temp;
clr_noscan(ptr) ; temp= without_bslash(getvar(LIBVAR)) ;
ptr= gr_final(&temp);
#ifdef DEBUG #ifdef DEBUG
if ( debug >=4 ) { if ( debug >=4 ) {
vprint("phase %s, library %s(%s)\n", vprint("phase %s, library %s(%s)\n",
@ -110,16 +117,12 @@ getmapflags(phase) register trf *phase ; {
} }
do_Rflag(argp) char *argp ; { static char *headvar(void) {
l_add(&R_list,argp) ;
}
char *headvar() {
if ( !touch_head) return "" ; if ( !touch_head) return "" ;
return gr_start(head) ; return gr_start(head) ;
} }
add_head(str) char *str; { void add_head(const char *str) {
if ( !touch_head) { if ( !touch_head) {
gr_init(&head) ; gr_init(&head) ;
touch_head=YES ; touch_head=YES ;
@ -127,12 +130,12 @@ add_head(str) char *str; {
gr_cat(&head,str) ; gr_cat(&head,str) ;
} }
char *tailvar() { static char *tailvar(void) {
if ( !touch_tail ) return "" ; if ( !touch_tail ) return "" ;
return gr_start(tail) ; return gr_start(tail) ;
} }
add_tail(str) char *str ; { void add_tail(const char *str) {
if ( !touch_tail ) { if ( !touch_tail ) {
gr_init(&tail) ; gr_init(&tail) ;
touch_tail=YES ; touch_tail=YES ;
@ -141,7 +144,7 @@ add_tail(str) char *str ; {
} }
transini() { void transini(void) {
register list_elem *elem ; register list_elem *elem ;
register trf *phase ; register trf *phase ;
@ -157,8 +160,7 @@ transini() {
setpvar(keeps(TAIL),tailvar) ; setpvar(keeps(TAIL),tailvar) ;
} }
void static void set_Rflag(char *argp) {
set_Rflag(argp) register char *argp ; {
register char *eos ; register char *eos ;
register list_elem *prog ; register list_elem *prog ;
register int length ; register int length ;
@ -206,72 +208,47 @@ set_Rflag(argp) register char *argp ; {
/* */ /* */
/**************************************************************************/ /**************************************************************************/
growstring scanb(line) char *line ; { static growstring scanvars(const char *line) {
/* Scan a line for backslashes, setting the NO_SCAN bit in characters
preceded by a backslash.
*/
register char *in_c ;
register int token ;
growstring result ;
enum { TEXT, ESCAPED } state = TEXT ;
gr_init(&result) ;
for ( in_c= line ; *in_c ; in_c++ ) {
token= *in_c&0377 ;
switch( state ) {
case TEXT :
if ( token==BSLASH ) {
state= ESCAPED ;
} else {
gr_add(&result,token) ;
}
break ;
case ESCAPED :
gr_add(&result,token|NO_SCAN) ;
state=TEXT ;
break ;
}
}
gr_add(&result,0) ;
if ( state!=TEXT ) werror("flag line ends with %c",BSLASH) ;
return result ;
}
growstring scanvars(line) char *line ; {
/* Scan a line variable replacements started by S_VAR. /* Scan a line variable replacements started by S_VAR.
Two sequences exist: S_VAR name E_VAR, S_VAR name A_VAR text E_VAR. Two sequences exist: S_VAR name C_VAR, S_VAR name A_VAR text C_VAR.
neither name nor text may contain further replacements. neither name nor text may contain further replacements.
In the first form an error message is issued if the name is not In the first form an error message is issued if the name is not
present in the variables, the second form produces text present in the variables, the second form produces text
in that case. in that case.
The sequence S_VAR S_VAR is transformed into S_VAR.
This to allow later recognition in mapflags, where B_SLASH
would be preventing any recognition.
*/ */
register char *in_c ; const char *in_c ;
register int token ; int token, token_r ;
growstring result ; growstring result, name ;
growstring name ; char *tr ;
register char *tr ;
enum { TEXT, FIRST, NAME, SKIP, COPY } state = TEXT ; enum { TEXT, FIRST, NAME, SKIP, COPY } state = TEXT ;
int escaped = NO;
gr_init(&result) ; gr_init(&name) ; gr_init(&result) ; gr_init(&name) ;
for ( in_c= line ; *in_c ; in_c++ ) { for ( in_c= line ; *in_c ; in_c++ ) {
token= *in_c&0377 ; token= *in_c&0377 ;
token_r= (escaped ? 0 : token);
/* A backslash escapes the next character. */
if ( token_r==BSLASH ) {
if ( state==TEXT || state==COPY ) {
/* Keep BSLASH for later scans. */
gr_add(&result,token) ;
}
escaped= YES;
continue;
}
escaped= NO;
switch( state ) { switch( state ) {
case TEXT : case TEXT :
if ( token==S_VAR ) { if ( token_r==S_VAR ) {
state= FIRST ; state= FIRST ;
} else { } else {
gr_add(&result,token) ; gr_add(&result,token) ;
} }
break ; break ;
case FIRST : case FIRST :
switch ( token ) { switch ( token_r ) {
case S_VAR :
state= TEXT ;
gr_add(&result,token) ;
break ;
case A_VAR : case A_VAR :
case C_VAR : case C_VAR :
fatal("empty string variable name") ; fatal("empty string variable name") ;
@ -282,7 +259,7 @@ growstring scanvars(line) char *line ; {
} }
break ; break ;
case NAME: case NAME:
switch ( token ) { switch ( token_r ) {
case A_VAR : case A_VAR :
gr_add(&name,0) ; gr_add(&name,0) ;
if ( tr=getvar(gr_start(name)) ) { if ( tr=getvar(gr_start(name)) ) {
@ -314,16 +291,17 @@ growstring scanvars(line) char *line ; {
} }
break ; break ;
case SKIP : case SKIP :
if ( token==C_VAR ) state= TEXT ; if ( token_r==C_VAR ) state= TEXT ;
break ; break ;
case COPY : case COPY :
if ( token==C_VAR ) state= TEXT ; else { if ( token_r==C_VAR ) state= TEXT ; else {
gr_add(&result,token) ; gr_add(&result,token) ;
} }
break ; break ;
} }
} }
gr_add(&result,0) ; gr_add(&result,0) ;
if ( escaped ) werror("flag line ends with %c",BSLASH) ;
if ( state!=TEXT ) { if ( state!=TEXT ) {
werror("flag line misses %c",C_VAR) ; werror("flag line misses %c",C_VAR) ;
gr_throw(&name) ; gr_throw(&name) ;
@ -331,74 +309,84 @@ growstring scanvars(line) char *line ; {
return result ; return result ;
} }
growstring scanexpr(line) char *line ; { static growstring scanexpr(const char *line) {
/* Scan a line for conditional or flag expressions, /* Scan a line for conditional or flag expressions,
dependent on the type. The format is dependent on the type. The format is
S_EXPR suflist M_EXPR suflist T_EXPR tail C_EXPR S_EXPR suflist M_EXPR suflist T_EXPR tail C_EXPR
the head and tail are passed to treat, together with the the head and tail are passed to condit(), together with the
growstring for futher treatment. growstring for futher treatment.
Nesting is not allowed. Nesting is not allowed.
*/ */
register char *in_c ; const char *in_c, *heads ;
char *heads ; int token, token_r ;
register int token ; growstring sufs, tailval, result ;
growstring sufs, tailval ;
growstring result ;
static list_head fsuff, lsuff ; static list_head fsuff, lsuff ;
enum { TEXT, FDOT, FSUF, LDOT, LSUF, FTAIL } state = TEXT ; enum { TEXT, FDOT, FSUF, LDOT, LSUF, FTAIL } state = TEXT ;
int escaped = NO;
gr_init(&result) ; gr_init(&sufs) ; gr_init(&tailval) ; gr_init(&result) ; gr_init(&sufs) ; gr_init(&tailval) ;
for ( in_c= line ; *in_c ; in_c++ ) { for ( in_c= line ; *in_c ; in_c++ ) {
token= *in_c&0377 ; token= *in_c&0377 ;
token_r= (escaped ? 0 : token);
/* A backslash escapes the next character. */
if ( token_r==BSLASH ) {
if ( state==TEXT || state==FTAIL ) {
/* Keep BSLASH for later scans. */
gr_add(&result,token) ;
}
escaped= YES;
continue;
}
escaped= NO;
switch( state ) { switch( state ) {
case TEXT : case TEXT :
if ( token==S_EXPR ) { if ( token_r==S_EXPR ) {
state= FDOT ; state= FDOT ;
heads=in_c ; heads=in_c ;
} else gr_add(&result,token) ; } else gr_add(&result,token) ;
break ; break ;
case FDOT : case FDOT :
if ( token==M_EXPR ) { if ( token_r==M_EXPR ) {
state=LDOT ; state=LDOT ;
break ; break ;
} }
token &= ~NO_SCAN ;
if ( token!=SUFCHAR ) { if ( token!=SUFCHAR ) {
error("Missing %c in expression",SUFCHAR) ; error("Missing %c in expression",SUFCHAR) ;
} }
gr_add(&sufs,token) ; state=FSUF ; gr_add(&sufs,token) ; state=FSUF ;
break ; break ;
case FSUF : case FSUF :
if ( token==M_EXPR || (token&~NO_SCAN)==SUFCHAR) { if ( token_r==M_EXPR || token==SUFCHAR ) {
gr_add(&sufs,0) ; gr_add(&sufs,0) ;
l_add(&fsuff,gr_final(&sufs)) ; l_add(&fsuff,gr_final(&sufs)) ;
} }
if ( token==M_EXPR ) { if ( token_r==M_EXPR ) {
state=LDOT ; state=LDOT ;
} else gr_add(&sufs,token&~NO_SCAN) ; } else gr_add(&sufs,token) ;
break ; break ;
case LDOT : case LDOT :
if ( token==T_EXPR ) { if ( token_r==T_EXPR ) {
state=FTAIL ; state=FTAIL ;
break ; break ;
} }
token &= ~NO_SCAN ;
if ( token!=SUFCHAR ) { if ( token!=SUFCHAR ) {
error("Missing %c in expression",SUFCHAR) ; error("Missing %c in expression",SUFCHAR) ;
} }
gr_add(&sufs,token) ; state=LSUF ; gr_add(&sufs,token) ; state=LSUF ;
break ; break ;
case LSUF : case LSUF :
if ( token==T_EXPR || (token&~NO_SCAN)==SUFCHAR) { if ( token_r==T_EXPR || token==SUFCHAR) {
gr_add(&sufs,0) ; gr_add(&sufs,0) ;
l_add(&lsuff,gr_final(&sufs)) ; l_add(&lsuff,gr_final(&sufs)) ;
} }
if ( token==T_EXPR ) { if ( token_r==T_EXPR ) {
state=FTAIL ; state=FTAIL ;
} else gr_add(&sufs,token&~NO_SCAN) ; } else gr_add(&sufs,token) ;
break ; break ;
case FTAIL : case FTAIL :
if ( token==C_EXPR ) { if ( token_r==C_EXPR ) {
/* Found one !! */ /* Found one !! */
gr_add(&tailval,0) ; gr_add(&tailval,0) ;
condit(&result,&fsuff,&lsuff,gr_start(tailval)) ; condit(&result,&fsuff,&lsuff,gr_start(tailval)) ;
@ -418,10 +406,8 @@ growstring scanexpr(line) char *line ; {
return result ; return result ;
} }
void static void condit(growstring *line, list_head *fsuff, list_head *lsuff,
condit(line,fsuff,lsuff,tailval) growstring *line ; char *tailval)
list_head *fsuff, *lsuff;
char *tailval ;
{ {
register list_elem *first ; register list_elem *first ;
register list_elem *last ; register list_elem *last ;
@ -446,7 +432,7 @@ condit(line,fsuff,lsuff,tailval) growstring *line ;
#endif #endif
} }
int mapflag(maplist,cflag) list_head *maplist ; char *cflag ; { static int mapflag(list_head *maplist, const char *cflag) {
/* Expand a flag expression */ /* Expand a flag expression */
/* The flag "cflag" is checked for each of the mapflags. /* The flag "cflag" is checked for each of the mapflags.
A mapflag entry has the form A mapflag entry has the form
@ -468,12 +454,9 @@ int mapflag(maplist,cflag) list_head *maplist ; char *cflag ; {
return 0 ; return 0 ;
} }
int mapexpand(mapentry,cflag) static int mapexpand(char *mapentry, const char *cflag) {
char *mapentry, *cflag ; const char *star ;
{ char *ptr, *space ;
register char *star ;
register char *ptr ;
register char *space ;
int length ; int length ;
star=strchr(mapentry,STAR) ; star=strchr(mapentry,STAR) ;
@ -510,10 +493,10 @@ int mapexpand(mapentry,cflag)
return 1 ; return 1 ;
} }
void void doassign(const char *line, const char *star, int length) {
doassign(line,star,length) char *line, *star ; {
growstring varval, name, temp ; growstring varval, name, temp ;
register char *ptr ; const char *ptr ;
int escaped = NO ;
gr_init(&varval) ; gr_init(&varval) ;
gr_init(&name) ; gr_init(&name) ;
@ -528,12 +511,21 @@ doassign(line,star,length) char *line, *star ; {
} }
temp= scanvars(ptr+1) ; temp= scanvars(ptr+1) ;
for ( ptr=gr_start(temp); *ptr; ptr++ ) switch ( *ptr ) { for ( ptr=gr_start(temp); *ptr; ptr++ ) switch ( *ptr ) {
case BSLASH :
escaped= YES ;
gr_add(&varval,*ptr) ;
break ;
case STAR : case STAR :
if ( star ) { if ( star && !escaped ) {
while ( length-- ) gr_add(&varval,*star++|NO_SCAN) ; while ( length-- ) {
gr_add(&varval,BSLASH) ;
gr_add(&varval,*star++) ;
}
break ; break ;
} }
/* FALLTHROUGH */
default : default :
escaped= NO ;
gr_add(&varval,*ptr) ; gr_add(&varval,*ptr) ;
break ; break ;
} }
@ -544,15 +536,16 @@ doassign(line,star,length) char *line, *star ; {
#define ISBLANK(c) ( (c)==SPACE || (c)==TAB ) #define ISBLANK(c) ( (c)==SPACE || (c)==TAB )
unravel(line,action) char *line ; int (*action)() ; { static void unravel(const char *line, void (*action)(char *)) {
/* Unravel the line, get arguments a la shell */ /* Unravel the line, get arguments a la shell */
/* each argument is handled to action */ /* each argument is handled to action */
/* The input string is left intact */ /* The input string is left intact */
register char *in_c ; const char *in_c ;
register int token ; int token ;
enum { BLANK, ARG } state = BLANK ; enum { BLANK, ARG, ESCAPED } state = BLANK ;
growstring argum ; growstring argum ;
/* Loop for each character of line, including final '\0' */
in_c=line ; in_c=line ;
for (;;) { for (;;) {
token= *in_c&0377 ; token= *in_c&0377 ;
@ -560,9 +553,13 @@ unravel(line,action) char *line ; int (*action)() ; {
case BLANK : case BLANK :
if ( token==0 ) break ; if ( token==0 ) break ;
if ( !ISBLANK(token) ) { if ( !ISBLANK(token) ) {
state= ARG ;
gr_init(&argum) ; gr_init(&argum) ;
gr_add(&argum,token&~NO_SCAN) ; gr_add(&argum,token) ;
if ( token == BSLASH ) {
state= ESCAPED ;
} else {
state= ARG ;
}
} }
break ; break ;
case ARG : case ARG :
@ -572,97 +569,106 @@ unravel(line,action) char *line ; int (*action)() ; {
gr_throw(&argum) ; gr_throw(&argum) ;
state=BLANK ; state=BLANK ;
} else { } else {
gr_add(&argum,token&~NO_SCAN) ; gr_add(&argum,token) ;
if ( token == BSLASH ) state= ESCAPED ;
} }
break ; break ;
case ESCAPED :
gr_add(&argum,token) ;
state= ARG ;
break ;
} }
if ( token == 0 ) break ; if ( token == 0 ) break ;
in_c++ ; in_c++ ;
} }
} }
char *c_rep(string,place,rep) char *string, *place, *rep ; {
/* Produce a string in stable storage produced from 'string'
with the character at place replaced by rep
*/
growstring name ;
register char *nc ;
register char *xc ;
gr_init(&name) ;
for ( nc=string ; *nc && nc<place ; nc++ ) {
gr_add(&name,*nc) ;
}
#ifdef DEBUG
if ( *nc==0 ) fatal("Place is not in string") ;
#endif
for ( xc=rep ; *xc ; xc++ ) gr_add(&name,*xc|NO_SCAN) ;
gr_add(&name,0) ;
gr_cat(&name,nc+1) ;
return gr_final(&name) ;
}
static list_head *curargs ; static list_head *curargs ;
static list_head *comb_args ; static list_head *comb_args ;
void static void addargs3(const char *prefix1, const char *prefix2,
addargs(string) char *string ; { const char *string)
register char *temp, *repc ; {
register list_elem *elem ; /* Prepend prefix1 and prefix2 to string, then add it to
curargs. string is scanned to strip backslashes and
substitute files for C_IN and C_OUT. prefixes are not
scanned.
*/
const char *in_c ;
int token ;
char *tr ;
list_elem *elem ;
growstring argum ;
int escaped = NO ;
repc=strchr(string,C_IN) ; gr_init(&argum);
if ( repc ) { for ( in_c= prefix1 ; *in_c ; in_c++ ) {
/* INPUT FILE TOKEN seen, replace it and scan further */ gr_add(&argum,*in_c) ;
if ( repc==string && string[1]==0 ) {
if ( in.p_path ) { /* All but combiner */
l_add(curargs,keeps(in.p_path)) ;
} else {
scanlist( l_first(*comb_args), elem ) {
l_add(curargs,
keeps(p_cont(*elem)->p_path)) ;
} }
for ( in_c= prefix2 ; *in_c ; in_c++ ) {
gr_add(&argum,*in_c) ;
} }
return ; for ( in_c= string ; *in_c ; in_c++ ) {
token= *in_c&0377 ;
if ( escaped ) {
/* Strip BSLASH, keep escaped character. */
gr_add(&argum,token) ;
escaped= NO ;
continue;
} }
switch ( token ) {
case BSLASH:
escaped= YES ;
break;
case C_IN: /* Input file */
if ( in.p_path ) { /* Not for the combiners */ if ( in.p_path ) { /* Not for the combiners */
temp=c_rep(string,repc,in.p_path) ; for ( tr= in.p_path ; *tr; tr++ ) {
addargs(temp) ; gr_add(&argum,*tr);
throws(temp) ; }
} else { /* For the combiners */ } else { /* For the combiners */
gr_add(&argum,0);
tr= gr_final(&argum);
in_c++;
scanlist( l_first(*comb_args), elem ) { scanlist( l_first(*comb_args), elem ) {
temp=c_rep(string,repc,p_cont(*elem)->p_path); char *p = p_cont(*elem)->p_path ;
addargs(temp) ; addargs3(tr,p,in_c) ;
throws(temp) ;
} }
throws(tr);
return;
} }
return ; break;
} case C_OUT: /* Output file */
repc=strchr(string,C_OUT) ;
if ( repc ) {
/* replace the outfile token as with the infile token */
#ifdef DEBUG #ifdef DEBUG
if ( !out.p_path ) fatal("missing output filename") ; if ( !out.p_path ) fatal("missing output filename") ;
#endif #endif
temp=c_rep(string,repc,out.p_path) ; for ( tr= out.p_path ; *tr ; tr++ ) {
addargs(temp) ; gr_add(&argum,*tr) ;
throws(temp) ;
return ;
} }
temp= keeps(string) ; break;
clr_noscan(temp) ; default:
l_add(curargs,temp) ; gr_add(&argum,token) ;
break;
}
}
gr_add(&argum,0) ;
tr= gr_final(&argum) ;
l_add(curargs,tr) ;
} }
getcallargs(phase) register trf *phase ; { static void addargs(char *string) {
addargs3("", "", string) ;
}
static void getcallargs(trf *phase) {
growstring arg1, arg2 ; growstring arg1, arg2 ;
arg1= scanvars(phase->t_argd) ; arg1= scanvars(phase->t_argd) ;
#ifdef DEBUG #ifdef DEBUG
if ( debug>=3 ) { vprint("\tvars: ") ; prns(gr_start(arg1)) ; } if ( debug>=3 ) vprint("\tvars: %s", gr_start(arg1)) ;
#endif #endif
arg2= scanexpr(gr_start(arg1)) ; arg2= scanexpr(gr_start(arg1)) ;
#ifdef DEBUG #ifdef DEBUG
if ( debug>=3 ) { vprint("\texpr: ") ; prns(gr_start(arg2)) ; } if ( debug>=3 ) vprint("\texpr: %s", gr_start(arg2)) ;
#endif #endif
gr_throw(&arg1) ; gr_throw(&arg1) ;
curargs= &phase->t_args ; curargs= &phase->t_args ;
@ -671,6 +677,39 @@ getcallargs(phase) register trf *phase ; {
gr_throw(&arg2) ; gr_throw(&arg2) ;
} }
discardargs(phase) register trf *phase ; { static growstring without_bslash(const char *string) {
l_throw(&phase->t_args) ; /* Strip backslashes from a copy of the string. */
growstring result;
const char *in_c ;
int token ;
int escaped = NO ;
gr_init(&result) ;
for ( in_c= string ; *in_c ; in_c++ ) {
token= *in_c&0377 ;
if ( token==BSLASH && !escaped ) {
escaped= YES ;
} else {
gr_add(&result,token);
escaped= NO ;
}
}
gr_add(&result,0);
return result;
}
static void getprogram(trf *phase) {
growstring prog1, prog2 ;
const char *in_c ;
int token ;
int escaped = NO ;
/* Expand string variables in program name. */
prog1= scanvars(phase->t_prog) ;
throws(phase->t_prog) ;
/* Strip backslashes. */
prog2= without_bslash(gr_start(prog1));
gr_throw(&prog1);
phase->t_prog= gr_final(&prog2);
} }

View file

@ -44,3 +44,26 @@ struct transform {
} ; } ;
#define t_cont(elem) ((trf *)l_content(elem)) #define t_cont(elem) ((trf *)l_content(elem))
/* files.c */
int setfiles(trf *);
void disc_files(trf *);
void disc_inputs(trf *);
void rmfile(path *);
void rmtemps(void);
void add_input(path *, trf *);
/* run.c */
int runphase(trf *);
/* scan.c */
enum f_path { F_OK, F_NOMATCH, F_NOPATH } ;
enum f_path getpath(trf **);
/* trans.c */
int transform(trf *);
void getmapflags(trf *);
void add_head(const char *);
void add_tail(const char *);
void transini(void);
void doassign(const char *, const char *, int);

View file

@ -32,15 +32,11 @@ extern int n_error;
# define STDOUT stderr # define STDOUT stderr
#endif #endif
void fuerror(const char* fmt, ...); char *ack_basename(const char *string) {
void werror(const char* fmt, ...);
char *basename(string) char *string ; {
static char retval[256] ; static char retval[256] ;
char *last_dot, *last_start ; const char *last_dot, *last_start, *fetch ;
register char *store; char *store ;
register char *fetch ; int ctoken ;
register int ctoken ;
last_dot= (char *)0 ; last_dot= (char *)0 ;
last_start= string ; last_start= string ;
@ -50,9 +46,6 @@ char *basename(string) char *string ; {
case '/' : last_start=fetch+1 ; break ; case '/' : last_start=fetch+1 ; break ;
case 0 : goto out ; case 0 : goto out ;
} }
if ( !isascii(ctoken) || !isprint(ctoken) ) {
werror("non-ascii characters in argument %s",string) ;
}
} }
out: out:
if ( ! *last_start ) fuerror("empty filename \"%s\"",string) ; if ( ! *last_start ) fuerror("empty filename \"%s\"",string) ;
@ -65,21 +58,14 @@ out:
return retval ; return retval ;
} }
clr_noscan(str) char *str ; { char *skipblank(char *str) {
register char *ptr ;
for ( ptr=str ; *ptr ; ptr++ ) {
*ptr&= ~NO_SCAN ;
}
}
char *skipblank(str) char *str ; {
register char *ptr ; register char *ptr ;
for ( ptr=str ; *ptr==SPACE || *ptr==TAB ; ptr++ ) ; for ( ptr=str ; *ptr==SPACE || *ptr==TAB ; ptr++ ) ;
return ptr ; return ptr ;
} }
char *firstblank(str) char *str ; { char *firstblank(char *str) {
register char *ptr ; register char *ptr ;
for ( ptr=str ; *ptr && *ptr!=SPACE && *ptr!=TAB ; ptr++ ) ; for ( ptr=str ; *ptr && *ptr!=SPACE && *ptr!=TAB ; ptr++ ) ;
@ -109,15 +95,6 @@ void vprint(const char* fmt, ...)
va_end(ap); va_end(ap);
} }
#ifdef DEBUG
prns(s) register char *s ; {
for ( ; *s ; s++ ) {
putc((*s&0377)&~NO_SCAN,STDOUT) ;
}
putc('\n',STDOUT) ;
}
#endif
/* VARARGS1 */ /* VARARGS1 */
void fuerror(const char *fmt, ...) { void fuerror(const char *fmt, ...) {
/* Fatal user error */ /* Fatal user error */
@ -153,48 +130,36 @@ void error(const char *fmt, ...) {
va_end(ap); va_end(ap);
} }
do_flush() { void quit(int code) {
fflush(stdout) ;
fflush(stderr) ;
}
void
noodstop() {
quit(-3) ;
}
quit(code) {
rmtemps(); rmtemps();
exit(code); exit(code);
} }
/****** /******
char *keeps(string) char *keeps(string)
Keep the string in stable storage. Keep the string in stable storage.
throws(string) throws(string)
Remove the string stored by keep from stable storage. Remove the string stored by keep from stable storage.
throws() is now a macro in ack.h.
***********/ ***********/
char *keeps(str) char *str ; { char *keeps(const char *str) {
register char *result ; register char *result ;
result= getcore( (unsigned)(strlen(str)+1) ) ; result= getcore( (unsigned)(strlen(str)+1) ) ;
if ( !result ) fatal("Out of core") ; if ( !result ) fatal("Out of core") ;
return strcpy(result,str) ; return strcpy(result,str) ;
} }
throws(str) char *str ; { void *getcore(size_t size) {
freecore(str) ; void *retptr ;
}
char *getcore(size) unsigned size ; {
register char *retptr ;
retptr= calloc(1,size) ; retptr= calloc(1,size) ;
if ( !retptr ) fatal("Out of memory") ; if ( !retptr ) fatal("Out of memory") ;
return retptr ; return retptr ;
} }
char *changecore(ptr,size) char *ptr ; unsigned size ; { void *changecore(void *ptr, size_t size) {
register char *retptr ; void *retptr ;
retptr= realloc(ptr,size) ; retptr= realloc(ptr,size) ;
if ( !retptr ) fatal("Out of memory") ; if ( !retptr ) fatal("Out of memory") ;