home *** CD-ROM | disk | FTP | other *** search
- /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/function.c,v 1.1 91/05/06 15:23:14 dvadura Exp $
- -- SYNOPSIS -- GNU style functions for dmake.
- --
- -- DESCRIPTION
- -- All GNU stule functions understood by dmake are implemented in this
- -- file. Currently the only such function is $(mktmp ...) which is
- -- not part of GNU-make is an extension provided by dmake.
- --
- -- AUTHOR
- -- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- -- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- --
- -- COPYRIGHT
- -- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- --
- -- This program is free software; you can redistribute it and/or
- -- modify it under the terms of the GNU General Public License
- -- (version 1), as published by the Free Software Foundation, and
- -- found in the file 'LICENSE' included with this distribution.
- --
- -- This program is distributed in the hope that it will be useful,
- -- but WITHOUT ANY WARRANTY; without even the implied warrant of
- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- -- GNU General Public License for more details.
- --
- -- You should have received a copy of the GNU General Public License
- -- along with this program; if not, write to the Free Software
- -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- --
- -- LOG
- -- $Log: function.c,v $
- * Revision 1.1 91/05/06 15:23:14 dvadura
- * dmake Release Version 3.7
- *
- */
-
- #include "extern.h"
-
- static char *_exec_mktmp ANSI((char *, char *, char *));
- static char *_exec_subst ANSI((char *, char *, char *));
- static char *_exec_iseq ANSI((char *, char *, char *, int));
- static char *_exec_sort ANSI((char *));
- static char *_exec_shell ANSI((char *));
- static int _mystrcmp ANSI((CONST void *, CONST void *));
-
-
- PUBLIC char *
- Exec_function(buf)/*
- ====================
- Execute the function given by the value of args.
-
- So far mktmp is the only valid function, anything else elicits and error
- message. It is my hope to support the GNU style functions in this portion
- of the code at some time in the future. */
- char *buf;
- {
- char *fname;
- char *args;
- char *mod1;
- char *mod2 = NIL(char);
- char *res = NIL(char);
-
- /* This must succeed since the presence of ' ', \t or \n is what
- * determines if this functions is called in the first place. */
- fname = _substr(buf, args=_strpbrk(buf," \t\n"));
-
- if( (mod1 = strchr(fname,',')) != NIL(char) ){
- *mod1 = '\0';
- mod1++;
-
- if( (mod2 = strchr(mod1,',')) != NIL(char) ){
- *mod2 = '\0';
- mod2++;
- }
- }
-
- switch( *fname ) {
- case 'e':
- if(strncmp(fname,"eq",2) == 0) res = _exec_iseq(mod1,mod2,args,TRUE);
- break;
-
- case 'm':
- if( strncmp(fname,"mktmp", 5) == 0 ) res = _exec_mktmp(mod1,mod2,args);
- break;
-
- case 'n':
- if( strncmp(fname,"null", 4) == 0 )
- res = _exec_iseq(mod1,NIL(char),args,TRUE);
- break;
-
- case '!':
- if(strncmp(fname,"!null",5) == 0)
- res = _exec_iseq(mod1,NIL(char),args,FALSE);
- if(strncmp(fname,"!eq",3) == 0) res = _exec_iseq(mod1,mod2,args,FALSE);
- break;
-
- case 's':
- if(strncmp(fname,"sort",4) == 0) res = _exec_sort(args);
- else if(strncmp(fname,"shell",5)==0) res = _exec_shell(args);
- else if(strncmp(fname,"strip",5)==0) res = Tokenize(Expand(args)," ");
- else if(strncmp(fname,"subst",5)==0) res = _exec_subst(mod1,mod2,args);
- break;
-
- default:
- Warning( "Function '%s' not implemented at this time", fname );
- }
-
- if( res == NIL(char) ) res = _strdup("");
-
- FREE(fname);
- return(res);
- }
-
-
- static char *
- _exec_mktmp( file, text, data )
- char *file;
- char *text;
- char *data;
- {
- register char *p;
- char *tmpname;
- char *name;
- FILE *tmpfile = NIL(FILE);
-
- /* This is only a test of the recipe line so prevent the tempfile side
- * effects. */
- if( Suppress_temp_file ) return(NIL(char));
-
- name = Current_target ? Current_target->CE_NAME:"makefile text";
-
- if( file && *file ) {
- char *newtmp;
-
- /* This call to Get_temp sets TMPFILE for subsequent expansion of file.
- * DO NOT DELETE IT! */
- Get_temp( &newtmp, "", FALSE ); FREE(newtmp);
- tmpname = Expand(file);
-
- if( *tmpname ) {
- if( (tmpfile = fopen(tmpname, "w")) == NIL(FILE) )
- Open_temp_error( tmpname, name );
-
- Def_macro("TMPFILE", tmpname, M_EXPANDED|M_MULTI);
- Link_temp( Current_target, tmpfile, tmpname );
- }
- else
- FREE(tmpname);
- }
-
- if( !tmpfile )
- tmpfile = Start_temp( "", Current_target, &tmpname );
-
- if( !text || !*text ) text = tmpname;
- data = Expand(_strspn(data, " \t\n"));
-
- for(p=strchr(data,'\n'); p; p=strchr(p,'\n')) {
- char *q = _strspn(++p," \t");
- strcpy(p,q);
- }
-
- Append_line( data, FALSE, tmpfile, name, FALSE, TRUE );
- Close_temp( Current_target, tmpfile );
- FREE(data);
-
- return( Expand(text) );
- }
-
-
- static char *
- _exec_iseq( lhs, rhs, data, eq )
- char *lhs;
- char *rhs;
- char *data;
- int eq;
- {
- char *l = Expand(lhs);
- char *r = Expand(rhs);
- char *i = _strspn(data, " \t\n");
- char *e = strchr(i, ' ');
- char *res = NIL(char);
- int val = strcmp(l,r);
-
- if( (!val && eq) || (val && !eq) ) {
- if( e != NIL(char) ) *e = '\0';
- res = Expand(i);
- }
- else if( e != NIL(char) ) {
- e = _strspn(e," \t\n");
- if( *e ) res = Expand(e);
- }
-
- FREE(l);
- FREE(r);
- return(res);
- }
-
-
- static char *
- _exec_sort( args )
- char *args;
- {
- char *res = NIL(char);
- char *data = Expand(args);
- char **tokens = NIL(char *);
- char *p;
- char *white = " \t\n";
- int j;
- int i = 0;
-
- for( i=0,p=_strspn(data,white); *p; p=_strspn(_strpbrk(p,white),white),i++);
-
- if( i != 0 ) {
- TALLOC(tokens, i, char *);
-
- for( i=0,p=_strspn(data,white); *p; p=_strspn(p,white),i++){
- tokens[i] = p;
- p = _strpbrk(p,white);
- if( *p ) *p++ = '\0';
- }
-
- qsort( tokens, i-1, sizeof(char *), _mystrcmp );
-
- for( j=0; j<i; j++ ) res = _strapp(res, tokens[j]);
- FREE(data);
- FREE(tokens);
- }
-
- return(res);
- }
-
-
- static int
- _mystrcmp( p, q )
- CONST void *p;
- CONST void *q;
- {
- return(strcmp(*((CONST char **)p),*((CONST char **)q)));
- }
-
-
- static char *
- _exec_subst( pat, subst, data )
- char *pat;
- char *subst;
- char *data;
- {
- char *res;
-
- pat = Expand(pat);
- subst = Expand(subst);
- res = Apply_edit( Expand(data), pat, subst, TRUE, FALSE );
- FREE(pat);
- FREE(subst);
-
- return(res);
- }
-
-
- static char *
- _exec_shell( data )
- char *data;
- {
- extern char *tempnam();
- int wait = Wait_for_completion;
- char *res = NIL(char);
- int free_buf = FALSE;
- char *buffer;
- int out;
- int err;
- FILE *tmp;
- char *tmpnm;
- CELL cell;
- STRING rcp;
- HASH cname;
-
- if( Suppress_temp_file ) return(NIL(char));
-
- /* Set the temp CELL used for building prerequisite candidates to
- * all zero so that we don't have to keep initializing all the
- * fields. */
- {
- register char *s = (char *) &cell;
- register int n = sizeof(CELL);
- while( n ) { *s++ = '\0'; n--; }
- }
- rcp.st_string = _strspn(data, " \t+-%@");
- rcp.st_attr = Rcp_attribute( data );
- rcp.st_next = NIL(STRING);
- cname.ht_name = "Shell escape";
- cell.ce_name = &cname;
- cell.ce_fname = cname.ht_name;
- cell.ce_recipe = &rcp;
- cell.ce_flag = F_TARGET|F_RULES;
- cell.ce_attr = A_PHONY|A_SILENT;
-
- tmpnm = tempnam(NIL(char),"mk");
- out = dup( 1 );
- if( (tmp = fopen(tmpnm, "w")) == NIL(FILE) )
- Open_temp_error( tmpnm, cname.ht_name );
-
- Wait_for_completion = TRUE;
- close( 1 );
- dup( fileno(tmp) );
- fclose( tmp );
- Exec_commands( &cell );
- close(1);
- dup(out);
- close(out);
-
- /* Now we have to read the temporary file, get the tokens and return them
- * as a string. */
- if( (tmp = fopen(tmpnm, "r")) == NIL(FILE) )
- Open_temp_error( tmpnm, cname.ht_name );
-
- if( Buffer == NIL(char) ) {
- Buffer_size = BUFSIZ-2;
- buffer = MALLOC(BUFSIZ-2,char);
- free_buf = TRUE;
- }
- else
- buffer = Buffer;
-
- while( fgets(buffer, Buffer_size, tmp) ) {
- char *p = strchr(buffer, '\n');
-
- if( p == NIL(char) )
- res = _strjoin(res,buffer,-1,TRUE);
- else {
- *p = '\0';
- res = _strapp(res,buffer);
- }
- }
-
- fclose(tmp);
- unlink(tmpnm);
- FREE(tmpnm);
- if( free_buf ) FREE(buffer);
-
- Wait_for_completion = wait;
- return(res);
- }
-