mirror of
https://github.com/mirror/make.git
synced 2025-01-27 12:51:07 +08:00
Tue Mar 19 20:21:34 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
Merged VMS port from Klaus Kaempf <kkaempf@didymus.rmi.de>. * make.h (PARAMS): New macro. * config.h-vms: New file. * makefile.com: New file. * makefile.vms: New file. * readme.vms: New file. * vmsdir.h: New file. * vmsfunctions.c: New file. * vmsify.c: New file. * file.h: Renamed to filedef.h to avoid conflict with VMS system hdr. * ar.c: Added prototypes and changes for VMS. * commands.c: Likewise. * commands.h: Likewise. * default.c: Likewise. * dep.h: Likewise. * dir.c: Likewise. * expand.c: Likewise. * file.c: Likewise. * function.c: Likewise. * implicit.c: Likewise. * job.c: Likewise. * job.h: Likewise. * main.c: Likewise. * make.h: Likewise. * misc.c: Likewise. * read.c: Likewise. * remake.c: Likewise. * remote-stub.c: Likewise. * rule.c: Likewise. * rule.h: Likewise. * variable.c: Likewise. * variable.h: Likewise. * vpath.c: Likewise. * compatMakefile (srcs): Rename file.h to filedef.h.
This commit is contained in:
parent
dfefc77263
commit
9e443adaf6
126
ar.c
126
ar.c
@ -20,14 +20,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
|
|
||||||
#ifndef NO_ARCHIVES
|
#ifndef NO_ARCHIVES
|
||||||
|
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
|
||||||
/* Defined in arscan.c. */
|
/* Defined in arscan.c. */
|
||||||
extern long int ar_scan ();
|
extern long int ar_scan PARAMS ((char *archive, long int (*function) (), long int arg));
|
||||||
extern int ar_member_touch ();
|
extern int ar_member_touch PARAMS ((char *arname, char *memname));
|
||||||
extern int ar_name_equal ();
|
extern int ar_name_equal PARAMS ((char *name, char *mem, int truncated));
|
||||||
|
|
||||||
|
|
||||||
/* Return nonzero if NAME is an archive-member reference, zero if not.
|
/* Return nonzero if NAME is an archive-member reference, zero if not.
|
||||||
@ -67,8 +67,113 @@ ar_parse_name (name, arname_p, memname_p)
|
|||||||
if (memname_p != 0)
|
if (memname_p != 0)
|
||||||
*memname_p = savestring (p + 1, end - (p + 1));
|
*memname_p = savestring (p + 1, end - (p + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
#include <lbrdef.h>
|
||||||
|
#include <mhddef.h>
|
||||||
|
#include <credef.h>
|
||||||
|
#include <descrip.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#if __DECC
|
||||||
|
#include <lbr$routines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define uppercasify(str) {char *str1; for (str1 = str; *str1; str1++) *str1 = _toupper(*str1);}
|
||||||
|
|
||||||
|
#define LBR$_KEYNOTFND 2527330 /* This isn't in any .h file anywhere so I got it from a MACRO library */
|
||||||
|
|
||||||
|
time_t
|
||||||
|
ar_member_date (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
static char *arname;
|
||||||
|
static char *memname;
|
||||||
|
char *p,*q;
|
||||||
|
long int val;
|
||||||
|
static struct {
|
||||||
|
struct mhddef mhd;
|
||||||
|
struct credef cre;
|
||||||
|
char garbage[256];
|
||||||
|
} buf;
|
||||||
|
int func=LBR$C_READ,
|
||||||
|
type=LBR$C_TYP_OBJ,
|
||||||
|
rfa[2],
|
||||||
|
lidx,
|
||||||
|
status;
|
||||||
|
$DESCRIPTOR(bufdesc,(char *)&buf);
|
||||||
|
$DESCRIPTOR(libdesc,arname);
|
||||||
|
$DESCRIPTOR(moddesc,memname);
|
||||||
|
|
||||||
|
/* This "file" is an archive member. */
|
||||||
|
p = index (name, '(');
|
||||||
|
arname = savestring (name, p - name);
|
||||||
|
val = strlen (p) - 2;
|
||||||
|
/*
|
||||||
|
if (val > 15)
|
||||||
|
val = 15;
|
||||||
|
*/
|
||||||
|
memname = savestring (p + 1, val);
|
||||||
|
#ifdef OLDWAY
|
||||||
|
p = rindex (memname, ')');
|
||||||
|
if (p != 0) {
|
||||||
|
q = rindex(p,'.');
|
||||||
|
if (q)
|
||||||
|
*q = '\0'; /* to get rid of extension */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
q = rindex(memname,'.');
|
||||||
|
if (q)
|
||||||
|
*q = '\0'; /* to get rid of extension */
|
||||||
|
|
||||||
|
uppercasify(memname);
|
||||||
|
|
||||||
|
/* Make sure we know the modtime of the archive itself because
|
||||||
|
we are likely to be called just before commands to remake a
|
||||||
|
member are run, and they will change the archive itself. */
|
||||||
|
(void) f_mtime (enter_file (arname));
|
||||||
|
|
||||||
|
libdesc.dsc$a_pointer = arname;
|
||||||
|
libdesc.dsc$w_length = strlen(arname);
|
||||||
|
moddesc.dsc$a_pointer = memname;
|
||||||
|
moddesc.dsc$w_length = strlen(memname);
|
||||||
|
|
||||||
|
if (!((status = lbr$ini_control(&lidx,&func,&type,0)) & 1)) {
|
||||||
|
printf("Error in lbr$ini_control, %d\n",status);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((status = lbr$open(&lidx,&libdesc,0,0,0,0,0)) & 1)) {
|
||||||
|
printf("Error opening library %s to lookup member %s, %d\n",arname, memname ,status);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((status = lbr$lookup_key(&lidx,&moddesc,rfa)) & 1)) {
|
||||||
|
if (status != LBR$_KEYNOTFND)
|
||||||
|
printf("Error looking up module %s in library %s, %d\n",memname, arname ,status);
|
||||||
|
lbr$close(&lidx);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((status = lbr$set_module(&lidx,rfa,&bufdesc,&bufdesc,0)) & 1)) {
|
||||||
|
printf("Error getting module info, %d\n",status);
|
||||||
|
lbr$close(&lidx);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lbr$close(&lidx);
|
||||||
|
|
||||||
|
val = SHELL$FIX_TIME(&buf.mhd.mhd$l_datim);
|
||||||
|
|
||||||
|
free (arname);
|
||||||
|
free (memname);
|
||||||
|
return (val <= 0 ? (time_t) -1 : (time_t) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
static long int ar_member_date_1 ();
|
static long int ar_member_date_1 PARAMS ((int desc, char *mem, int truncated, long int hdrpos,
|
||||||
|
long int datapos, long int size, long int date, int uid, int gid, int mode, char *name));
|
||||||
|
|
||||||
/* Return the modtime of NAME. */
|
/* Return the modtime of NAME. */
|
||||||
|
|
||||||
@ -127,9 +232,19 @@ ar_member_date_1 (desc, mem, truncated,
|
|||||||
{
|
{
|
||||||
return ar_name_equal (name, mem, truncated) ? date : 0;
|
return ar_name_equal (name, mem, truncated) ? date : 0;
|
||||||
}
|
}
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
/* Set the archive-member NAME's modtime to now. */
|
/* Set the archive-member NAME's modtime to now. */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
int
|
||||||
|
ar_touch (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
error ("touch archive member is not available on VMS");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
int
|
int
|
||||||
ar_touch (name)
|
ar_touch (name)
|
||||||
char *name;
|
char *name;
|
||||||
@ -182,6 +297,7 @@ ar_touch (name)
|
|||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
/* State of an `ar_glob' run, passed to `ar_glob_match'. */
|
/* State of an `ar_glob' run, passed to `ar_glob_match'. */
|
||||||
|
|
||||||
|
22
commands.c
22
commands.c
@ -18,12 +18,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "commands.h"
|
#include "filedef.h"
|
||||||
#include "file.h"
|
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "job.h"
|
#include "job.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
extern int remote_kill ();
|
extern int remote_kill PARAMS ((int id, int sig));
|
||||||
|
|
||||||
#ifndef HAVE_UNISTD_H
|
#ifndef HAVE_UNISTD_H
|
||||||
extern int getpid ();
|
extern int getpid ();
|
||||||
@ -154,8 +154,11 @@ set_file_variables (file)
|
|||||||
|
|
||||||
bcopy (c, cp, len);
|
bcopy (c, cp, len);
|
||||||
cp += len;
|
cp += len;
|
||||||
|
#if VMS
|
||||||
|
*cp++ = ',';
|
||||||
|
#else
|
||||||
*cp++ = ' ';
|
*cp++ = ' ';
|
||||||
|
#endif
|
||||||
if (! d->changed)
|
if (! d->changed)
|
||||||
qmark_len -= len + 1; /* Don't space in $? for this one. */
|
qmark_len -= len + 1; /* Don't space in $? for this one. */
|
||||||
}
|
}
|
||||||
@ -193,13 +196,20 @@ set_file_variables (file)
|
|||||||
|
|
||||||
bcopy (c, cp, len);
|
bcopy (c, cp, len);
|
||||||
cp += len;
|
cp += len;
|
||||||
|
#if VMS
|
||||||
|
*cp++ = ',';
|
||||||
|
#else
|
||||||
*cp++ = ' ';
|
*cp++ = ' ';
|
||||||
|
#endif
|
||||||
if (d->changed)
|
if (d->changed)
|
||||||
{
|
{
|
||||||
bcopy (c, qp, len);
|
bcopy (c, qp, len);
|
||||||
qp += len;
|
qp += len;
|
||||||
|
#if VMS
|
||||||
|
*qp++ = ',';
|
||||||
|
#else
|
||||||
*qp++ = ' ';
|
*qp++ = ' ';
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +423,7 @@ fatal_error_signal (sig)
|
|||||||
if (sig == SIGQUIT)
|
if (sig == SIGQUIT)
|
||||||
/* We don't want to send ourselves SIGQUIT, because it will
|
/* We don't want to send ourselves SIGQUIT, because it will
|
||||||
cause a core dump. Just exit instead. */
|
cause a core dump. Just exit instead. */
|
||||||
exit (1);
|
exit (EXIT_FAILURE);
|
||||||
|
|
||||||
/* Signal the same code; this time it will really be fatal. The signal
|
/* Signal the same code; this time it will really be fatal. The signal
|
||||||
will be unblocked when we return and arrive then to kill us. */
|
will be unblocked when we return and arrive then to kill us. */
|
||||||
|
@ -36,7 +36,7 @@ struct commands
|
|||||||
#define COMMANDS_SILENT 2 /* Silent: @. */
|
#define COMMANDS_SILENT 2 /* Silent: @. */
|
||||||
#define COMMANDS_NOERROR 4 /* No errors: -. */
|
#define COMMANDS_NOERROR 4 /* No errors: -. */
|
||||||
|
|
||||||
extern void execute_file_commands ();
|
extern void execute_file_commands PARAMS ((struct file *file));
|
||||||
extern void print_commands ();
|
extern void print_commands PARAMS ((struct commands *cmds));
|
||||||
extern void delete_child_targets ();
|
extern void delete_child_targets PARAMS ((struct child *child));
|
||||||
extern void chop_commands ();
|
extern void chop_commands PARAMS ((struct commands *cmds));
|
||||||
|
@ -122,7 +122,7 @@ srcs = $(srcdir)/commands.c $(srcdir)/job.c $(srcdir)/dir.c \
|
|||||||
$(srcdir)/ar.c $(srcdir)/arscan.c \
|
$(srcdir)/ar.c $(srcdir)/arscan.c \
|
||||||
$(srcdir)/signame.c $(srcdir)/signame.h \
|
$(srcdir)/signame.c $(srcdir)/signame.h \
|
||||||
$(srcdir)/getopt.c $(srcdir)/getopt1.c $(srcdir)/getopt.h \
|
$(srcdir)/getopt.c $(srcdir)/getopt1.c $(srcdir)/getopt.h \
|
||||||
$(srcdir)/commands.h $(srcdir)/dep.h $(srcdir)/file.h \
|
$(srcdir)/commands.h $(srcdir)/dep.h $(srcdir)/filedef.h \
|
||||||
$(srcdir)/job.h $(srcdir)/make.h $(srcdir)/rule.h \
|
$(srcdir)/job.h $(srcdir)/make.h $(srcdir)/rule.h \
|
||||||
$(srcdir)/variable.h $(ALLOCA_SRC) $(srcdir)/config.h.in
|
$(srcdir)/variable.h $(ALLOCA_SRC) $(srcdir)/config.h.in
|
||||||
|
|
||||||
|
292
config.h-vms.template
Normal file
292
config.h-vms.template
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@didymus.rmi.de> */
|
||||||
|
/* config.h. Generated automatically by configure. */
|
||||||
|
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||||
|
|
||||||
|
/* Define if on AIX 3.
|
||||||
|
System headers sometimes define this.
|
||||||
|
We just want to avoid a redefinition error message. */
|
||||||
|
#ifndef _ALL_SOURCE
|
||||||
|
/* #undef _ALL_SOURCE */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define if using alloca.c. */
|
||||||
|
/* #undef C_ALLOCA */
|
||||||
|
|
||||||
|
/* Define to empty if the keyword does not work. */
|
||||||
|
/* #undef const */
|
||||||
|
|
||||||
|
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||||
|
This function is required for alloca.c support on those systems. */
|
||||||
|
/* #undef CRAY_STACKSEG_END */
|
||||||
|
|
||||||
|
/* Define for DGUX with <sys/dg_sys_info.h>. */
|
||||||
|
/* #undef DGUX */
|
||||||
|
|
||||||
|
/* Define if the `getloadavg' function needs to be run setuid or setgid. */
|
||||||
|
/* #undef GETLOADAVG_PRIVILEGED 1 */
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
/* #undef gid_t */
|
||||||
|
|
||||||
|
/* Define if you have alloca, as a function or macro. */
|
||||||
|
#define HAVE_ALLOCA 1
|
||||||
|
|
||||||
|
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||||
|
/* #undef HAVE_ALLOCA_H 1 */
|
||||||
|
|
||||||
|
/* Define if you don't have vprintf but do have _doprnt. */
|
||||||
|
/* #undef HAVE_DOPRNT */
|
||||||
|
|
||||||
|
/* Define if your system has its own `getloadavg' function. */
|
||||||
|
/* #undef HAVE_GETLOADAVG */
|
||||||
|
|
||||||
|
/* Define if you have the getmntent function. */
|
||||||
|
/* #undef HAVE_GETMNTENT */
|
||||||
|
|
||||||
|
/* Define if the `long double' type works. */
|
||||||
|
/* #undef HAVE_LONG_DOUBLE */
|
||||||
|
|
||||||
|
/* Define if you support file names longer than 14 characters. */
|
||||||
|
#define HAVE_LONG_FILE_NAMES 1
|
||||||
|
|
||||||
|
/* Define if you have a working `mmap' system call. */
|
||||||
|
/* #undef HAVE_MMAP */
|
||||||
|
|
||||||
|
/* Define if system calls automatically restart after interruption
|
||||||
|
by a signal. */
|
||||||
|
/* #undef HAVE_RESTARTABLE_SYSCALLS */
|
||||||
|
|
||||||
|
/* Define if your struct stat has st_blksize. */
|
||||||
|
/* #undef HAVE_ST_BLKSIZE */
|
||||||
|
|
||||||
|
/* Define if your struct stat has st_blocks. */
|
||||||
|
/* #undef HAVE_ST_BLOCKS */
|
||||||
|
|
||||||
|
/* Define if you have the strcoll function and it is properly defined. */
|
||||||
|
/* #undef HAVE_STRCOLL 1 */
|
||||||
|
|
||||||
|
/* Define if your struct stat has st_rdev. */
|
||||||
|
/* #undef HAVE_ST_RDEV */
|
||||||
|
|
||||||
|
/* Define if you have the strftime function. */
|
||||||
|
/* #undef HAVE_STRFTIME */
|
||||||
|
|
||||||
|
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||||
|
/* #undef HAVE_SYS_WAIT_H 1 */
|
||||||
|
|
||||||
|
/* Define if your struct tm has tm_zone. */
|
||||||
|
/* #undef HAVE_TM_ZONE */
|
||||||
|
|
||||||
|
/* Define if you don't have tm_zone but do have the external array
|
||||||
|
tzname. */
|
||||||
|
/* #undef HAVE_TZNAME */
|
||||||
|
|
||||||
|
/* Define if you have <unistd.h>. */
|
||||||
|
#ifdef __DECC
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||||
|
/* #undef HAVE_UTIME_NULL */
|
||||||
|
|
||||||
|
/* Define if you have <vfork.h>. */
|
||||||
|
/* #undef HAVE_VFORK_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the vprintf function. */
|
||||||
|
#define HAVE_VPRINTF 1
|
||||||
|
|
||||||
|
/* Define if you have the wait3 system call. */
|
||||||
|
/* #undef HAVE_WAIT3 1 */
|
||||||
|
|
||||||
|
/* Define if on MINIX. */
|
||||||
|
/* #undef _MINIX */
|
||||||
|
|
||||||
|
/* Define if your struct nlist has an n_un member. */
|
||||||
|
/* #undef NLIST_NAME_UNION */
|
||||||
|
|
||||||
|
/* Define if you have <nlist.h>. */
|
||||||
|
/* #undef NLIST_STRUCT 1 */
|
||||||
|
|
||||||
|
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||||
|
/* #undef NO_MINUS_C_MINUS_O */
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#define pid_t int
|
||||||
|
|
||||||
|
/* Define if the system does not provide POSIX.1 features except
|
||||||
|
with this defined. */
|
||||||
|
/* #undef _POSIX_1_SOURCE */
|
||||||
|
|
||||||
|
/* Define if you need to in order for stat and other things to work. */
|
||||||
|
/* #undef _POSIX_SOURCE */
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (int or void). */
|
||||||
|
#define RETSIGTYPE void
|
||||||
|
|
||||||
|
/* Define if the setvbuf function takes the buffering type as its second
|
||||||
|
argument and the buffer pointer as the third, as on System V
|
||||||
|
before release 3. */
|
||||||
|
/* #undef SETVBUF_REVERSED 1 */
|
||||||
|
|
||||||
|
/* If using the C implementation of alloca, define if you know the
|
||||||
|
direction of stack growth for your system; otherwise it will be
|
||||||
|
automatically deduced at run-time.
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown
|
||||||
|
*/
|
||||||
|
/* #undef STACK_DIRECTION */
|
||||||
|
|
||||||
|
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||||
|
/* #undef STAT_MACROS_BROKEN */
|
||||||
|
|
||||||
|
/* Define if you have the ANSI C header files. */
|
||||||
|
/* #undef STDC_HEADERS */
|
||||||
|
|
||||||
|
/* Define on System V Release 4. */
|
||||||
|
/* #undef SVR4 */
|
||||||
|
|
||||||
|
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||||
|
/* #undef SYS_SIGLIST_DECLARED */
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#define uid_t int
|
||||||
|
|
||||||
|
/* Define for Encore UMAX. */
|
||||||
|
/* #undef UMAX */
|
||||||
|
|
||||||
|
/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
|
||||||
|
instead of <sys/cpustats.h>. */
|
||||||
|
/* #undef UMAX4_3 */
|
||||||
|
|
||||||
|
/* Define vfork as fork if vfork does not work. */
|
||||||
|
/* #undef vfork */
|
||||||
|
|
||||||
|
/* Define to the name of the SCCS `get' command. */
|
||||||
|
/* #undef SCCS_GET "/usr/sccs/get" */
|
||||||
|
|
||||||
|
/* Define this if the SCCS `get' command understands the `-G<file>' option. */
|
||||||
|
/* #undef SCCS_GET_MINUS_G 1 */
|
||||||
|
|
||||||
|
/* Define this if the C library defines the variable `sys_siglist'. */
|
||||||
|
/* #undefine HAVE_SYS_SIGLIST 1 */
|
||||||
|
|
||||||
|
/* Define this if the C library defines the variable `_sys_siglist'. */
|
||||||
|
/* #undef HAVE__SYS_SIGLIST */
|
||||||
|
|
||||||
|
/* Define this if you have the `union wait' type in <sys/wait.h>. */
|
||||||
|
/* #undef HAVE_UNION_WAIT */
|
||||||
|
|
||||||
|
/* Define this if the POSIX.1 call `sysconf (_SC_OPEN_MAX)' works properly. */
|
||||||
|
/* #undef HAVE_SYSCONF_OPEN_MAX */
|
||||||
|
|
||||||
|
/* Define if you have the dup2 function. */
|
||||||
|
#define HAVE_DUP2 1
|
||||||
|
|
||||||
|
/* Define if you have the getcwd function. */
|
||||||
|
#define HAVE_GETCWD 1
|
||||||
|
|
||||||
|
/* Define if you have the getdtablesize function. */
|
||||||
|
/* #undef HAVE_GETDTABLESIZE 1 */
|
||||||
|
|
||||||
|
/* Define if you have the getgroups function. */
|
||||||
|
/* #undef HAVE_GETGROUPS 1 */
|
||||||
|
|
||||||
|
/* Define if you have the mktemp function. */
|
||||||
|
#define HAVE_MKTEMP 1
|
||||||
|
|
||||||
|
/* Define if you have the psignal function. */
|
||||||
|
/* #undef HAVE_PSIGNAL 1 */
|
||||||
|
|
||||||
|
/* Define if you have the setegid function. */
|
||||||
|
/* #undef HAVE_SETEGID 1 */
|
||||||
|
|
||||||
|
/* Define if you have the seteuid function. */
|
||||||
|
/* #undef HAVE_SETEUID 1 */
|
||||||
|
|
||||||
|
/* Define if you have the setlinebuf function. */
|
||||||
|
/* #undef HAVE_SETLINEBUF 1 */
|
||||||
|
|
||||||
|
/* Define if you have the setregid function. */
|
||||||
|
/* #undefine HAVE_SETREGID 1 */
|
||||||
|
|
||||||
|
/* Define if you have the setreuid function. */
|
||||||
|
/* #define HAVE_SETREUID 1 */
|
||||||
|
|
||||||
|
/* Define if you have the sigsetmask function. */
|
||||||
|
#define HAVE_SIGSETMASK 1
|
||||||
|
|
||||||
|
/* Define if you have the strerror function. */
|
||||||
|
#define HAVE_STRERROR 1
|
||||||
|
|
||||||
|
/* Define if you have the strsignal function. */
|
||||||
|
/* #undef HAVE_STRSIGNAL */
|
||||||
|
|
||||||
|
/* Define if you have the wait3 function. */
|
||||||
|
/* #define HAVE_WAIT3 1 */
|
||||||
|
|
||||||
|
/* Define if you have the waitpid function. */
|
||||||
|
/* #undef HAVE_WAITPID 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <dirent.h> header file. */
|
||||||
|
/* #unddef HAVE_DIRENT_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <fcntl.h> header file. */
|
||||||
|
#ifdef __DECC
|
||||||
|
#define HAVE_FCNTL_H 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define if you have the <limits.h> header file. */
|
||||||
|
#define HAVE_LIMITS_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <mach/mach.h> header file. */
|
||||||
|
/* #undef HAVE_MACH_MACH_H */
|
||||||
|
|
||||||
|
/* Define if you have the <memory.h> header file. */
|
||||||
|
/* #undef HAVE_MEMORY_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <ndir.h> header file. */
|
||||||
|
/* #undef HAVE_NDIR_H */
|
||||||
|
|
||||||
|
/* Define if you have the <string.h> header file. */
|
||||||
|
#define HAVE_STRING_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <pwd.h> header file. */
|
||||||
|
/* #undef HAVE_PWD_H */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/dir.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_DIR_H */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/ndir.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_NDIR_H */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/param.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_PARAM_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the <sys/timeb.h> header file. */
|
||||||
|
#define HAVE_SYS_TIMEB_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <sys/wait.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_WAIT_H 1 */
|
||||||
|
|
||||||
|
/* Define if you have the dgc library (-ldgc). */
|
||||||
|
/* #undef HAVE_LIBDGC */
|
||||||
|
|
||||||
|
/* Define if you have the sun library (-lsun). */
|
||||||
|
/* #undef HAVE_LIBSUN */
|
||||||
|
|
||||||
|
/* VMS specific */
|
||||||
|
|
||||||
|
#define HAVE_VMSDIR_H 1
|
||||||
|
#define HAVE_STDLIB_H 1
|
||||||
|
#define INCLUDEDIR "sys$sysroot:[syslib]"
|
||||||
|
#define LIBDIR "sys$sysroot:[syslib]"
|
||||||
|
|
||||||
|
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||||
|
#undef PARAMS
|
||||||
|
#define PARAMS(protos) protos
|
||||||
|
#else /* Not C++ or ANSI C. */
|
||||||
|
#undef PARAMS
|
||||||
|
#define PARAMS(protos) ()
|
||||||
|
#endif /* C++ or ANSI C. */
|
||||||
|
|
114
default.c
114
default.c
@ -19,7 +19,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
|
#include "job.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
@ -35,9 +36,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
a `.c' or `.p' or ... file rather than from a .s file. */
|
a `.c' or `.p' or ... file rather than from a .s file. */
|
||||||
|
|
||||||
static char default_suffixes[]
|
static char default_suffixes[]
|
||||||
|
#ifdef VMS
|
||||||
|
= ".exe .olb .ln .obj .c .cc .pas .p .for .f .r .y .l .mar \
|
||||||
|
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
||||||
|
.w .ch .cweb .web .com .sh .elc .el";
|
||||||
|
#else
|
||||||
= ".out .a .ln .o .c .cc .C .p .f .F .r .y .l .s .S \
|
= ".out .a .ln .o .c .cc .C .p .f .F .r .y .l .s .S \
|
||||||
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
||||||
.w .ch .web .sh .elc .el";
|
.w .ch .web .sh .elc .el";
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct pspec default_pattern_rules[] =
|
static struct pspec default_pattern_rules[] =
|
||||||
{
|
{
|
||||||
@ -47,9 +54,13 @@ static struct pspec default_pattern_rules[] =
|
|||||||
/* The X.out rules are only in BSD's default set because
|
/* The X.out rules are only in BSD's default set because
|
||||||
BSD Make has no null-suffix rules, so `foo.out' and
|
BSD Make has no null-suffix rules, so `foo.out' and
|
||||||
`foo' are the same thing. */
|
`foo' are the same thing. */
|
||||||
|
#ifdef VMS
|
||||||
|
{ "%.exe", "%",
|
||||||
|
"copy $< $@" },
|
||||||
|
#else
|
||||||
{ "%.out", "%",
|
{ "%.out", "%",
|
||||||
"@rm -f $@ \n cp $< $@" },
|
"@rm -f $@ \n cp $< $@" },
|
||||||
|
#endif
|
||||||
/* Syntax is "ctangle foo.w foo.ch foo.c". */
|
/* Syntax is "ctangle foo.w foo.ch foo.c". */
|
||||||
{ "%.c", "%.w %.ch",
|
{ "%.c", "%.w %.ch",
|
||||||
"$(CTANGLE) $^ $@" },
|
"$(CTANGLE) $^ $@" },
|
||||||
@ -61,6 +72,20 @@ static struct pspec default_pattern_rules[] =
|
|||||||
|
|
||||||
static struct pspec default_terminal_rules[] =
|
static struct pspec default_terminal_rules[] =
|
||||||
{
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
/* RCS. */
|
||||||
|
{ "%", "%$$5lv", /* Multinet style */
|
||||||
|
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
|
||||||
|
{ "%", "[.$$rcs]%$$5lv", /* Multinet style */
|
||||||
|
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
|
||||||
|
{ "%", "%_v", /* Normal style */
|
||||||
|
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
|
||||||
|
{ "%", "[.rcs]%_v", /* Normal style */
|
||||||
|
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
|
||||||
|
|
||||||
|
/* SCCS. */
|
||||||
|
/* ain't no SCCS on vms */
|
||||||
|
#else
|
||||||
/* RCS. */
|
/* RCS. */
|
||||||
{ "%", "%,v",
|
{ "%", "%,v",
|
||||||
"$(CHECKOUT,v)" },
|
"$(CHECKOUT,v)" },
|
||||||
@ -72,12 +97,53 @@ static struct pspec default_terminal_rules[] =
|
|||||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||||
{ "%", "SCCS/s.%",
|
{ "%", "SCCS/s.%",
|
||||||
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
|
||||||
|
#endif /* !VMS */
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *default_suffix_rules[] =
|
static char *default_suffix_rules[] =
|
||||||
{
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
".obj.exe",
|
||||||
|
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) /exe=$@",
|
||||||
|
".mar.exe",
|
||||||
|
"$(LINK.mar) $^ $(LOADLIBES) $(LDLIBS) /exe=$@",
|
||||||
|
".c.exe",
|
||||||
|
"$(COMPILE.c) $^ \n $(LINK.obj) $(subst .c,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@",
|
||||||
|
".cc.exe",
|
||||||
|
"$(COMPILE.cc) $^ \n $(LINK.obj) $(subst .cc,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@",
|
||||||
|
".for.exe",
|
||||||
|
"$(COMPILE.for) $^ \n $(LINK.obj) $(subst .for,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@",
|
||||||
|
".pas.exe",
|
||||||
|
"$(COMPILE.pas) $^ \n $(LINK.obj) $(subst .pas,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@",
|
||||||
|
|
||||||
|
".com",
|
||||||
|
"copy $< >$@",
|
||||||
|
|
||||||
|
".mar.obj",
|
||||||
|
"$(COMPILE.mar) /obj=$@ $<",
|
||||||
|
".c.obj",
|
||||||
|
"$(COMPILE.c) /obj=$@ $<",
|
||||||
|
".cc.obj",
|
||||||
|
"$(COMPILE.cc) /obj=$@ $<",
|
||||||
|
".for.obj",
|
||||||
|
"$(COMPILE.for) /obj=$@ $<",
|
||||||
|
".pas.obj",
|
||||||
|
"$(COMPILE.pas) /obj=$@ $<",
|
||||||
|
|
||||||
|
".y.c",
|
||||||
|
"$(YACC.y) $< \n rename y_tab.c $@",
|
||||||
|
".l.c",
|
||||||
|
"$(LEX.l) $< \n rename lexyy.c $@",
|
||||||
|
|
||||||
|
".texinfo.info",
|
||||||
|
"$(MAKEINFO) $<",
|
||||||
|
|
||||||
|
".tex.dvi",
|
||||||
|
"$(TEX) $<",
|
||||||
|
|
||||||
|
#else /* ! VMS */
|
||||||
|
|
||||||
".o",
|
".o",
|
||||||
"$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
"$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@",
|
||||||
".s",
|
".s",
|
||||||
@ -195,11 +261,52 @@ static char *default_suffix_rules[] =
|
|||||||
".web.tex",
|
".web.tex",
|
||||||
"$(WEAVE) $<",
|
"$(WEAVE) $<",
|
||||||
|
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
0, 0,
|
0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *default_variables[] =
|
static char *default_variables[] =
|
||||||
{
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
"AR", "library/obj",
|
||||||
|
"ARFLAGS", "/replace",
|
||||||
|
"AS", "macro",
|
||||||
|
"CC", "cc",
|
||||||
|
"C++", "gcc/plus",
|
||||||
|
"CXX", "gcc/plus",
|
||||||
|
"CO", "co",
|
||||||
|
"CPP", "$(CC) /preprocess_only",
|
||||||
|
"FC", "fortran",
|
||||||
|
/* System V uses these, so explicit rules using them should work.
|
||||||
|
However, there is no way to make implicit rules use them and FC. */
|
||||||
|
"F77", "$(FC)",
|
||||||
|
"F77FLAGS", "$(FFLAGS)",
|
||||||
|
"LD", "link",
|
||||||
|
"LEX", "lex",
|
||||||
|
"PC", "pascal",
|
||||||
|
"YACC", "yacc", /* Or "bison -y" */
|
||||||
|
"MAKEINFO", "makeinfo",
|
||||||
|
"TEX", "tex",
|
||||||
|
"TEXINDEX", "texindex",
|
||||||
|
|
||||||
|
"RM", "delete/nolog",
|
||||||
|
|
||||||
|
"LINK.obj", "$(LD) $(LDFLAGS)",
|
||||||
|
"COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
|
||||||
|
"COMPILE.cc", "$(C++) $(C++FLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
|
||||||
|
"YACC.y", "$(YACC) $(YFLAGS)",
|
||||||
|
"LEX.l", "$(LEX) $(LFLAGS)",
|
||||||
|
"COMPILE.for", "$(FC) $(FFLAGS) $(TARGET_ARCH)",
|
||||||
|
"COMPILE.pas", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
|
||||||
|
"COMPILE.mar", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
|
||||||
|
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
|
||||||
|
|
||||||
|
"MV", "rename/new_version",
|
||||||
|
"CP", "copy",
|
||||||
|
|
||||||
|
#else /* !VMS */
|
||||||
|
|
||||||
"AR", "ar",
|
"AR", "ar",
|
||||||
"ARFLAGS", "rv",
|
"ARFLAGS", "rv",
|
||||||
"AS", "as",
|
"AS", "as",
|
||||||
@ -310,6 +417,7 @@ static char *default_variables[] =
|
|||||||
"SCCS_OUTPUT_OPTION", "-G$@",
|
"SCCS_OUTPUT_OPTION", "-G$@",
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* !VMS */
|
||||||
0, 0
|
0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
13
dep.h
13
dep.h
@ -40,11 +40,16 @@ struct nameseq
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern struct nameseq *multi_glob (), *parse_file_seq ();
|
extern struct nameseq *multi_glob PARAMS ((struct nameseq *chain, unsigned int size));
|
||||||
extern char *tilde_expand ();
|
#ifdef VMS
|
||||||
|
extern struct nameseq *parse_file_seq ();
|
||||||
|
#else
|
||||||
|
extern struct nameseq *parse_file_seq PARAMS ((char **stringp, char stopchar, unsigned int size, int strip));
|
||||||
|
#endif
|
||||||
|
extern char *tilde_expand PARAMS ((char *name));
|
||||||
|
|
||||||
#ifndef NO_ARCHIVES
|
#ifndef NO_ARCHIVES
|
||||||
extern struct nameseq *ar_glob ();
|
extern struct nameseq *ar_glob PARAMS ((char *arname, char *member_pattern, unsigned int size));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef iAPX286
|
#ifndef iAPX286
|
||||||
@ -54,7 +59,7 @@ extern struct nameseq *ar_glob ();
|
|||||||
extern char *dep_name ();
|
extern char *dep_name ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern struct dep *read_all_makefiles ();
|
extern struct dep *read_all_makefiles PARAMS ((char **makefiles));
|
||||||
|
|
||||||
/* Flag bits for the second argument to `read_makefile'.
|
/* Flag bits for the second argument to `read_makefile'.
|
||||||
These flags are saved in the `changed' field of each
|
These flags are saved in the `changed' field of each
|
||||||
|
192
dir.c
192
dir.c
@ -33,6 +33,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
# ifdef HAVE_NDIR_H
|
# ifdef HAVE_NDIR_H
|
||||||
# include <ndir.h>
|
# include <ndir.h>
|
||||||
# endif
|
# endif
|
||||||
|
# ifdef HAVE_VMSDIR_H
|
||||||
|
# include "vmsdir.h"
|
||||||
|
# endif /* HAVE_VMSDIR_H */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* In GNU systems, <dirent.h> defines this macro for us. */
|
/* In GNU systems, <dirent.h> defines this macro for us. */
|
||||||
@ -92,7 +95,63 @@ dosify (filename)
|
|||||||
*df = 0;
|
*df = 0;
|
||||||
return dos_filename;
|
return dos_filename;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* __MSDOS__ */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
|
||||||
|
static int
|
||||||
|
vms_hash (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
int h = 0;
|
||||||
|
int g;
|
||||||
|
|
||||||
|
while (*name)
|
||||||
|
{
|
||||||
|
h = (h << 4) + *name++;
|
||||||
|
g = h & 0xf0000000;
|
||||||
|
if (g)
|
||||||
|
{
|
||||||
|
h = h ^ (g >> 24);
|
||||||
|
h = h ^ g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fake stat entry for a directory */
|
||||||
|
static int
|
||||||
|
vmsstat_dir (name, st)
|
||||||
|
char *name;
|
||||||
|
struct stat *st;
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
int h;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
dir = opendir (name);
|
||||||
|
if (dir == 0)
|
||||||
|
return -1;
|
||||||
|
closedir (dir);
|
||||||
|
s = strchr (name, ':'); /* find device */
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
*s++ = 0;
|
||||||
|
st->st_dev = (char *)vms_hash (name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
st->st_dev = 0;
|
||||||
|
s = name;
|
||||||
|
}
|
||||||
|
h = vms_hash (s);
|
||||||
|
st->st_ino[0] = h & 0xff;
|
||||||
|
st->st_ino[1] = h & 0xff00;
|
||||||
|
st->st_ino[2] = h >> 16;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* VMS */
|
||||||
|
|
||||||
/* Hash table of directories. */
|
/* Hash table of directories. */
|
||||||
|
|
||||||
@ -104,8 +163,12 @@ struct directory_contents
|
|||||||
{
|
{
|
||||||
struct directory_contents *next;
|
struct directory_contents *next;
|
||||||
|
|
||||||
int dev, ino; /* Device and inode numbers of this dir. */
|
dev_t dev; /* Device and inode numbers of this dir. */
|
||||||
|
#ifdef VMS
|
||||||
|
ino_t ino[3];
|
||||||
|
#else
|
||||||
|
ino_t ino;
|
||||||
|
#endif
|
||||||
struct dirfile **files; /* Files in this directory. */
|
struct dirfile **files; /* Files in this directory. */
|
||||||
DIR *dirstream; /* Stream reading this directory. */
|
DIR *dirstream; /* Stream reading this directory. */
|
||||||
};
|
};
|
||||||
@ -149,7 +212,8 @@ struct dirfile
|
|||||||
#define DIRFILE_BUCKETS 107
|
#define DIRFILE_BUCKETS 107
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int dir_contents_file_exists_p ();
|
static int dir_contents_file_exists_p PARAMS ((struct directory_contents *dir, char *filename));
|
||||||
|
static struct directory *find_directory PARAMS ((char *name));
|
||||||
|
|
||||||
/* Find the directory named NAME and return its `struct directory'. */
|
/* Find the directory named NAME and return its `struct directory'. */
|
||||||
|
|
||||||
@ -160,6 +224,12 @@ find_directory (name)
|
|||||||
register unsigned int hash = 0;
|
register unsigned int hash = 0;
|
||||||
register char *p;
|
register char *p;
|
||||||
register struct directory *dir;
|
register struct directory *dir;
|
||||||
|
#ifdef VMS
|
||||||
|
if ((*name == '.') && (*(name+1) == 0))
|
||||||
|
name = "[]";
|
||||||
|
else
|
||||||
|
name = vmsify (name,1);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (p = name; *p != '\0'; ++p)
|
for (p = name; *p != '\0'; ++p)
|
||||||
HASH (hash, *p);
|
HASH (hash, *p);
|
||||||
@ -183,21 +253,41 @@ find_directory (name)
|
|||||||
/* The directory is not in the name hash table.
|
/* The directory is not in the name hash table.
|
||||||
Find its device and inode numbers, and look it up by them. */
|
Find its device and inode numbers, and look it up by them. */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
if (vmsstat_dir (name, &st) < 0)
|
||||||
|
#else
|
||||||
if (stat (name, &st) < 0)
|
if (stat (name, &st) < 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
/* Couldn't stat the directory. Mark this by
|
/* Couldn't stat the directory. Mark this by
|
||||||
setting the `contents' member to a nil pointer. */
|
setting the `contents' member to a nil pointer. */
|
||||||
dir->contents = 0;
|
dir->contents = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Search the contents hash table; device and inode are the key. */
|
/* Search the contents hash table; device and inode are the key. */
|
||||||
|
|
||||||
struct directory_contents *dc;
|
struct directory_contents *dc;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
hash = ((unsigned int) st.st_dev << 16)
|
||||||
|
| ((unsigned int) st.st_ino[0]
|
||||||
|
+ (unsigned int) st.st_ino[1]
|
||||||
|
+ (unsigned int) st.st_ino[2]);
|
||||||
|
#else
|
||||||
hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ino;
|
hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ino;
|
||||||
|
#endif
|
||||||
hash %= DIRECTORY_BUCKETS;
|
hash %= DIRECTORY_BUCKETS;
|
||||||
|
|
||||||
for (dc = directories_contents[hash]; dc != 0; dc = dc->next)
|
for (dc = directories_contents[hash]; dc != 0; dc = dc->next)
|
||||||
if (dc->dev == st.st_dev && dc->ino == st.st_ino)
|
if (dc->dev == st.st_dev
|
||||||
|
#ifdef VMS
|
||||||
|
&& dc->ino[0] == st.st_ino[0]
|
||||||
|
&& dc->ino[1] == st.st_ino[1]
|
||||||
|
&& dc->ino[2] == st.st_ino[2])
|
||||||
|
#else
|
||||||
|
&& dc->ino == st.st_ino)
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (dc == 0)
|
if (dc == 0)
|
||||||
@ -209,15 +299,23 @@ find_directory (name)
|
|||||||
|
|
||||||
/* Enter it in the contents hash table. */
|
/* Enter it in the contents hash table. */
|
||||||
dc->dev = st.st_dev;
|
dc->dev = st.st_dev;
|
||||||
|
#ifdef VMS
|
||||||
|
dc->ino[0] = st.st_ino[0];
|
||||||
|
dc->ino[1] = st.st_ino[1];
|
||||||
|
dc->ino[2] = st.st_ino[2];
|
||||||
|
#else
|
||||||
dc->ino = st.st_ino;
|
dc->ino = st.st_ino;
|
||||||
|
#endif
|
||||||
dc->next = directories_contents[hash];
|
dc->next = directories_contents[hash];
|
||||||
directories_contents[hash] = dc;
|
directories_contents[hash] = dc;
|
||||||
|
|
||||||
dc->dirstream = opendir (name);
|
dc->dirstream = opendir (name);
|
||||||
if (dc->dirstream == 0)
|
if (dc->dirstream == 0)
|
||||||
|
{
|
||||||
/* Couldn't open the directory. Mark this by
|
/* Couldn't open the directory. Mark this by
|
||||||
setting the `files' member to a nil pointer. */
|
setting the `files' member to a nil pointer. */
|
||||||
dc->files = 0;
|
dc->files = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Allocate an array of buckets for files and zero it. */
|
/* Allocate an array of buckets for files and zero it. */
|
||||||
@ -257,19 +355,26 @@ dir_contents_file_exists_p (dir, filename)
|
|||||||
register struct dirent *d;
|
register struct dirent *d;
|
||||||
|
|
||||||
if (dir == 0 || dir->files == 0)
|
if (dir == 0 || dir->files == 0)
|
||||||
|
{
|
||||||
/* The directory could not be stat'd or opened. */
|
/* The directory could not be stat'd or opened. */
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
filename = dosify (filename);
|
filename = dosify (filename);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
filename = vmsify (filename,0);
|
||||||
|
#endif
|
||||||
|
|
||||||
hash = 0;
|
hash = 0;
|
||||||
if (filename != 0)
|
if (filename != 0)
|
||||||
{
|
{
|
||||||
if (*filename == '\0')
|
if (*filename == '\0')
|
||||||
|
{
|
||||||
/* Checking if the directory exists. */
|
/* Checking if the directory exists. */
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (p = filename; *p != '\0'; ++p)
|
for (p = filename; *p != '\0'; ++p)
|
||||||
HASH (hash, *p);
|
HASH (hash, *p);
|
||||||
@ -278,16 +383,22 @@ dir_contents_file_exists_p (dir, filename)
|
|||||||
/* Search the list of hashed files. */
|
/* Search the list of hashed files. */
|
||||||
|
|
||||||
for (df = dir->files[hash]; df != 0; df = df->next)
|
for (df = dir->files[hash]; df != 0; df = df->next)
|
||||||
if (streq (df->name, filename))
|
{
|
||||||
return !df->impossible;
|
if (streq (df->name, filename))
|
||||||
|
{
|
||||||
|
return !df->impossible;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The file was not found in the hashed list.
|
/* The file was not found in the hashed list.
|
||||||
Try to read the directory further. */
|
Try to read the directory further. */
|
||||||
|
|
||||||
if (dir->dirstream == 0)
|
if (dir->dirstream == 0)
|
||||||
|
{
|
||||||
/* The directory has been all read in. */
|
/* The directory has been all read in. */
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while ((d = readdir (dir->dirstream)) != 0)
|
while ((d = readdir (dir->dirstream)) != 0)
|
||||||
{
|
{
|
||||||
@ -309,11 +420,12 @@ dir_contents_file_exists_p (dir, filename)
|
|||||||
dir->files[newhash] = df;
|
dir->files[newhash] = df;
|
||||||
df->name = savestring (d->d_name, len);
|
df->name = savestring (d->d_name, len);
|
||||||
df->impossible = 0;
|
df->impossible = 0;
|
||||||
|
|
||||||
/* Check if the name matches the one we're searching for. */
|
/* Check if the name matches the one we're searching for. */
|
||||||
if (filename != 0
|
if (filename != 0
|
||||||
&& newhash == hash && streq (d->d_name, filename))
|
&& newhash == hash && streq (d->d_name, filename))
|
||||||
return 1;
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the directory has been completely read in,
|
/* If the directory has been completely read in,
|
||||||
@ -324,7 +436,6 @@ dir_contents_file_exists_p (dir, filename)
|
|||||||
closedir (dir->dirstream);
|
closedir (dir->dirstream);
|
||||||
dir->dirstream = 0;
|
dir->dirstream = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,9 +466,16 @@ file_exists_p (name)
|
|||||||
return ar_member_date (name) != (time_t) -1;
|
return ar_member_date (name) != (time_t) -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
dirend = rindex (name, ']');
|
||||||
|
dirend++;
|
||||||
|
if (dirend == (char *)1)
|
||||||
|
return dir_file_exists_p ("[]", name);
|
||||||
|
#else
|
||||||
dirend = rindex (name, '/');
|
dirend = rindex (name, '/');
|
||||||
if (dirend == 0)
|
if (dirend == 0)
|
||||||
return dir_file_exists_p (".", name);
|
return dir_file_exists_p (".", name);
|
||||||
|
#endif
|
||||||
|
|
||||||
dirname = (char *) alloca (dirend - name + 1);
|
dirname = (char *) alloca (dirend - name + 1);
|
||||||
bcopy (name, dirname, dirend - name);
|
bcopy (name, dirname, dirend - name);
|
||||||
@ -379,9 +497,16 @@ file_impossible (filename)
|
|||||||
register struct directory *dir;
|
register struct directory *dir;
|
||||||
register struct dirfile *new;
|
register struct dirfile *new;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
dirend = rindex (p, ']');
|
||||||
|
dirend++;
|
||||||
|
if (dirend == (char *)1)
|
||||||
|
dir = find_directory ("[]");
|
||||||
|
#else
|
||||||
dirend = rindex (p, '/');
|
dirend = rindex (p, '/');
|
||||||
if (dirend == 0)
|
if (dirend == 0)
|
||||||
dir = find_directory (".");
|
dir = find_directory (".");
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *dirname = (char *) alloca (dirend - p + 1);
|
char *dirname = (char *) alloca (dirend - p + 1);
|
||||||
@ -401,7 +526,13 @@ file_impossible (filename)
|
|||||||
structure for it, but leave it out of the contents hash table. */
|
structure for it, but leave it out of the contents hash table. */
|
||||||
dir->contents = (struct directory_contents *)
|
dir->contents = (struct directory_contents *)
|
||||||
xmalloc (sizeof (struct directory_contents));
|
xmalloc (sizeof (struct directory_contents));
|
||||||
|
#ifdef VMS
|
||||||
|
dir->contents->dev = 0;
|
||||||
|
dir->contents->ino[0] = dir->contents->ino[1] =
|
||||||
|
dir->contents->ino[2] = 0;
|
||||||
|
#else
|
||||||
dir->contents->dev = dir->contents->ino = 0;
|
dir->contents->dev = dir->contents->ino = 0;
|
||||||
|
#endif
|
||||||
dir->contents->files = 0;
|
dir->contents->files = 0;
|
||||||
dir->contents->dirstream = 0;
|
dir->contents->dirstream = 0;
|
||||||
}
|
}
|
||||||
@ -436,9 +567,15 @@ file_impossible_p (filename)
|
|||||||
register struct directory_contents *dir;
|
register struct directory_contents *dir;
|
||||||
register struct dirfile *next;
|
register struct dirfile *next;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
dirend = rindex (filename, ']');
|
||||||
|
if (dirend == 0)
|
||||||
|
dir = find_directory ("[]")->contents;
|
||||||
|
#else
|
||||||
dirend = rindex (filename, '/');
|
dirend = rindex (filename, '/');
|
||||||
if (dirend == 0)
|
if (dirend == 0)
|
||||||
dir = find_directory (".")->contents;
|
dir = find_directory (".")->contents;
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *dirname = (char *) alloca (dirend - filename + 1);
|
char *dirname = (char *) alloca (dirend - filename + 1);
|
||||||
@ -455,6 +592,9 @@ file_impossible_p (filename)
|
|||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
p = filename = dosify (p);
|
p = filename = dosify (p);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VMS
|
||||||
|
p = filename = vmsify (p, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (hash = 0; *p != '\0'; ++p)
|
for (hash = 0; *p != '\0'; ++p)
|
||||||
HASH (hash, *p);
|
HASH (hash, *p);
|
||||||
@ -495,8 +635,15 @@ print_dir_data_base ()
|
|||||||
if (dir->contents == 0)
|
if (dir->contents == 0)
|
||||||
printf ("# %s: could not be stat'd.\n", dir->name);
|
printf ("# %s: could not be stat'd.\n", dir->name);
|
||||||
else if (dir->contents->files == 0)
|
else if (dir->contents->files == 0)
|
||||||
|
#ifdef VMS
|
||||||
|
printf ("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n",
|
||||||
|
dir->name, dir->contents->dev,
|
||||||
|
dir->contents->ino[0], dir->contents->ino[1],
|
||||||
|
dir->contents->ino[2]);
|
||||||
|
#else
|
||||||
printf ("# %s (device %d, inode %d): could not be opened.\n",
|
printf ("# %s (device %d, inode %d): could not be opened.\n",
|
||||||
dir->name, dir->contents->dev, dir->contents->ino);
|
dir->name, dir->contents->dev, dir->contents->ino);
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
register unsigned int f = 0, im = 0;
|
register unsigned int f = 0, im = 0;
|
||||||
@ -508,8 +655,15 @@ print_dir_data_base ()
|
|||||||
++im;
|
++im;
|
||||||
else
|
else
|
||||||
++f;
|
++f;
|
||||||
|
#ifdef VMS
|
||||||
|
printf ("# %s (device %d, inode [%d,%d,%d]): ",
|
||||||
|
dir->name, dir->contents->dev,
|
||||||
|
dir->contents->ino[0], dir->contents->ino[1],
|
||||||
|
dir->contents->ino[2]);
|
||||||
|
#else
|
||||||
printf ("# %s (device %d, inode %d): ",
|
printf ("# %s (device %d, inode %d): ",
|
||||||
dir->name, dir->contents->dev, dir->contents->ino);
|
dir->name, dir->contents->dev, dir->contents->ino);
|
||||||
|
#endif
|
||||||
if (f == 0)
|
if (f == 0)
|
||||||
fputs ("No", stdout);
|
fputs ("No", stdout);
|
||||||
else
|
else
|
||||||
@ -557,15 +711,15 @@ struct dirstream
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Forward declarations. */
|
/* Forward declarations. */
|
||||||
static __ptr_t open_dirstream __P ((const char *));
|
static __ptr_t open_dirstream PARAMS ((const char *));
|
||||||
static struct dirent *read_dirstream __P ((__ptr_t));
|
static struct dirent *read_dirstream PARAMS ((__ptr_t));
|
||||||
|
|
||||||
static __ptr_t
|
static __ptr_t
|
||||||
open_dirstream (directory)
|
open_dirstream (directory)
|
||||||
const char *directory;
|
const char *directory;
|
||||||
{
|
{
|
||||||
struct dirstream *new;
|
struct dirstream *new;
|
||||||
struct directory *dir = find_directory (directory);
|
struct directory *dir = find_directory ((char *)directory);
|
||||||
|
|
||||||
if (dir->contents == 0 || dir->contents->files == 0)
|
if (dir->contents == 0 || dir->contents->files == 0)
|
||||||
/* DIR->contents is nil if the directory could not be stat'd.
|
/* DIR->contents is nil if the directory could not be stat'd.
|
||||||
|
3
expand.c
3
expand.c
@ -17,8 +17,9 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
|
#include "filedef.h"
|
||||||
|
#include "job.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "file.h"
|
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
/* The next two describe the variable output buffer.
|
/* The next two describe the variable output buffer.
|
||||||
|
55
file.c
55
file.c
@ -17,9 +17,10 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
|
#include "job.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@ -55,6 +56,10 @@ lookup_file (name)
|
|||||||
/* This is also done in parse_file_seq, so this is redundant
|
/* This is also done in parse_file_seq, so this is redundant
|
||||||
for names read from makefiles. It is here for names passed
|
for names read from makefiles. It is here for names passed
|
||||||
on the command line. */
|
on the command line. */
|
||||||
|
#ifdef VMS
|
||||||
|
while (name[0] == '[' && name[1] == ']' && name[2] != '\0')
|
||||||
|
name += 2;
|
||||||
|
#endif
|
||||||
while (name[0] == '.' && name[1] == '/' && name[2] != '\0')
|
while (name[0] == '.' && name[1] == '/' && name[2] != '\0')
|
||||||
{
|
{
|
||||||
name += 2;
|
name += 2;
|
||||||
@ -65,7 +70,11 @@ lookup_file (name)
|
|||||||
|
|
||||||
if (*name == '\0')
|
if (*name == '\0')
|
||||||
/* It was all slashes after a dot. */
|
/* It was all slashes after a dot. */
|
||||||
|
#ifdef VMS
|
||||||
|
name = "[]";
|
||||||
|
#else
|
||||||
name = "./";
|
name = "./";
|
||||||
|
#endif
|
||||||
|
|
||||||
hashval = 0;
|
hashval = 0;
|
||||||
for (n = name; *n != '\0'; ++n)
|
for (n = name; *n != '\0'; ++n)
|
||||||
@ -73,8 +82,12 @@ lookup_file (name)
|
|||||||
hashval %= FILE_BUCKETS;
|
hashval %= FILE_BUCKETS;
|
||||||
|
|
||||||
for (f = files[hashval]; f != 0; f = f->next)
|
for (f = files[hashval]; f != 0; f = f->next)
|
||||||
if (streq (f->name, name))
|
{
|
||||||
return f;
|
if (streq (f->name, name))
|
||||||
|
{
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,10 +98,26 @@ enter_file (name)
|
|||||||
register struct file *f, *new;
|
register struct file *f, *new;
|
||||||
register char *n;
|
register char *n;
|
||||||
register unsigned int hashval;
|
register unsigned int hashval;
|
||||||
|
#ifdef VMS
|
||||||
|
char *lname, *ln;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (*name == '\0')
|
if (*name == '\0')
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
lname = (char *)malloc (strlen (name) + 1);
|
||||||
|
for (n = name, ln = lname; *n != '\0'; ++n, ++ln)
|
||||||
|
{
|
||||||
|
if (isupper(*n))
|
||||||
|
*ln = tolower(*n);
|
||||||
|
else
|
||||||
|
*ln = *n;
|
||||||
|
}
|
||||||
|
*ln = 0;
|
||||||
|
name = lname;
|
||||||
|
#endif
|
||||||
|
|
||||||
hashval = 0;
|
hashval = 0;
|
||||||
for (n = name; *n != '\0'; ++n)
|
for (n = name; *n != '\0'; ++n)
|
||||||
HASH (hashval, *n);
|
HASH (hashval, *n);
|
||||||
@ -99,7 +128,12 @@ enter_file (name)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (f != 0 && !f->double_colon)
|
if (f != 0 && !f->double_colon)
|
||||||
return f;
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
free(lname);
|
||||||
|
#endif
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
new = (struct file *) xmalloc (sizeof (struct file));
|
new = (struct file *) xmalloc (sizeof (struct file));
|
||||||
bzero ((char *) new, sizeof (struct file));
|
bzero ((char *) new, sizeof (struct file));
|
||||||
@ -477,7 +511,9 @@ print_file (f)
|
|||||||
struct file *f;
|
struct file *f;
|
||||||
{
|
{
|
||||||
register struct dep *d;
|
register struct dep *d;
|
||||||
|
#ifdef VMS
|
||||||
|
extern char *cvt_time PARAMS ((unsigned long));
|
||||||
|
#endif
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
if (!f->is_target)
|
if (!f->is_target)
|
||||||
puts ("# Not a target:");
|
puts ("# Not a target:");
|
||||||
@ -513,8 +549,13 @@ print_file (f)
|
|||||||
else if (f->last_mtime == (time_t) -1)
|
else if (f->last_mtime == (time_t) -1)
|
||||||
puts ("# File does not exist.");
|
puts ("# File does not exist.");
|
||||||
else
|
else
|
||||||
|
#ifdef VMS
|
||||||
|
printf ("# Last modified %.24s (%0lx)\n",
|
||||||
|
cvt_time(f->last_mtime), (unsigned long) f->last_mtime);
|
||||||
|
#else
|
||||||
printf ("# Last modified %.24s (%ld)\n",
|
printf ("# Last modified %.24s (%ld)\n",
|
||||||
ctime (&f->last_mtime), (long int) f->last_mtime);
|
ctime (&f->last_mtime), (long int) f->last_mtime);
|
||||||
|
#endif
|
||||||
printf ("# File has%s been updated.\n",
|
printf ("# File has%s been updated.\n",
|
||||||
f->updated ? "" : " not");
|
f->updated ? "" : " not");
|
||||||
switch (f->command_state)
|
switch (f->command_state)
|
||||||
@ -601,3 +642,5 @@ print_file_data_base ()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
120
filedef.h
Normal file
120
filedef.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* Definition of target file data structures for GNU Make.
|
||||||
|
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||||
|
This file is part of GNU Make.
|
||||||
|
|
||||||
|
GNU Make is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GNU Make is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* Structure that represents the info on one file
|
||||||
|
that the makefile says how to make.
|
||||||
|
All of these are chained together through `next'. */
|
||||||
|
|
||||||
|
struct file
|
||||||
|
{
|
||||||
|
struct file *next;
|
||||||
|
char *name;
|
||||||
|
struct dep *deps;
|
||||||
|
struct commands *cmds; /* Commands to execute for this target. */
|
||||||
|
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
|
||||||
|
char *stem; /* Implicit stem, if an implicit
|
||||||
|
rule has been used */
|
||||||
|
struct dep *also_make; /* Targets that are made by making this. */
|
||||||
|
time_t last_mtime; /* File's modtime, if already known. */
|
||||||
|
struct file *prev; /* Previous entry for same file name;
|
||||||
|
used when there are multiple double-colon
|
||||||
|
entries for the same file. */
|
||||||
|
|
||||||
|
/* File that this file was renamed to. After any time that a
|
||||||
|
file could be renamed, call `check_renamed' (below). */
|
||||||
|
struct file *renamed;
|
||||||
|
|
||||||
|
/* List of variable sets used for this file. */
|
||||||
|
struct variable_set_list *variables;
|
||||||
|
|
||||||
|
/* Immediate dependent that caused this target to be remade,
|
||||||
|
or nil if there isn't one. */
|
||||||
|
struct file *parent;
|
||||||
|
|
||||||
|
/* For a double-colon entry, this is the first double-colon entry for
|
||||||
|
the same file. Otherwise this is null. */
|
||||||
|
struct file *double_colon;
|
||||||
|
|
||||||
|
short int update_status; /* Status of the last attempt to update,
|
||||||
|
or -1 if none has been made. */
|
||||||
|
|
||||||
|
enum /* State of the commands. */
|
||||||
|
{ /* Note: It is important that cs_not_started be zero. */
|
||||||
|
cs_not_started, /* Not yet started. */
|
||||||
|
cs_deps_running, /* Dep commands running. */
|
||||||
|
cs_running, /* Commands running. */
|
||||||
|
cs_finished /* Commands finished. */
|
||||||
|
} command_state ENUM_BITFIELD (2);
|
||||||
|
|
||||||
|
unsigned int precious:1; /* Non-0 means don't delete file on quit */
|
||||||
|
unsigned int tried_implicit:1; /* Nonzero if have searched
|
||||||
|
for implicit rule for making
|
||||||
|
this file; don't search again. */
|
||||||
|
unsigned int updating:1; /* Nonzero while updating deps of this file */
|
||||||
|
unsigned int updated:1; /* Nonzero if this file has been remade. */
|
||||||
|
unsigned int is_target:1; /* Nonzero if file is described as target. */
|
||||||
|
unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */
|
||||||
|
unsigned int phony:1; /* Nonzero if this is a phony file
|
||||||
|
i.e., a dependency of .PHONY. */
|
||||||
|
unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */
|
||||||
|
/* Nonzero, for an intermediate file,
|
||||||
|
means remove_intermediates should not delete it. */
|
||||||
|
unsigned int secondary:1;
|
||||||
|
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
|
||||||
|
this target cannot be remade. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Number of intermediate files entered. */
|
||||||
|
|
||||||
|
extern unsigned int num_intermediates;
|
||||||
|
|
||||||
|
extern struct file *default_goal_file, *suffix_file, *default_file;
|
||||||
|
|
||||||
|
|
||||||
|
extern struct file *lookup_file (), *enter_file ();
|
||||||
|
extern void remove_intermediates (), snap_deps ();
|
||||||
|
extern void rename_file (), file_hash_enter ();
|
||||||
|
extern void set_command_state ();
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the mtime of file F (a struct file *), caching it.
|
||||||
|
The value is -1 if the file does not exist. */
|
||||||
|
#define file_mtime(f) file_mtime_1 ((f), 1)
|
||||||
|
/* Return the mtime of file F (a struct file *), caching it.
|
||||||
|
Don't search using vpath for the file--if it doesn't actually exist,
|
||||||
|
we don't find it.
|
||||||
|
The value is -1 if the file does not exist. */
|
||||||
|
#define file_mtime_no_search(f) file_mtime_1 ((f), 0)
|
||||||
|
extern time_t f_mtime ();
|
||||||
|
#define file_mtime_1(f, v) \
|
||||||
|
((f)->last_mtime != (time_t) 0 ? (f)->last_mtime : f_mtime ((f), v))
|
||||||
|
|
||||||
|
/* Modtime value to use for `infinitely new'. We used to get the current time
|
||||||
|
from the system and use that whenever we wanted `new'. But that causes
|
||||||
|
trouble when the machine running make and the machine holding a file have
|
||||||
|
different ideas about what time it is; and can also lose for `force'
|
||||||
|
targets, which need to be considered newer than anything that depends on
|
||||||
|
them, even if said dependents' modtimes are in the future.
|
||||||
|
|
||||||
|
NOTE: This assumes 32-bit `time_t's, but I cannot think of a portable way
|
||||||
|
to produce the largest representable integer of a given signed type. */
|
||||||
|
#define NEW_MTIME ((time_t) 0x7fffffff)
|
||||||
|
|
||||||
|
|
||||||
|
#define check_renamed(file) \
|
||||||
|
while ((file)->renamed != 0) (file) = (file)->renamed /* No ; here. */
|
98
function.c
98
function.c
@ -17,17 +17,18 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
|
#include "filedef.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "job.h"
|
#include "job.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *string_glob ();
|
static char *string_glob PARAMS ((char *line));
|
||||||
|
|
||||||
/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
|
/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
|
||||||
each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
|
each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
|
||||||
@ -35,7 +36,7 @@ static char *string_glob ();
|
|||||||
nonzero, substitutions are done only on matches which are complete
|
nonzero, substitutions are done only on matches which are complete
|
||||||
whitespace-delimited words. If SUFFIX_ONLY is nonzero, substitutions are
|
whitespace-delimited words. If SUFFIX_ONLY is nonzero, substitutions are
|
||||||
done only at the ends of whitespace-delimited words. */
|
done only at the ends of whitespace-delimited words. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only)
|
subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only)
|
||||||
char *o;
|
char *o;
|
||||||
@ -337,7 +338,8 @@ expand_function (o, function, text, end)
|
|||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef VMS /* not supported for vms yet */
|
||||||
case function_shell:
|
case function_shell:
|
||||||
{
|
{
|
||||||
char **argv, **envp;
|
char **argv, **envp;
|
||||||
@ -349,12 +351,13 @@ expand_function (o, function, text, end)
|
|||||||
text = expand_argument (text, end);
|
text = expand_argument (text, end);
|
||||||
|
|
||||||
/* Construct the argument list. */
|
/* Construct the argument list. */
|
||||||
argv = construct_command_argv (text, (char *) NULL, (struct file *) 0);
|
argv = construct_command_argv (text,
|
||||||
|
(char **) NULL, (struct file *) 0);
|
||||||
if (argv == 0)
|
if (argv == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Using a target environment for `shell' loses in cases like:
|
/* Using a target environment for `shell' loses in cases like:
|
||||||
export var = $(shell echo foobie)
|
export var = $(shell echo foobie)
|
||||||
because target_environment hits a loop trying to expand $(var)
|
because target_environment hits a loop trying to expand $(var)
|
||||||
to put it in the environment. This is even more confusing when
|
to put it in the environment. This is even more confusing when
|
||||||
var was not explicitly exported, but just appeared in the
|
var was not explicitly exported, but just appeared in the
|
||||||
@ -498,7 +501,7 @@ expand_function (o, function, text, end)
|
|||||||
unsigned int maxlen = 200;
|
unsigned int maxlen = 200;
|
||||||
int cc;
|
int cc;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
strcpy (tmp_output, "shXXXXXX");
|
strcpy (tmp_output, "shXXXXXX");
|
||||||
mktemp (tmp_output);
|
mktemp (tmp_output);
|
||||||
child_stdout = open (tmp_output,
|
child_stdout = open (tmp_output,
|
||||||
@ -509,9 +512,9 @@ expand_function (o, function, text, end)
|
|||||||
dup2 (save_stdout, 1);
|
dup2 (save_stdout, 1);
|
||||||
close (child_stdout);
|
close (child_stdout);
|
||||||
close (save_stdout);
|
close (save_stdout);
|
||||||
|
|
||||||
child_stdout = open (tmp_output, O_RDONLY|O_TEXT, 0644);
|
child_stdout = open (tmp_output, O_RDONLY|O_TEXT, 0644);
|
||||||
|
|
||||||
buffer = xmalloc (maxlen);
|
buffer = xmalloc (maxlen);
|
||||||
i = 0;
|
i = 0;
|
||||||
do
|
do
|
||||||
@ -521,15 +524,15 @@ expand_function (o, function, text, end)
|
|||||||
maxlen += 512;
|
maxlen += 512;
|
||||||
buffer = (char *) xrealloc (buffer, maxlen + 1);
|
buffer = (char *) xrealloc (buffer, maxlen + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc = read (child_stdout, &buffer[i], maxlen - i);
|
cc = read (child_stdout, &buffer[i], maxlen - i);
|
||||||
if (cc > 0)
|
if (cc > 0)
|
||||||
i += cc;
|
i += cc;
|
||||||
} while (cc > 0);
|
} while (cc > 0);
|
||||||
|
|
||||||
close (child_stdout);
|
close (child_stdout);
|
||||||
unlink (tmp_output);
|
unlink (tmp_output);
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
if (buffer[i - 1] == '\n')
|
if (buffer[i - 1] == '\n')
|
||||||
@ -548,6 +551,7 @@ expand_function (o, function, text, end)
|
|||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
case function_origin:
|
case function_origin:
|
||||||
/* Expand the argument. */
|
/* Expand the argument. */
|
||||||
@ -590,7 +594,7 @@ expand_function (o, function, text, end)
|
|||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_sort:
|
case function_sort:
|
||||||
/* Expand the argument. */
|
/* Expand the argument. */
|
||||||
text = expand_argument (text, end);
|
text = expand_argument (text, end);
|
||||||
@ -610,7 +614,7 @@ expand_function (o, function, text, end)
|
|||||||
nwords *= 2;
|
nwords *= 2;
|
||||||
words = (char **) xrealloc ((char *) words,
|
words = (char **) xrealloc ((char *) words,
|
||||||
nwords * sizeof (char *));
|
nwords * sizeof (char *));
|
||||||
}
|
}
|
||||||
words[wordi++] = savestring (p, len);
|
words[wordi++] = savestring (p, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,7 +644,7 @@ expand_function (o, function, text, end)
|
|||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_foreach:
|
case function_foreach:
|
||||||
{
|
{
|
||||||
/* Get three comma-separated arguments but
|
/* Get three comma-separated arguments but
|
||||||
@ -733,7 +737,7 @@ expand_function (o, function, text, end)
|
|||||||
if (p == end)
|
if (p == end)
|
||||||
BADARGS (function == function_filter ? "filter" : "filter-out");
|
BADARGS (function == function_filter ? "filter" : "filter-out");
|
||||||
p2 = expand_argument (text, p);
|
p2 = expand_argument (text, p);
|
||||||
|
|
||||||
text = expand_argument (p + 1, end);
|
text = expand_argument (p + 1, end);
|
||||||
|
|
||||||
/* Chop TEXT up into words and then run each pattern through. */
|
/* Chop TEXT up into words and then run each pattern through. */
|
||||||
@ -792,7 +796,7 @@ expand_function (o, function, text, end)
|
|||||||
free (text);
|
free (text);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_patsubst:
|
case function_patsubst:
|
||||||
/* Get three comma-separated arguments and expand each one. */
|
/* Get three comma-separated arguments and expand each one. */
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -825,9 +829,9 @@ expand_function (o, function, text, end)
|
|||||||
text = expand_argument (text, p2);
|
text = expand_argument (text, p2);
|
||||||
p3 = expand_argument (p2 + 1, p);
|
p3 = expand_argument (p2 + 1, p);
|
||||||
p2 = expand_argument (p + 1, end);
|
p2 = expand_argument (p + 1, end);
|
||||||
|
|
||||||
o = patsubst_expand (o, p2, text, p3, (char *) 0, (char *) 0);
|
o = patsubst_expand (o, p2, text, p3, (char *) 0, (char *) 0);
|
||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
free (p3);
|
free (p3);
|
||||||
free (p2);
|
free (p2);
|
||||||
@ -850,7 +854,7 @@ expand_function (o, function, text, end)
|
|||||||
text = expand_argument (text, p);
|
text = expand_argument (text, p);
|
||||||
|
|
||||||
p = expand_argument (p + 1, end);
|
p = expand_argument (p + 1, end);
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Write each word of the first argument directly followed
|
/* Write each word of the first argument directly followed
|
||||||
by the corresponding word of the second argument.
|
by the corresponding word of the second argument.
|
||||||
@ -866,11 +870,11 @@ expand_function (o, function, text, end)
|
|||||||
tp = find_next_token (&p2, &tlen);
|
tp = find_next_token (&p2, &tlen);
|
||||||
if (tp != 0)
|
if (tp != 0)
|
||||||
o = variable_buffer_output (o, tp, tlen);
|
o = variable_buffer_output (o, tp, tlen);
|
||||||
|
|
||||||
pp = find_next_token (&p3, &plen);
|
pp = find_next_token (&p3, &plen);
|
||||||
if (pp != 0)
|
if (pp != 0)
|
||||||
o = variable_buffer_output (o, pp, plen);
|
o = variable_buffer_output (o, pp, plen);
|
||||||
|
|
||||||
if (tp != 0 || pp != 0)
|
if (tp != 0 || pp != 0)
|
||||||
{
|
{
|
||||||
o = variable_buffer_output (o, " ", 1);
|
o = variable_buffer_output (o, " ", 1);
|
||||||
@ -882,11 +886,11 @@ expand_function (o, function, text, end)
|
|||||||
/* Kill the last blank. */
|
/* Kill the last blank. */
|
||||||
--o;
|
--o;
|
||||||
}
|
}
|
||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
free (p);
|
free (p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_strip:
|
case function_strip:
|
||||||
/* Expand the argument. */
|
/* Expand the argument. */
|
||||||
text = expand_argument (text, end);
|
text = expand_argument (text, end);
|
||||||
@ -901,19 +905,19 @@ expand_function (o, function, text, end)
|
|||||||
if (doneany)
|
if (doneany)
|
||||||
/* Kill the last space. */
|
/* Kill the last space. */
|
||||||
--o;
|
--o;
|
||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_wildcard:
|
case function_wildcard:
|
||||||
text = expand_argument (text, end);
|
text = expand_argument (text, end);
|
||||||
|
|
||||||
p = string_glob (text);
|
p = string_glob (text);
|
||||||
o = variable_buffer_output (o, p, strlen (p));
|
o = variable_buffer_output (o, p, strlen (p));
|
||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_subst:
|
case function_subst:
|
||||||
/* Get three comma-separated arguments and expand each one. */
|
/* Get three comma-separated arguments and expand each one. */
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -946,14 +950,14 @@ expand_function (o, function, text, end)
|
|||||||
text = expand_argument (text, p2);
|
text = expand_argument (text, p2);
|
||||||
p3 = expand_argument (p2 + 1, p);
|
p3 = expand_argument (p2 + 1, p);
|
||||||
p2 = expand_argument (p + 1, end);
|
p2 = expand_argument (p + 1, end);
|
||||||
|
|
||||||
o = subst_expand (o, p2, text, p3, strlen (text), strlen (p3), 0, 0);
|
o = subst_expand (o, p2, text, p3, strlen (text), strlen (p3), 0, 0);
|
||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
free (p3);
|
free (p3);
|
||||||
free (p2);
|
free (p2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_firstword:
|
case function_firstword:
|
||||||
/* Expand the argument. */
|
/* Expand the argument. */
|
||||||
text = expand_argument (text, end);
|
text = expand_argument (text, end);
|
||||||
@ -963,10 +967,10 @@ expand_function (o, function, text, end)
|
|||||||
p = find_next_token (&p2, &i);
|
p = find_next_token (&p2, &i);
|
||||||
if (p != 0)
|
if (p != 0)
|
||||||
o = variable_buffer_output (o, p, i);
|
o = variable_buffer_output (o, p, i);
|
||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_word:
|
case function_word:
|
||||||
/* Get two comma-separated arguments and expand each one. */
|
/* Get two comma-separated arguments and expand each one. */
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -1058,11 +1062,11 @@ index argument");
|
|||||||
i = strlen (text);
|
i = strlen (text);
|
||||||
if (sindex (p, 0, text, i) != 0)
|
if (sindex (p, 0, text, i) != 0)
|
||||||
o = variable_buffer_output (o, text, i);
|
o = variable_buffer_output (o, text, i);
|
||||||
|
|
||||||
free (p);
|
free (p);
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_addsuffix:
|
case function_addsuffix:
|
||||||
case function_addprefix:
|
case function_addprefix:
|
||||||
/* Get two comma-separated arguments and expand each one. */
|
/* Get two comma-separated arguments and expand each one. */
|
||||||
@ -1082,7 +1086,7 @@ index argument");
|
|||||||
i = strlen (text);
|
i = strlen (text);
|
||||||
|
|
||||||
p2 = expand_argument (p + 1, end);
|
p2 = expand_argument (p + 1, end);
|
||||||
|
|
||||||
p3 = p2;
|
p3 = p2;
|
||||||
while ((p = find_next_token (&p3, &len)) != 0)
|
while ((p = find_next_token (&p3, &len)) != 0)
|
||||||
{
|
{
|
||||||
@ -1097,11 +1101,11 @@ index argument");
|
|||||||
if (doneany)
|
if (doneany)
|
||||||
/* Kill last space. */
|
/* Kill last space. */
|
||||||
--o;
|
--o;
|
||||||
|
|
||||||
free (p2);
|
free (p2);
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_dir:
|
case function_dir:
|
||||||
case function_basename:
|
case function_basename:
|
||||||
/* Expand the argument. */
|
/* Expand the argument. */
|
||||||
@ -1111,7 +1115,11 @@ index argument");
|
|||||||
while ((p2 = find_next_token (&p3, &len)) != 0)
|
while ((p2 = find_next_token (&p3, &len)) != 0)
|
||||||
{
|
{
|
||||||
p = p2 + len;
|
p = p2 + len;
|
||||||
|
#ifdef VMS
|
||||||
|
while (p >= p2 && *p != (function == function_dir ? ']' : '.'))
|
||||||
|
#else
|
||||||
while (p >= p2 && *p != (function == function_dir ? '/' : '.'))
|
while (p >= p2 && *p != (function == function_dir ? '/' : '.'))
|
||||||
|
#endif
|
||||||
--p;
|
--p;
|
||||||
if (p >= p2)
|
if (p >= p2)
|
||||||
{
|
{
|
||||||
@ -1120,7 +1128,11 @@ index argument");
|
|||||||
o = variable_buffer_output (o, p2, p - p2);
|
o = variable_buffer_output (o, p2, p - p2);
|
||||||
}
|
}
|
||||||
else if (function == function_dir)
|
else if (function == function_dir)
|
||||||
|
#ifdef VMS
|
||||||
|
o = variable_buffer_output (o, "[]", 2);
|
||||||
|
#else
|
||||||
o = variable_buffer_output (o, "./", 2);
|
o = variable_buffer_output (o, "./", 2);
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
/* The entire name is the basename. */
|
/* The entire name is the basename. */
|
||||||
o = variable_buffer_output (o, p2, len);
|
o = variable_buffer_output (o, p2, len);
|
||||||
@ -1131,10 +1143,10 @@ index argument");
|
|||||||
if (doneany)
|
if (doneany)
|
||||||
/* Kill last space. */
|
/* Kill last space. */
|
||||||
--o;
|
--o;
|
||||||
|
|
||||||
free (text);
|
free (text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case function_notdir:
|
case function_notdir:
|
||||||
case function_suffix:
|
case function_suffix:
|
||||||
/* Expand the argument. */
|
/* Expand the argument. */
|
||||||
@ -1144,7 +1156,11 @@ index argument");
|
|||||||
while ((p2 = find_next_token (&p3, &len)) != 0)
|
while ((p2 = find_next_token (&p3, &len)) != 0)
|
||||||
{
|
{
|
||||||
p = p2 + len;
|
p = p2 + len;
|
||||||
|
#ifdef VMS
|
||||||
|
while (p >= p2 && *p != (function == function_notdir ? ']' : '.'))
|
||||||
|
#else
|
||||||
while (p >= p2 && *p != (function == function_notdir ? '/' : '.'))
|
while (p >= p2 && *p != (function == function_notdir ? '/' : '.'))
|
||||||
|
#endif
|
||||||
--p;
|
--p;
|
||||||
if (p >= p2)
|
if (p >= p2)
|
||||||
{
|
{
|
||||||
|
13
implicit.c
13
implicit.c
@ -19,9 +19,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
|
|
||||||
static int pattern_search ();
|
static int pattern_search PARAMS ((struct file *file, int archive, unsigned int depth,
|
||||||
|
unsigned int recursions));
|
||||||
|
|
||||||
/* For a FILE which has no commands specified, try to figure out some
|
/* For a FILE which has no commands specified, try to figure out some
|
||||||
from the implicit pattern rules.
|
from the implicit pattern rules.
|
||||||
@ -162,7 +163,11 @@ pattern_search (file, archive, depth, recursions)
|
|||||||
/* Set LASTSLASH to point at the last slash in FILENAME
|
/* Set LASTSLASH to point at the last slash in FILENAME
|
||||||
but not counting any slash at the end. (foo/bar/ counts as
|
but not counting any slash at the end. (foo/bar/ counts as
|
||||||
bar/ in directory foo/, not empty in directory foo/bar/.) */
|
bar/ in directory foo/, not empty in directory foo/bar/.) */
|
||||||
|
#ifdef VMS
|
||||||
|
lastslash = rindex (filename, ']');
|
||||||
|
#else
|
||||||
lastslash = rindex (filename, '/');
|
lastslash = rindex (filename, '/');
|
||||||
|
#endif
|
||||||
if (lastslash != 0 && lastslash[1] == '\0')
|
if (lastslash != 0 && lastslash[1] == '\0')
|
||||||
lastslash = 0;
|
lastslash = 0;
|
||||||
}
|
}
|
||||||
@ -210,7 +215,11 @@ pattern_search (file, archive, depth, recursions)
|
|||||||
/* Set CHECK_LASTSLASH if FILENAME contains a directory
|
/* Set CHECK_LASTSLASH if FILENAME contains a directory
|
||||||
prefix and the target pattern does not contain a slash. */
|
prefix and the target pattern does not contain a slash. */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
check_lastslash = lastslash != 0 && index (target, ']') == 0;
|
||||||
|
#else
|
||||||
check_lastslash = lastslash != 0 && index (target, '/') == 0;
|
check_lastslash = lastslash != 0 && index (target, '/') == 0;
|
||||||
|
#endif
|
||||||
if (check_lastslash)
|
if (check_lastslash)
|
||||||
{
|
{
|
||||||
/* In that case, don't include the
|
/* In that case, don't include the
|
||||||
|
366
job.c
366
job.c
@ -18,9 +18,9 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "job.h"
|
#include "job.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@ -36,6 +36,13 @@ static char *dos_bename;
|
|||||||
static int dos_batch_file;
|
static int dos_batch_file;
|
||||||
#endif /* MSDOS. */
|
#endif /* MSDOS. */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
#include <time.h>
|
||||||
|
#include <processes.h>
|
||||||
|
#include <starlet.h>
|
||||||
|
#include <lib$routines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#else
|
#else
|
||||||
@ -102,22 +109,40 @@ extern int wait ();
|
|||||||
|
|
||||||
#endif /* Don't have `union wait'. */
|
#endif /* Don't have `union wait'. */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
static int vms_jobsefnmask=0;
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
#ifndef HAVE_UNISTD_H
|
#ifndef HAVE_UNISTD_H
|
||||||
extern int dup2 ();
|
extern int dup2 ();
|
||||||
extern int execve ();
|
extern int execve ();
|
||||||
extern void _exit ();
|
extern void _exit ();
|
||||||
extern int geteuid (), getegid ();
|
#ifndef VMS
|
||||||
extern int setgid (), getgid ();
|
extern int geteuid ();
|
||||||
|
extern int getegid ();
|
||||||
|
extern int setgid ();
|
||||||
|
extern int getgid ();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int getloadavg ();
|
extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file));
|
||||||
extern int start_remote_job_p ();
|
|
||||||
extern int start_remote_job (), remote_status ();
|
|
||||||
|
|
||||||
RETSIGTYPE child_handler ();
|
extern int getloadavg PARAMS ((double loadavg[], int nelem));
|
||||||
static void free_child (), start_job_command ();
|
extern int start_remote_job PARAMS ((char **argv, char **envp, int stdin_fd,
|
||||||
static int load_too_high (), job_next_command ();
|
int *is_remote, int *id_ptr, int *used_stdin));
|
||||||
|
extern int start_remote_job_p PARAMS ((void));
|
||||||
|
extern int remote_status PARAMS ((int *exit_code_ptr, int *signal_ptr,
|
||||||
|
int *coredump_ptr, int block));
|
||||||
|
|
||||||
|
RETSIGTYPE child_handler PARAMS ((int));
|
||||||
|
static void free_child PARAMS ((struct child *));
|
||||||
|
static void start_job_command PARAMS ((struct child *child));
|
||||||
|
static int load_too_high PARAMS ((void));
|
||||||
|
static int job_next_command PARAMS ((struct child *));
|
||||||
|
static int start_waiting_job PARAMS ((struct child *));
|
||||||
|
#ifdef VMS
|
||||||
|
static void vmsWaitForChildren PARAMS ((int *));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Chain of all live (or recently deceased) children. */
|
/* Chain of all live (or recently deceased) children. */
|
||||||
|
|
||||||
@ -148,6 +173,10 @@ child_error (target_name, exit_code, exit_sig, coredump, ignored)
|
|||||||
if (ignored && silent_flag)
|
if (ignored && silent_flag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
if (!(exit_code & 1))
|
||||||
|
error("*** [%s] Error 0x%x%s", target_name, exit_code, ((ignored)? " (ignored)" : ""));
|
||||||
|
#else
|
||||||
if (exit_sig == 0)
|
if (exit_sig == 0)
|
||||||
error (ignored ? "[%s] Error %d (ignored)" :
|
error (ignored ? "[%s] Error %d (ignored)" :
|
||||||
"*** [%s] Error %d",
|
"*** [%s] Error %d",
|
||||||
@ -156,10 +185,31 @@ child_error (target_name, exit_code, exit_sig, coredump, ignored)
|
|||||||
error ("*** [%s] %s%s",
|
error ("*** [%s] %s%s",
|
||||||
target_name, strsignal (exit_sig),
|
target_name, strsignal (exit_sig),
|
||||||
coredump ? " (core dumped)" : "");
|
coredump ? " (core dumped)" : "");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int dead_children = 0;
|
static unsigned int dead_children = 0;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
/* Wait for nchildren children to terminate */
|
||||||
|
static void
|
||||||
|
vmsWaitForChildren(int *status)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!vms_jobsefnmask)
|
||||||
|
{
|
||||||
|
*status = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*status = sys$wflor (32, vms_jobsefnmask);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Notice that a child died.
|
/* Notice that a child died.
|
||||||
reap_children should be called when convenient. */
|
reap_children should be called when convenient. */
|
||||||
RETSIGTYPE
|
RETSIGTYPE
|
||||||
@ -215,7 +265,7 @@ reap_children (block, err)
|
|||||||
and we might print the "Waiting for unfinished jobs" message above
|
and we might print the "Waiting for unfinished jobs" message above
|
||||||
when not necessary. */
|
when not necessary. */
|
||||||
|
|
||||||
if (dead_children != 0)
|
if (dead_children > 0)
|
||||||
--dead_children;
|
--dead_children;
|
||||||
|
|
||||||
any_remote = 0;
|
any_remote = 0;
|
||||||
@ -228,6 +278,9 @@ reap_children (block, err)
|
|||||||
printf ("Live child 0x%08lx PID %d%s\n",
|
printf ("Live child 0x%08lx PID %d%s\n",
|
||||||
(unsigned long int) c,
|
(unsigned long int) c,
|
||||||
c->pid, c->remote ? " (remote)" : "");
|
c->pid, c->remote ? " (remote)" : "");
|
||||||
|
#ifdef VMS
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First, check for remote children. */
|
/* First, check for remote children. */
|
||||||
@ -235,6 +288,7 @@ reap_children (block, err)
|
|||||||
pid = remote_status (&exit_code, &exit_sig, &coredump, 0);
|
pid = remote_status (&exit_code, &exit_sig, &coredump, 0);
|
||||||
else
|
else
|
||||||
pid = 0;
|
pid = 0;
|
||||||
|
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
{
|
{
|
||||||
remote_status_lose:
|
remote_status_lose:
|
||||||
@ -251,19 +305,24 @@ reap_children (block, err)
|
|||||||
|
|
||||||
if (any_local)
|
if (any_local)
|
||||||
{
|
{
|
||||||
#ifdef WAIT_NOHANG
|
#ifdef VMS
|
||||||
|
vmsWaitForChildren (&status);
|
||||||
|
pid = c->pid;
|
||||||
|
#else
|
||||||
|
#ifdef WAIT_NOHANG
|
||||||
if (!block)
|
if (!block)
|
||||||
pid = WAIT_NOHANG (&status);
|
pid = WAIT_NOHANG (&status);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
pid = wait (&status);
|
pid = wait (&status);
|
||||||
|
#endif /* !VMS */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pid = 0;
|
pid = 0;
|
||||||
|
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
{
|
{
|
||||||
#ifdef EINTR
|
#ifdef EINTR
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
@ -442,7 +501,8 @@ reap_children (block, err)
|
|||||||
free_child (c);
|
free_child (c);
|
||||||
|
|
||||||
/* There is now another slot open. */
|
/* There is now another slot open. */
|
||||||
--job_slots_used;
|
if (job_slots_used > 0)
|
||||||
|
--job_slots_used;
|
||||||
|
|
||||||
/* If the job failed, and the -k flag was not given, die,
|
/* If the job failed, and the -k flag was not given, die,
|
||||||
unless we are already in the process of dying. */
|
unless we are already in the process of dying. */
|
||||||
@ -453,6 +513,7 @@ reap_children (block, err)
|
|||||||
/* Only block for one child. */
|
/* Only block for one child. */
|
||||||
block = 0;
|
block = 0;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the storage allocated for CHILD. */
|
/* Free the storage allocated for CHILD. */
|
||||||
@ -514,7 +575,11 @@ start_job_command (child)
|
|||||||
static int bad_stdin = -1;
|
static int bad_stdin = -1;
|
||||||
register char *p;
|
register char *p;
|
||||||
int flags;
|
int flags;
|
||||||
|
#ifdef VMS
|
||||||
|
char *argv;
|
||||||
|
#else
|
||||||
char **argv;
|
char **argv;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Combine the flags parsed for the line itself with
|
/* Combine the flags parsed for the line itself with
|
||||||
the flags specified globally for this target. */
|
the flags specified globally for this target. */
|
||||||
@ -523,6 +588,7 @@ start_job_command (child)
|
|||||||
|
|
||||||
p = child->command_ptr;
|
p = child->command_ptr;
|
||||||
child->noerror = flags & COMMANDS_NOERROR;
|
child->noerror = flags & COMMANDS_NOERROR;
|
||||||
|
|
||||||
while (*p != '\0')
|
while (*p != '\0')
|
||||||
{
|
{
|
||||||
if (*p == '@')
|
if (*p == '@')
|
||||||
@ -553,8 +619,12 @@ start_job_command (child)
|
|||||||
/* Figure out an argument list from this command line. */
|
/* Figure out an argument list from this command line. */
|
||||||
|
|
||||||
{
|
{
|
||||||
char *end;
|
char *end = 0;
|
||||||
|
#ifdef VMS
|
||||||
|
argv = p;
|
||||||
|
#else
|
||||||
argv = construct_command_argv (p, &end, child->file);
|
argv = construct_command_argv (p, &end, child->file);
|
||||||
|
#endif
|
||||||
if (end == NULL)
|
if (end == NULL)
|
||||||
child->command_ptr = NULL;
|
child->command_ptr = NULL;
|
||||||
else
|
else
|
||||||
@ -568,8 +638,10 @@ start_job_command (child)
|
|||||||
{
|
{
|
||||||
/* Go on to the next command. It might be the recursive one.
|
/* Go on to the next command. It might be the recursive one.
|
||||||
We construct ARGV only to find the end of the command line. */
|
We construct ARGV only to find the end of the command line. */
|
||||||
|
#ifndef VMS
|
||||||
free (argv[0]);
|
free (argv[0]);
|
||||||
free ((char *) argv);
|
free ((char *) argv);
|
||||||
|
#endif
|
||||||
argv = 0;
|
argv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,8 +680,10 @@ start_job_command (child)
|
|||||||
|
|
||||||
if (just_print_flag && !(flags & COMMANDS_RECURSE))
|
if (just_print_flag && !(flags & COMMANDS_RECURSE))
|
||||||
{
|
{
|
||||||
|
#ifndef VMS
|
||||||
free (argv[0]);
|
free (argv[0]);
|
||||||
free ((char *) argv);
|
free ((char *) argv);
|
||||||
|
#endif
|
||||||
goto next_command;
|
goto next_command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,6 +692,8 @@ start_job_command (child)
|
|||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
|
|
||||||
|
#ifndef VMS
|
||||||
|
|
||||||
/* Set up a bad standard input that reads from a broken pipe. */
|
/* Set up a bad standard input that reads from a broken pipe. */
|
||||||
|
|
||||||
if (bad_stdin == -1)
|
if (bad_stdin == -1)
|
||||||
@ -652,6 +728,8 @@ start_job_command (child)
|
|||||||
if (child->good_stdin)
|
if (child->good_stdin)
|
||||||
good_stdin_used = 1;
|
good_stdin_used = 1;
|
||||||
|
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
child->deleted = 0;
|
child->deleted = 0;
|
||||||
|
|
||||||
/* Set up the environment for the child. */
|
/* Set up the environment for the child. */
|
||||||
@ -660,6 +738,7 @@ start_job_command (child)
|
|||||||
|
|
||||||
#ifndef __MSDOS__
|
#ifndef __MSDOS__
|
||||||
|
|
||||||
|
#ifndef VMS
|
||||||
/* start_waiting_job has set CHILD->remote if we can start a remote job. */
|
/* start_waiting_job has set CHILD->remote if we can start a remote job. */
|
||||||
if (child->remote)
|
if (child->remote)
|
||||||
{
|
{
|
||||||
@ -680,6 +759,7 @@ start_job_command (child)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif /* !VMS */
|
||||||
{
|
{
|
||||||
/* Fork the child process. */
|
/* Fork the child process. */
|
||||||
|
|
||||||
@ -694,6 +774,17 @@ start_job_command (child)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
child->remote = 0;
|
child->remote = 0;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
|
||||||
|
if (!child_execute_job (argv, child)) {
|
||||||
|
/* Fork failed! */
|
||||||
|
perror_with_name ("vfork", "");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
parent_environ = environ;
|
parent_environ = environ;
|
||||||
child->pid = vfork ();
|
child->pid = vfork ();
|
||||||
environ = parent_environ; /* Restore value child may have clobbered. */
|
environ = parent_environ; /* Restore value child may have clobbered. */
|
||||||
@ -711,9 +802,11 @@ start_job_command (child)
|
|||||||
perror_with_name ("vfork", "");
|
perror_with_name ("vfork", "");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
#endif /* !VMS */
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* MSDOS. */
|
#else /* MSDOS. */
|
||||||
|
|
||||||
dos_status = spawnvpe (P_WAIT, argv[0], argv, child->environment);
|
dos_status = spawnvpe (P_WAIT, argv[0], argv, child->environment);
|
||||||
++dead_children;
|
++dead_children;
|
||||||
child->pid = dos_pid++;
|
child->pid = dos_pid++;
|
||||||
@ -735,15 +828,17 @@ start_job_command (child)
|
|||||||
set_command_state (child->file, cs_running);
|
set_command_state (child->file, cs_running);
|
||||||
|
|
||||||
/* Free the storage used by the child's argument list. */
|
/* Free the storage used by the child's argument list. */
|
||||||
|
#ifndef VMS
|
||||||
free (argv[0]);
|
free (argv[0]);
|
||||||
free ((char *) argv);
|
free ((char *) argv);
|
||||||
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
child->file->update_status = 2;
|
child->file->update_status = 2;
|
||||||
notice_finished_file (child->file);
|
notice_finished_file (child->file);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to start a child running.
|
/* Try to start a child running.
|
||||||
@ -949,13 +1044,15 @@ new_job (file)
|
|||||||
|
|
||||||
/* The job is now primed. Start it running.
|
/* The job is now primed. Start it running.
|
||||||
(This will notice if there are in fact no commands.) */
|
(This will notice if there are in fact no commands.) */
|
||||||
start_waiting_job (c);
|
(void)start_waiting_job (c);
|
||||||
|
|
||||||
if (job_slots == 1)
|
if (job_slots == 1)
|
||||||
/* Since there is only one job slot, make things run linearly.
|
/* Since there is only one job slot, make things run linearly.
|
||||||
Wait for the child to die, setting the state to `cs_finished'. */
|
Wait for the child to die, setting the state to `cs_finished'. */
|
||||||
while (file->command_state == cs_running)
|
while (file->command_state == cs_running)
|
||||||
reap_children (1, 0);
|
reap_children (1, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move CHILD's pointers to the next command for it to execute.
|
/* Move CHILD's pointers to the next command for it to execute.
|
||||||
@ -984,10 +1081,9 @@ job_next_command (child)
|
|||||||
static int
|
static int
|
||||||
load_too_high ()
|
load_too_high ()
|
||||||
{
|
{
|
||||||
#ifdef __MSDOS__
|
#if defined(__MSDOS__) || defined(VMS)
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
extern int getloadavg ();
|
|
||||||
double load;
|
double load;
|
||||||
|
|
||||||
if (max_load_average < 0)
|
if (max_load_average < 0)
|
||||||
@ -1036,10 +1132,226 @@ start_waiting_jobs ()
|
|||||||
|
|
||||||
/* Try to start that job. We break out of the loop as soon
|
/* Try to start that job. We break out of the loop as soon
|
||||||
as start_waiting_job puts one back on the waiting list. */
|
as start_waiting_job puts one back on the waiting list. */
|
||||||
} while (start_waiting_job (job) && waiting_jobs != 0);
|
}
|
||||||
|
while (start_waiting_job (job) && waiting_jobs != 0);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace the current process with one executing the command in ARGV.
|
#ifdef VMS
|
||||||
|
#include <descrip.h>
|
||||||
|
#include <clidef.h>
|
||||||
|
|
||||||
|
/* This is called as an AST when a child process dies (it won't get
|
||||||
|
interrupted by anything except a higher level AST).
|
||||||
|
*/
|
||||||
|
int vmsHandleChildTerm(struct child *child)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
register struct child *lastc, *c;
|
||||||
|
int child_failed;
|
||||||
|
|
||||||
|
vms_jobsefnmask &= ~(1 << (child->efn - 32));
|
||||||
|
|
||||||
|
lib$free_ef(&child->efn);
|
||||||
|
|
||||||
|
(void) sigblock (fatal_signal_mask);
|
||||||
|
|
||||||
|
child_failed = !(child->cstatus & 1 || ((child->cstatus & 7) == 0));
|
||||||
|
|
||||||
|
/* Search for a child matching the deceased one. */
|
||||||
|
lastc = 0;
|
||||||
|
#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
|
||||||
|
for (c = children; c != 0 && c != child; lastc = c, c = c->next);
|
||||||
|
#else
|
||||||
|
c = child;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (child_failed && !c->noerror && !ignore_errors_flag)
|
||||||
|
{
|
||||||
|
/* The commands failed. Write an error message,
|
||||||
|
delete non-precious targets, and abort. */
|
||||||
|
child_error (c->file->name, c->cstatus, 0, 0, 0);
|
||||||
|
c->file->update_status = 1;
|
||||||
|
delete_child_targets (c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (child_failed)
|
||||||
|
{
|
||||||
|
/* The commands failed, but we don't care. */
|
||||||
|
child_error (c->file->name, c->cstatus, 0, 0, 1);
|
||||||
|
child_failed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
|
||||||
|
/* If there are more commands to run, try to start them. */
|
||||||
|
start_job (c);
|
||||||
|
|
||||||
|
switch (c->file->command_state)
|
||||||
|
{
|
||||||
|
case cs_running:
|
||||||
|
/* Successfully started. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cs_finished:
|
||||||
|
if (c->file->update_status != 0) {
|
||||||
|
/* We failed to start the commands. */
|
||||||
|
delete_child_targets (c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error ("internal error: `%s' command_state \
|
||||||
|
%d in child_handler", c->file->name);
|
||||||
|
abort ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif /* RECURSIVEJOBS */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the state flag to say the commands have finished. */
|
||||||
|
c->file->command_state = cs_finished;
|
||||||
|
notice_finished_file (c->file);
|
||||||
|
|
||||||
|
#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
|
||||||
|
/* Remove the child from the chain and free it. */
|
||||||
|
if (lastc == 0)
|
||||||
|
children = c->next;
|
||||||
|
else
|
||||||
|
lastc->next = c->next;
|
||||||
|
free_child (c);
|
||||||
|
#endif /* RECURSIVEJOBS */
|
||||||
|
|
||||||
|
/* There is now another slot open. */
|
||||||
|
if (job_slots_used > 0)
|
||||||
|
--job_slots_used;
|
||||||
|
|
||||||
|
/* If the job failed, and the -k flag was not given, die. */
|
||||||
|
if (child_failed && !keep_going_flag)
|
||||||
|
die (EXIT_FAILURE);
|
||||||
|
|
||||||
|
(void) sigsetmask (sigblock (0) & ~(fatal_signal_mask));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VMS:
|
||||||
|
Spawn a process executing the command in ARGV and return its pid. */
|
||||||
|
|
||||||
|
#define MAXCMDLEN 200
|
||||||
|
|
||||||
|
int
|
||||||
|
child_execute_job (argv, child)
|
||||||
|
char *argv;
|
||||||
|
struct child *child;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static struct dsc$descriptor_s cmddsc;
|
||||||
|
#ifndef DONTWAITFORCHILD
|
||||||
|
int spflags = 0;
|
||||||
|
#else
|
||||||
|
int spflags = CLI$M_NOWAIT;
|
||||||
|
#endif
|
||||||
|
int status;
|
||||||
|
char cmd[4096],*p,*c;
|
||||||
|
char comname[50];
|
||||||
|
|
||||||
|
/* Remove backslashes */
|
||||||
|
for (p = argv, c = cmd; *p; p++,c++)
|
||||||
|
{
|
||||||
|
if (*p == '\\') p++;
|
||||||
|
*c = *p;
|
||||||
|
}
|
||||||
|
*c = *p;
|
||||||
|
|
||||||
|
/* check for maximum dcl length and create *.com file if neccesary */
|
||||||
|
|
||||||
|
comname[0] = '\0';
|
||||||
|
|
||||||
|
if (strlen (cmd) > MAXCMDLEN)
|
||||||
|
{
|
||||||
|
FILE *outfile;
|
||||||
|
char tmp;
|
||||||
|
|
||||||
|
strcpy (comname, "sys$scratch:CMDXXXXXX.COM");
|
||||||
|
(void) mktemp (comname);
|
||||||
|
|
||||||
|
outfile = fopen (comname, "w");
|
||||||
|
if (outfile == 0)
|
||||||
|
pfatal_with_name (comname);
|
||||||
|
|
||||||
|
fprintf (outfile, "$ ");
|
||||||
|
c = cmd;
|
||||||
|
|
||||||
|
while (c)
|
||||||
|
{
|
||||||
|
p = strchr (c, ',');
|
||||||
|
if ((p == NULL) || (p-c > MAXCMDLEN))
|
||||||
|
p = strchr (c, ' ');
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
tmp = *p;
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tmp = '\0';
|
||||||
|
fprintf (outfile, "%s%s\n", c, (tmp == '\0')?"":" -");
|
||||||
|
if (p != NULL)
|
||||||
|
*p = tmp;
|
||||||
|
c = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (outfile);
|
||||||
|
|
||||||
|
sprintf (cmd, "$ @%s", comname);
|
||||||
|
|
||||||
|
if (debug_flag)
|
||||||
|
printf ("Executing %s instead\n", cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmddsc.dsc$w_length = strlen(cmd);
|
||||||
|
cmddsc.dsc$a_pointer = cmd;
|
||||||
|
cmddsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
||||||
|
cmddsc.dsc$b_class = DSC$K_CLASS_S;
|
||||||
|
|
||||||
|
child->efn = 0;
|
||||||
|
while (child->efn < 32 || child->efn > 63)
|
||||||
|
{
|
||||||
|
status = lib$get_ef(&child->efn);
|
||||||
|
if (!(status & 1))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys$clref(child->efn);
|
||||||
|
|
||||||
|
vms_jobsefnmask |= (1 << (child->efn - 32));
|
||||||
|
|
||||||
|
#ifndef DONTWAITFORCHILD
|
||||||
|
status = lib$spawn(&cmddsc,0,0,&spflags,0,&child->pid,&child->cstatus,
|
||||||
|
&child->efn,0,0);
|
||||||
|
vmsHandleChildTerm(child);
|
||||||
|
#else
|
||||||
|
status = lib$spawn(&cmddsc,0,0,&spflags,0,&child->pid,&child->cstatus,
|
||||||
|
&child->efn,vmsHandleChildTerm,child);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(status & 1))
|
||||||
|
{
|
||||||
|
printf("Error spawning, %d\n",status);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink (comname);
|
||||||
|
|
||||||
|
return (status & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !VMS */
|
||||||
|
|
||||||
|
/* UNIX:
|
||||||
|
Replace the current process with one executing the command in ARGV.
|
||||||
STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is
|
STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is
|
||||||
the environment of the new program. This function does not return. */
|
the environment of the new program. This function does not return. */
|
||||||
|
|
||||||
@ -1060,6 +1372,7 @@ child_execute_job (stdin_fd, stdout_fd, argv, envp)
|
|||||||
/* Run the command. */
|
/* Run the command. */
|
||||||
exec_command (argv, envp);
|
exec_command (argv, envp);
|
||||||
}
|
}
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
/* Replace the current process with one running the command in ARGV,
|
/* Replace the current process with one running the command in ARGV,
|
||||||
with environment ENVP. This function does not return. */
|
with environment ENVP. This function does not return. */
|
||||||
@ -1068,6 +1381,12 @@ void
|
|||||||
exec_command (argv, envp)
|
exec_command (argv, envp)
|
||||||
char **argv, **envp;
|
char **argv, **envp;
|
||||||
{
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
/* Run the program. */
|
||||||
|
execve (argv[0], argv, envp);
|
||||||
|
perror_with_name ("execve: ", argv[0]);
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
#else
|
||||||
/* Be the user, permanently. */
|
/* Be the user, permanently. */
|
||||||
child_access ();
|
child_access ();
|
||||||
|
|
||||||
@ -1119,8 +1438,10 @@ exec_command (argv, envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_exit (127);
|
_exit (127);
|
||||||
|
#endif /* !VMS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef VMS
|
||||||
/* Figure out the argument list necessary to run LINE as a command. Try to
|
/* Figure out the argument list necessary to run LINE as a command. Try to
|
||||||
avoid using a shell. This routine handles only ' quoting, and " quoting
|
avoid using a shell. This routine handles only ' quoting, and " quoting
|
||||||
when no backslash, $ or ` characters are seen in the quotes. Starting
|
when no backslash, $ or ` characters are seen in the quotes. Starting
|
||||||
@ -1364,7 +1685,7 @@ construct_command_argv_internal (line, restp, shell, ifs)
|
|||||||
{
|
{
|
||||||
/* Free the old argument list we were working on. */
|
/* Free the old argument list we were working on. */
|
||||||
free (new_argv[0]);
|
free (new_argv[0]);
|
||||||
free (new_argv);
|
free ((void *)new_argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
@ -1496,6 +1817,7 @@ construct_command_argv (line, restp, file)
|
|||||||
|
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
#endif /* !VMS */
|
||||||
|
|
||||||
#ifndef HAVE_DUP2
|
#ifndef HAVE_DUP2
|
||||||
int
|
int
|
||||||
|
27
job.h
27
job.h
@ -16,6 +16,9 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with GNU Make; see the file COPYING. If not, write to
|
along with GNU Make; see the file COPYING. If not, write to
|
||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef SEEN_JOB_H
|
||||||
|
#define SEEN_JOB_H
|
||||||
|
|
||||||
/* Structure describing a running or dead child process. */
|
/* Structure describing a running or dead child process. */
|
||||||
|
|
||||||
struct child
|
struct child
|
||||||
@ -31,6 +34,10 @@ struct child
|
|||||||
char *command_ptr; /* Ptr into command_lines[command_line]. */
|
char *command_ptr; /* Ptr into command_lines[command_line]. */
|
||||||
|
|
||||||
pid_t pid; /* Child process's ID number. */
|
pid_t pid; /* Child process's ID number. */
|
||||||
|
#ifdef VMS
|
||||||
|
int efn; /* Completion event flag number */
|
||||||
|
int cstatus; /* Completion status */
|
||||||
|
#endif
|
||||||
unsigned int remote:1; /* Nonzero if executing remotely. */
|
unsigned int remote:1; /* Nonzero if executing remotely. */
|
||||||
|
|
||||||
unsigned int noerror:1; /* Nonzero if commands contained a `-'. */
|
unsigned int noerror:1; /* Nonzero if commands contained a `-'. */
|
||||||
@ -41,18 +48,22 @@ struct child
|
|||||||
|
|
||||||
extern struct child *children;
|
extern struct child *children;
|
||||||
|
|
||||||
extern void new_job ();
|
extern void new_job PARAMS ((struct file *file));
|
||||||
extern void reap_children ();
|
extern void reap_children PARAMS ((int block, int err));
|
||||||
extern void start_waiting_jobs ();
|
extern void start_waiting_jobs PARAMS ((void));
|
||||||
|
|
||||||
extern char **construct_command_argv ();
|
extern char **construct_command_argv PARAMS ((char *line, char **restp, struct file *file));
|
||||||
extern void child_execute_job ();
|
#ifdef VMS
|
||||||
extern void exec_command ();
|
extern int child_execute_job PARAMS ((char *argv, struct child *child));
|
||||||
|
#else
|
||||||
|
extern void child_execute_job PARAMS ((int stdin_fd, int stdout_fd, char **argv, char **envp));
|
||||||
|
#endif
|
||||||
|
extern void exec_command PARAMS ((char **argv, char **envp));
|
||||||
|
|
||||||
extern unsigned int job_slots_used;
|
extern unsigned int job_slots_used;
|
||||||
|
|
||||||
#ifdef POSIX
|
#ifdef POSIX
|
||||||
extern void unblock_sigs ();
|
extern void unblock_sigs PARAMS ((void));
|
||||||
#else
|
#else
|
||||||
#ifdef HAVE_SIGSETMASK
|
#ifdef HAVE_SIGSETMASK
|
||||||
extern int fatal_signal_mask;
|
extern int fatal_signal_mask;
|
||||||
@ -61,3 +72,5 @@ extern int fatal_signal_mask;
|
|||||||
#define unblock_sigs()
|
#define unblock_sigs()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* SEEN_JOB_H */
|
||||||
|
49
main.c
49
main.c
@ -17,20 +17,23 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "job.h"
|
#include "job.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
extern void init_dir PARAMS ((void));
|
||||||
|
extern RETSIGTYPE fatal_error_signal PARAMS ((int sig));
|
||||||
|
extern RETSIGTYPE child_handler PARAMS ((int sig));
|
||||||
|
|
||||||
extern void print_variable_data_base ();
|
extern void print_variable_data_base PARAMS ((void));
|
||||||
extern void print_dir_data_base ();
|
extern void print_dir_data_base PARAMS ((void));
|
||||||
extern void print_rule_data_base ();
|
extern void print_rule_data_base PARAMS ((void));
|
||||||
extern void print_file_data_base ();
|
extern void print_file_data_base PARAMS ((void));
|
||||||
extern void print_vpath_data_base ();
|
extern void print_vpath_data_base PARAMS ((void));
|
||||||
|
|
||||||
#ifndef HAVE_UNISTD_H
|
#ifndef HAVE_UNISTD_H
|
||||||
extern int chdir ();
|
extern int chdir ();
|
||||||
@ -43,10 +46,12 @@ extern double atof ();
|
|||||||
#endif
|
#endif
|
||||||
extern char *mktemp ();
|
extern char *mktemp ();
|
||||||
|
|
||||||
static void print_data_base (), print_version ();
|
static void print_data_base PARAMS((void));
|
||||||
static void decode_switches (), decode_env_switches ();
|
static void print_version PARAMS ((void));
|
||||||
static void define_makeflags ();
|
static void decode_switches PARAMS ((int argc, char **argv, int env));
|
||||||
static char *quote_as_word ();
|
static void decode_env_switches PARAMS ((char *envar, unsigned int len));
|
||||||
|
static void define_makeflags PARAMS ((int all, int makefile));
|
||||||
|
static char *quote_as_word PARAMS ((char *out, char *in, int double_dollars));
|
||||||
|
|
||||||
/* The structure that describes an accepted command switch. */
|
/* The structure that describes an accepted command switch. */
|
||||||
|
|
||||||
@ -415,7 +420,6 @@ main (argc, argv, envp)
|
|||||||
char **argv;
|
char **argv;
|
||||||
char **envp;
|
char **envp;
|
||||||
{
|
{
|
||||||
extern RETSIGTYPE fatal_error_signal (), child_handler ();
|
|
||||||
register struct file *f;
|
register struct file *f;
|
||||||
register unsigned int i;
|
register unsigned int i;
|
||||||
char **p;
|
char **p;
|
||||||
@ -486,7 +490,11 @@ main (argc, argv, envp)
|
|||||||
program = "make";
|
program = "make";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
program = rindex (argv[0], ']');
|
||||||
|
#else
|
||||||
program = rindex (argv[0], '/');
|
program = rindex (argv[0], '/');
|
||||||
|
#endif
|
||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
if (program == 0)
|
if (program == 0)
|
||||||
program = rindex (argv[0], '\\');
|
program = rindex (argv[0], '\\');
|
||||||
@ -560,7 +568,7 @@ main (argc, argv, envp)
|
|||||||
if (print_version_flag)
|
if (print_version_flag)
|
||||||
die (0);
|
die (0);
|
||||||
|
|
||||||
#ifndef __MSDOS__
|
#if !defined(__MSDOS__) && !defined(VMS)
|
||||||
/* Set the "MAKE_COMMAND" variable to the name we were invoked with.
|
/* Set the "MAKE_COMMAND" variable to the name we were invoked with.
|
||||||
(If it is a relative pathname with a slash, prepend our directory name
|
(If it is a relative pathname with a slash, prepend our directory name
|
||||||
so the result will run the same program regardless of the current dir.
|
so the result will run the same program regardless of the current dir.
|
||||||
@ -699,7 +707,12 @@ main (argc, argv, envp)
|
|||||||
|
|
||||||
/* Make a unique filename. */
|
/* Make a unique filename. */
|
||||||
#ifdef HAVE_MKTEMP
|
#ifdef HAVE_MKTEMP
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
static char name[] = "sys$scratch:GmXXXXXX";
|
||||||
|
#else
|
||||||
static char name[] = "/tmp/GmXXXXXX";
|
static char name[] = "/tmp/GmXXXXXX";
|
||||||
|
#endif
|
||||||
(void) mktemp (name);
|
(void) mktemp (name);
|
||||||
#else
|
#else
|
||||||
static char name[L_tmpnam];
|
static char name[L_tmpnam];
|
||||||
@ -1101,15 +1114,15 @@ main (argc, argv, envp)
|
|||||||
/* Nothing happened. */
|
/* Nothing happened. */
|
||||||
case 0:
|
case 0:
|
||||||
/* Updated successfully. */
|
/* Updated successfully. */
|
||||||
status = 0;
|
status = EXIT_SUCCESS;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* Updating failed. */
|
/* Updating failed. */
|
||||||
status = 2;
|
status = EXIT_FAILURE;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* We are under -q and would run some commands. */
|
/* We are under -q and would run some commands. */
|
||||||
status = 1;
|
status = EXIT_FAILURE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
@ -1589,7 +1602,11 @@ quote_as_word (out, in, double_dollars)
|
|||||||
{
|
{
|
||||||
while (*in != '\0')
|
while (*in != '\0')
|
||||||
{
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
if (index ("^;'\"*?$<>(){}|&~`\\ \t\r\n\f\v", *in) != 0)
|
||||||
|
#else
|
||||||
if (index ("^;'\"*?[]$<>(){}|&~`\\ \t\r\n\f\v", *in) != 0)
|
if (index ("^;'\"*?[]$<>(){}|&~`\\ \t\r\n\f\v", *in) != 0)
|
||||||
|
#endif
|
||||||
*out++ = '\\';
|
*out++ = '\\';
|
||||||
if (double_dollars && *in == '$')
|
if (double_dollars && *in == '$')
|
||||||
*out++ = '$';
|
*out++ = '$';
|
||||||
|
119
make.h
119
make.h
@ -1,5 +1,5 @@
|
|||||||
/* Miscellaneous global declarations and portability cruft for GNU Make.
|
/* Miscellaneous global declarations and portability cruft for GNU Make.
|
||||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95 Free Software Foundation, Inc.
|
Copyright (C) 1988,89,90,91,92,93,94,95,96 Free Software Foundation, Inc.
|
||||||
This file is part of GNU Make.
|
This file is part of GNU Make.
|
||||||
|
|
||||||
GNU Make is free software; you can redistribute it and/or modify
|
GNU Make is free software; you can redistribute it and/or modify
|
||||||
@ -28,6 +28,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#undef HAVE_CONFIG_H
|
#undef HAVE_CONFIG_H
|
||||||
#define HAVE_CONFIG_H
|
#define HAVE_CONFIG_H
|
||||||
|
|
||||||
|
|
||||||
|
/* Use prototypes if available. */
|
||||||
|
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||||
|
#undef PARAMS
|
||||||
|
#define PARAMS(protos) protos
|
||||||
|
#else /* Not C++ or ANSI C. */
|
||||||
|
#undef PARAMS
|
||||||
|
#define PARAMS(protos) ()
|
||||||
|
#endif /* C++ or ANSI C. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef CRAY
|
#ifdef CRAY
|
||||||
/* This must happen before #include <signal.h> so
|
/* This must happen before #include <signal.h> so
|
||||||
that the declaration therein is changed. */
|
that the declaration therein is changed. */
|
||||||
@ -67,9 +78,7 @@ extern int errno;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some systems define _POSIX_VERSION but are not really POSIX.1. */
|
/* Some systems define _POSIX_VERSION but are not really POSIX.1. */
|
||||||
#if (defined (butterfly) || defined (__arm) || \
|
#if (defined (butterfly) || defined (__arm) || (defined (__mips) && defined (_SYSTYPE_SVR3)) || (defined (sequent) && defined (i386)))
|
||||||
(defined (__mips) && defined (_SYSTYPE_SVR3)) || \
|
|
||||||
(defined (sequent) && defined (i386)))
|
|
||||||
#undef POSIX
|
#undef POSIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -132,7 +141,7 @@ extern char *sys_siglist[];
|
|||||||
#define PATH_VAR(var) char var[PATH_MAX]
|
#define PATH_VAR(var) char var[PATH_MAX]
|
||||||
#else
|
#else
|
||||||
#define NEED_GET_PATH_MAX
|
#define NEED_GET_PATH_MAX
|
||||||
extern unsigned int get_path_max ();
|
extern unsigned int get_path_max PARAMS ((void));
|
||||||
#define GET_PATH_MAX (get_path_max ())
|
#define GET_PATH_MAX (get_path_max ())
|
||||||
#define PATH_VAR(var) char *var = (char *) alloca (GET_PATH_MAX)
|
#define PATH_VAR(var) char *var = (char *) alloca (GET_PATH_MAX)
|
||||||
#endif
|
#endif
|
||||||
@ -153,8 +162,16 @@ extern unsigned int get_path_max ();
|
|||||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <types.h>
|
||||||
|
#include <unixlib.h>
|
||||||
|
#include <unixio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <perror.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
|
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) || defined(VMS))
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#define ANSI_STRING
|
#define ANSI_STRING
|
||||||
@ -170,10 +187,12 @@ extern unsigned int get_path_max ();
|
|||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char *malloc (), *realloc ();
|
extern char *malloc PARAMS ((int));
|
||||||
extern void free ();
|
extern char *realloc PARAMS ((char *, int));
|
||||||
|
extern void free PARAMS ((char *));
|
||||||
|
|
||||||
extern void abort (), exit ();
|
extern void abort PARAMS ((void));
|
||||||
|
extern void exit PARAMS ((int));
|
||||||
|
|
||||||
#endif /* Standard headers. */
|
#endif /* Standard headers. */
|
||||||
|
|
||||||
@ -214,8 +233,8 @@ extern void bcopy ();
|
|||||||
/* SCO Xenix has a buggy macro definition in <string.h>. */
|
/* SCO Xenix has a buggy macro definition in <string.h>. */
|
||||||
#undef strerror
|
#undef strerror
|
||||||
|
|
||||||
#ifndef ANSI_STRING
|
#if !defined(ANSI_STRING) && !defined(__DECC)
|
||||||
extern char *strerror ();
|
extern char *strerror PARAMS ((int errnum));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -258,19 +277,30 @@ extern char *alloca ();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void die ();
|
extern void die ();
|
||||||
extern void message (), fatal (), error ();
|
extern void message ();
|
||||||
|
extern void fatal ();
|
||||||
|
extern void error ();
|
||||||
extern void log_working_directory ();
|
extern void log_working_directory ();
|
||||||
extern void makefile_error (), makefile_fatal ();
|
extern void makefile_error ();
|
||||||
extern void pfatal_with_name (), perror_with_name ();
|
extern void makefile_fatal ();
|
||||||
extern char *savestring (), *concat ();
|
extern void pfatal_with_name ();
|
||||||
extern char *xmalloc (), *xrealloc ();
|
extern void perror_with_name ();
|
||||||
extern char *find_next_token (), *next_token (), *end_of_token ();
|
extern char *savestring ();
|
||||||
extern void collapse_continuations (), remove_comments ();
|
extern char *concat ();
|
||||||
extern char *sindex (), *lindex ();
|
extern char *xmalloc ();
|
||||||
|
extern char *xrealloc ();
|
||||||
|
extern char *find_next_token ();
|
||||||
|
extern char *next_token ();
|
||||||
|
extern char *end_of_token ();
|
||||||
|
extern void collapse_continuations ();
|
||||||
|
extern void remove_comments ();
|
||||||
|
extern char *sindex ();
|
||||||
|
extern char *lindex ();
|
||||||
extern int alpha_compare ();
|
extern int alpha_compare ();
|
||||||
extern void print_spaces ();
|
extern void print_spaces ();
|
||||||
extern struct dep *copy_dep_chain ();
|
extern struct dep *copy_dep_chain ();
|
||||||
extern char *find_char_unquote (), *find_percent ();
|
extern char *find_char_unquote ();
|
||||||
|
extern char *find_percent ();
|
||||||
|
|
||||||
#ifndef NO_ARCHIVES
|
#ifndef NO_ARCHIVES
|
||||||
extern int ar_name ();
|
extern int ar_name ();
|
||||||
@ -280,16 +310,22 @@ extern time_t ar_member_date ();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void dir_load ();
|
extern void dir_load ();
|
||||||
extern int dir_file_exists_p (), file_exists_p (), file_impossible_p ();
|
extern int dir_file_exists_p ();
|
||||||
|
extern int file_exists_p ();
|
||||||
|
extern int file_impossible_p ();
|
||||||
extern void file_impossible ();
|
extern void file_impossible ();
|
||||||
extern char *dir_name ();
|
extern char *dir_name ();
|
||||||
|
|
||||||
extern void define_default_variables ();
|
extern void define_default_variables ();
|
||||||
extern void set_default_suffixes (), install_default_suffix_rules ();
|
extern void set_default_suffixes ();
|
||||||
extern void install_default_implicit_rules (), count_implicit_rule_limits ();
|
extern void install_default_suffix_rules ();
|
||||||
extern void convert_to_pattern (), create_pattern_rule ();
|
extern void install_default_implicit_rules ();
|
||||||
|
extern void count_implicit_rule_limits ();
|
||||||
|
extern void convert_to_pattern ();
|
||||||
|
extern void create_pattern_rule ();
|
||||||
|
|
||||||
extern void build_vpath_lists (), construct_vpath_list ();
|
extern void build_vpath_lists ();
|
||||||
|
extern void construct_vpath_list ();
|
||||||
extern int vpath_search ();
|
extern int vpath_search ();
|
||||||
|
|
||||||
extern void construct_include_path ();
|
extern void construct_include_path ();
|
||||||
@ -298,8 +334,9 @@ extern void uniquize_deps ();
|
|||||||
extern int update_goal_chain ();
|
extern int update_goal_chain ();
|
||||||
extern void notice_finished_file ();
|
extern void notice_finished_file ();
|
||||||
|
|
||||||
extern void user_access (), make_access (), child_access ();
|
extern void user_access ();
|
||||||
|
extern void make_access ();
|
||||||
|
extern void child_access ();
|
||||||
|
|
||||||
#ifdef HAVE_VFORK_H
|
#ifdef HAVE_VFORK_H
|
||||||
#include <vfork.h>
|
#include <vfork.h>
|
||||||
@ -311,12 +348,17 @@ extern void user_access (), make_access (), child_access ();
|
|||||||
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION)
|
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION)
|
||||||
|
|
||||||
extern long int atol ();
|
extern long int atol ();
|
||||||
|
#ifndef VMS
|
||||||
extern long int lseek ();
|
extern long int lseek ();
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* Not GNU C library or POSIX. */
|
#endif /* Not GNU C library or POSIX. */
|
||||||
|
|
||||||
#ifdef HAVE_GETCWD
|
#ifdef HAVE_GETCWD
|
||||||
extern char *getcwd ();
|
extern char *getcwd ();
|
||||||
|
#ifdef VMS
|
||||||
|
extern char *getwd PARAMS ((char *));
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
extern char *getwd ();
|
extern char *getwd ();
|
||||||
#define getcwd(buf, len) getwd (buf)
|
#define getcwd(buf, len) getwd (buf)
|
||||||
@ -349,3 +391,26 @@ extern int handling_fatal_signal;
|
|||||||
#define DEBUGPR(msg) \
|
#define DEBUGPR(msg) \
|
||||||
do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \
|
do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \
|
||||||
fflush (stdout); } while (0)
|
fflush (stdout); } while (0)
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
# ifndef EXIT_FAILURE
|
||||||
|
# define EXIT_FAILURE 3
|
||||||
|
# endif
|
||||||
|
# ifndef EXIT_SUCCESS
|
||||||
|
# define EXIT_SUCCESS 1
|
||||||
|
# endif
|
||||||
|
# ifndef EXIT_TROUBLE
|
||||||
|
# define EXIT_TROUBLE 2
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifndef EXIT_FAILURE
|
||||||
|
# define EXIT_FAILURE 2
|
||||||
|
# endif
|
||||||
|
# ifndef EXIT_SUCCESS
|
||||||
|
# define EXIT_SUCCESS 0
|
||||||
|
# endif
|
||||||
|
# ifndef EXIT_TROUBLE
|
||||||
|
# define EXIT_TROUBLE 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
34
makefile.com
Normal file
34
makefile.com
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
$!
|
||||||
|
$! Makefile.com - builds GNU Make for VMS
|
||||||
|
$!
|
||||||
|
$! P1 is non-empty if you want to link with the VAXCRTL library instead
|
||||||
|
$! of the shareable executable
|
||||||
|
$!
|
||||||
|
$ def/nolog sys sys$library:
|
||||||
|
$ filelist = "alloca commands default dir expand file function implicit job main misc read remake remote-stub rule signame variable version vmsfunctions vmsify vpath [.glob]glob [.glob]fnmatch getopt getopt1"
|
||||||
|
$ copy config.h-vms config.h
|
||||||
|
$ n=0
|
||||||
|
$ loop:
|
||||||
|
$ cfile = f$elem(n," ",filelist)
|
||||||
|
$ if cfile .eqs. " " then goto linkit
|
||||||
|
$ write sys$output "Compiling ''cfile'..."
|
||||||
|
$ call compileit 'cfile' 'p1'
|
||||||
|
$ n = n + 1
|
||||||
|
$ goto loop
|
||||||
|
$ linkit:
|
||||||
|
$ if p1 .nes. "" then goto link_using_library
|
||||||
|
$ link/exe=make alloca,commands,default,dir,expand,file,function,-
|
||||||
|
implicit,job,main,misc,read,remake,remote-stub,rule,-
|
||||||
|
signame,variable,version,vmsfunctions,vmsify,vpath,-
|
||||||
|
glob,fnmatch,getopt,getopt1
|
||||||
|
$ exit
|
||||||
|
$ link_using_library:
|
||||||
|
$ link/exe=make alloca,commands,default,dir,expand,file,function,-
|
||||||
|
implicit,job,main,misc,read,remake,remote-stub,rule,-
|
||||||
|
signame,variable,version,vmsfunctions,vmsfiy,vpath,-
|
||||||
|
glob,fnmatch,getopt,getopt1,sys$library:vaxcrtl/lib
|
||||||
|
$!
|
||||||
|
$ compileit : subroutine
|
||||||
|
$ cc/include=([],[.glob])/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file","unlink=remove","HAVE_CONFIG_H","VMS","NO_ARCHIVES") 'p1'
|
||||||
|
$ exit
|
||||||
|
$ endsubroutine : compileit
|
121
makefile.vms
Normal file
121
makefile.vms
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Copyright (C) 1988, 1989 Free Software Foundation, Inc.
|
||||||
|
# This file is part of GNU Make.
|
||||||
|
#
|
||||||
|
# VMS extensions from GNU Make 3.60 imported by
|
||||||
|
# Klaus Kämpf (kkaempf@didymus.rmi.de)
|
||||||
|
#
|
||||||
|
# GNU Make is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# GNU Make is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
CC = cc/warn
|
||||||
|
CP = copy
|
||||||
|
|
||||||
|
%.obj: %.c
|
||||||
|
$(CC) $(CFLAGS)/obj=$@ $<
|
||||||
|
#
|
||||||
|
# Makefile for GNU Make
|
||||||
|
#
|
||||||
|
|
||||||
|
CFLAGS = $(defines) /debug/noopt/include=([],[.glob])
|
||||||
|
#LDFLAGS = /deb
|
||||||
|
LDFLAGS =
|
||||||
|
|
||||||
|
defines = /define=("unlink=remove","HAVE_CONFIG_H","VMS","NO_ARCHIVES","allocated_variable_expand_for_file=alloc_var_expand_for_file")
|
||||||
|
|
||||||
|
LOAD_AVG = /define="NO_LDAV"
|
||||||
|
|
||||||
|
# If you don't want archive support, comment these out.
|
||||||
|
#ARCHIVES = ,ar.obj,arscan.obj
|
||||||
|
#ARCHIVES_SRC = ar.c arscan.c
|
||||||
|
|
||||||
|
# If your system needs extra libraries loaded in, define them here.
|
||||||
|
# System V probably need -lPW for alloca.
|
||||||
|
# if on vax, uncomment the following line
|
||||||
|
#LOADLIBES = ,c.opt/opt
|
||||||
|
LOADLIBES =
|
||||||
|
|
||||||
|
# If your system doesn't have alloca, or the one provided is bad,
|
||||||
|
# get it from the Emacs distribution and define these.
|
||||||
|
ALLOCA = ,alloca.obj
|
||||||
|
ALLOCASRC = alloca.c
|
||||||
|
|
||||||
|
# If there are remote execution facilities defined,
|
||||||
|
# enable them with switches here (see remote-*.c).
|
||||||
|
REMOTE =
|
||||||
|
|
||||||
|
# Any extra object files your system needs.
|
||||||
|
extras = ,signame.obj,remote-stub.obj,vmsfunctions.obj,vmsify.obj
|
||||||
|
#,directory.obj
|
||||||
|
# as an alternative:
|
||||||
|
glob = ,[.glob]glob.obj,[.glob]fnmatch.obj
|
||||||
|
getopt = ,getopt.obj,getopt1.obj
|
||||||
|
# Directory to install `make' in.
|
||||||
|
bindir = []
|
||||||
|
# Directory to install the man page in.
|
||||||
|
mandir = []
|
||||||
|
# Number to put on the man page filename.
|
||||||
|
manext = 1
|
||||||
|
|
||||||
|
objs = commands.obj,job.obj,dir.obj,file.obj,misc.obj,\
|
||||||
|
main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\
|
||||||
|
default.obj,variable.obj,expand.obj,function.obj,\
|
||||||
|
vpath.obj,version.obj$(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob)
|
||||||
|
srcs = commands.c job.c dir.c file.c misc.c \
|
||||||
|
main.c read.c remake.c rule.c implicit.c \
|
||||||
|
default.c variable.c expand.c function.c \
|
||||||
|
vpath.c version.c vmsfunctions.c vmsify.c $(ARCHIVES_SRC) $(ALLOCASRC) \
|
||||||
|
commands.h dep.h filedef.h job.h make.h rule.h variable.h
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: all doc
|
||||||
|
all: config.h make.exe
|
||||||
|
|
||||||
|
doc: make.info make.dvi
|
||||||
|
|
||||||
|
|
||||||
|
make.exe: $(objs)
|
||||||
|
$(LD)$(LDFLAGS)/exe=$@ $^$(LOADLIBES)
|
||||||
|
|
||||||
|
.PHONY: clean realclean
|
||||||
|
clean:
|
||||||
|
-$(RM) make.exe;,*.obj;*
|
||||||
|
|
||||||
|
# Automatically generated dependencies.
|
||||||
|
commands.obj: commands.c make.h dep.h commands.h filedef.h variable.h job.h
|
||||||
|
job.obj: job.c make.h commands.h job.h filedef.h variable.h
|
||||||
|
dir.obj: dir.c make.h
|
||||||
|
file.obj: file.c make.h commands.h dep.h filedef.h variable.h
|
||||||
|
misc.obj: misc.c make.h dep.h
|
||||||
|
main.obj: main.c make.h commands.h dep.h filedef.h variable.h job.h
|
||||||
|
read.obj: read.c make.h commands.h dep.h filedef.h variable.h
|
||||||
|
remake.obj: remake.c make.h commands.h job.h dep.h filedef.h
|
||||||
|
rule.obj: rule.c make.h commands.h dep.h filedef.h variable.h rule.h
|
||||||
|
implicit.obj: implicit.c make.h rule.h dep.h filedef.h
|
||||||
|
default.obj: default.c make.h rule.h dep.h filedef.h commands.h variable.h
|
||||||
|
variable.obj: variable.c make.h commands.h variable.h dep.h filedef.h
|
||||||
|
expand.obj: expand.c make.h commands.h filedef.h variable.h
|
||||||
|
function.obj: function.c make.h variable.h dep.h commands.h job.h
|
||||||
|
vpath.obj: vpath.c make.h filedef.h variable.h
|
||||||
|
version.obj: version.c
|
||||||
|
arscan.obj: arscan.c
|
||||||
|
ar.obj: ar.c make.h filedef.h
|
||||||
|
signame.obj: signame.c
|
||||||
|
remote-stub.obj: remote-stub.c
|
||||||
|
[.glob]glob.obj: [.glob]glob.c
|
||||||
|
[.glob]fnmatch.obj: [.glob]fnmatch.c
|
||||||
|
getopt.obj: getopt.c
|
||||||
|
getopt1.obj: getopt1.c
|
||||||
|
|
||||||
|
config.h: config.h-vms
|
||||||
|
$(CP) $< $@
|
4
misc.c
4
misc.c
@ -271,7 +271,9 @@ strerror (errnum)
|
|||||||
int errnum;
|
int errnum;
|
||||||
{
|
{
|
||||||
extern int errno, sys_nerr;
|
extern int errno, sys_nerr;
|
||||||
|
#ifndef __DECC
|
||||||
extern char *sys_errlist[];
|
extern char *sys_errlist[];
|
||||||
|
#endif
|
||||||
static char buf[] = "Unknown error 12345678901234567890";
|
static char buf[] = "Unknown error 12345678901234567890";
|
||||||
|
|
||||||
if (errno < sys_nerr)
|
if (errno < sys_nerr)
|
||||||
@ -540,6 +542,7 @@ log_access (flavor)
|
|||||||
static void
|
static void
|
||||||
init_access ()
|
init_access ()
|
||||||
{
|
{
|
||||||
|
#ifndef VMS
|
||||||
user_uid = getuid ();
|
user_uid = getuid ();
|
||||||
user_gid = getgid ();
|
user_gid = getgid ();
|
||||||
|
|
||||||
@ -553,6 +556,7 @@ init_access ()
|
|||||||
log_access ("Initialized");
|
log_access ("Initialized");
|
||||||
|
|
||||||
current_access = make;
|
current_access = make;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* GETLOADAVG_PRIVILEGED */
|
#endif /* GETLOADAVG_PRIVILEGED */
|
||||||
|
103
read.c
103
read.c
@ -17,9 +17,10 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
|
#include "job.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
/* This is POSIX.2, but most systems using -DPOSIX probably don't have it. */
|
/* This is POSIX.2, but most systems using -DPOSIX probably don't have it. */
|
||||||
@ -29,15 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "glob/glob.h"
|
#include "glob/glob.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef VMS
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
struct passwd *getpwnam ();
|
#else
|
||||||
|
struct passwd *getpwnam PARAMS ((char *name));
|
||||||
|
#endif
|
||||||
static int read_makefile ();
|
|
||||||
static unsigned int readline (), do_define ();
|
|
||||||
static int conditional_line ();
|
|
||||||
static void record_files ();
|
|
||||||
|
|
||||||
|
|
||||||
/* A `struct linebuffer' is a structure which holds a line of text.
|
/* A `struct linebuffer' is a structure which holds a line of text.
|
||||||
`readline' reads a line from a stream into a linebuffer
|
`readline' reads a line from a stream into a linebuffer
|
||||||
@ -104,6 +101,18 @@ unsigned int *reading_lineno_ptr;
|
|||||||
/* The chain of makefiles read by read_makefile. */
|
/* The chain of makefiles read by read_makefile. */
|
||||||
|
|
||||||
static struct dep *read_makefiles = 0;
|
static struct dep *read_makefiles = 0;
|
||||||
|
|
||||||
|
static int read_makefile PARAMS ((char *filename, int flags));
|
||||||
|
static unsigned int readline PARAMS ((struct linebuffer *linebuffer, FILE *stream,
|
||||||
|
char *filename, unsigned int lineno));
|
||||||
|
static unsigned int do_define PARAMS ((char *name, unsigned int namelen, enum variable_origin origin,
|
||||||
|
unsigned int lineno, FILE *infile, char *filename));
|
||||||
|
static int conditional_line PARAMS ((char *line, char *filename, unsigned int lineno));
|
||||||
|
static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent,
|
||||||
|
struct dep *deps, unsigned int commands_started, char *commands,
|
||||||
|
unsigned int commands_idx, int two_colon, char *filename,
|
||||||
|
unsigned int lineno, int set_default));
|
||||||
|
static char *find_semicolon PARAMS ((char *s));
|
||||||
|
|
||||||
/* Read in all the makefiles and return the chain of their names. */
|
/* Read in all the makefiles and return the chain of their names. */
|
||||||
|
|
||||||
@ -138,6 +147,7 @@ read_all_makefiles (makefiles)
|
|||||||
/* Set NAME to the start of next token and LENGTH to its length.
|
/* Set NAME to the start of next token and LENGTH to its length.
|
||||||
MAKEFILES is updated for finding remaining tokens. */
|
MAKEFILES is updated for finding remaining tokens. */
|
||||||
p = value;
|
p = value;
|
||||||
|
|
||||||
while ((name = find_next_token (&p, &length)) != 0)
|
while ((name = find_next_token (&p, &length)) != 0)
|
||||||
{
|
{
|
||||||
if (*p != '\0')
|
if (*p != '\0')
|
||||||
@ -176,7 +186,12 @@ read_all_makefiles (makefiles)
|
|||||||
if (num_makefiles == 0)
|
if (num_makefiles == 0)
|
||||||
{
|
{
|
||||||
static char *default_makefiles[] =
|
static char *default_makefiles[] =
|
||||||
|
#if VMS
|
||||||
|
/* all lower case since readdir() (the vms version) 'lowercasifies' */
|
||||||
|
{ "makefile.vms", "gnumakefile", "makefile", 0 };
|
||||||
|
#else
|
||||||
{ "GNUmakefile", "makefile", "Makefile", 0 };
|
{ "GNUmakefile", "makefile", "Makefile", 0 };
|
||||||
|
#endif
|
||||||
register char **p = default_makefiles;
|
register char **p = default_makefiles;
|
||||||
while (*p != 0 && !file_exists_p (*p))
|
while (*p != 0 && !file_exists_p (*p))
|
||||||
++p;
|
++p;
|
||||||
@ -302,7 +317,6 @@ read_makefile (filename, flags)
|
|||||||
/* If the makefile wasn't found and it's either a makefile from
|
/* If the makefile wasn't found and it's either a makefile from
|
||||||
the `MAKEFILES' variable or an included makefile,
|
the `MAKEFILES' variable or an included makefile,
|
||||||
search the included makefile search path for this makefile. */
|
search the included makefile search path for this makefile. */
|
||||||
|
|
||||||
if (infile == 0 && (flags & RM_INCLUDED) && *filename != '/')
|
if (infile == 0 && (flags & RM_INCLUDED) && *filename != '/')
|
||||||
{
|
{
|
||||||
register unsigned int i;
|
register unsigned int i;
|
||||||
@ -586,7 +600,7 @@ read_makefile (filename, flags)
|
|||||||
{
|
{
|
||||||
struct nameseq *next = files->next;
|
struct nameseq *next = files->next;
|
||||||
char *name = files->name;
|
char *name = files->name;
|
||||||
free (files);
|
free ((char *)files);
|
||||||
files = next;
|
files = next;
|
||||||
|
|
||||||
if (! read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
|
if (! read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
|
||||||
@ -1303,7 +1317,7 @@ record_files (filenames, pattern, pattern_percent, deps, commands_started,
|
|||||||
{
|
{
|
||||||
struct dep *nextd = d->next;
|
struct dep *nextd = d->next;
|
||||||
free (d->name);
|
free (d->name);
|
||||||
free (d);
|
free ((char *)d);
|
||||||
d = nextd;
|
d = nextd;
|
||||||
}
|
}
|
||||||
f->deps = 0;
|
f->deps = 0;
|
||||||
@ -1520,9 +1534,16 @@ parse_file_seq (stringp, stopchar, size, strip)
|
|||||||
register char *p = *stringp;
|
register char *p = *stringp;
|
||||||
char *q;
|
char *q;
|
||||||
char *name;
|
char *name;
|
||||||
char stopchars[2];
|
char stopchars[3];
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
stopchars[0] = ',';
|
||||||
|
stopchars[1] = stopchar;
|
||||||
|
stopchars[2] = '\0';
|
||||||
|
#else
|
||||||
stopchars[0] = stopchar;
|
stopchars[0] = stopchar;
|
||||||
stopchars[1] = '\0';
|
stopchars[1] = '\0';
|
||||||
|
#endif
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -1532,9 +1553,16 @@ parse_file_seq (stringp, stopchar, size, strip)
|
|||||||
break;
|
break;
|
||||||
if (*p == stopchar)
|
if (*p == stopchar)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Yes, find end of next name. */
|
/* Yes, find end of next name. */
|
||||||
q = p;
|
q = p;
|
||||||
p = find_char_unquote (q, stopchars, 1);
|
p = find_char_unquote (q, stopchars, 1);
|
||||||
|
#ifdef VMS
|
||||||
|
/* convert comma separated list to space separated */
|
||||||
|
if (p && *p == ',')
|
||||||
|
*p =' ';
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
/* For MS-DOS, skip a "C:\...". */
|
/* For MS-DOS, skip a "C:\...". */
|
||||||
if (stopchar == ':' && p != 0 && p[1] == '\\' && isalpha (p[-1]))
|
if (stopchar == ':' && p != 0 && p[1] == '\\' && isalpha (p[-1]))
|
||||||
@ -1544,8 +1572,13 @@ parse_file_seq (stringp, stopchar, size, strip)
|
|||||||
p = q + strlen (q);
|
p = q + strlen (q);
|
||||||
|
|
||||||
if (strip)
|
if (strip)
|
||||||
|
#ifdef VMS
|
||||||
|
/* Skip leading `[]'s. */
|
||||||
|
while (p - q > 2 && q[0] == '[' && q[1] == ']')
|
||||||
|
#else
|
||||||
/* Skip leading `./'s. */
|
/* Skip leading `./'s. */
|
||||||
while (p - q > 2 && q[0] == '.' && q[1] == '/')
|
while (p - q > 2 && q[0] == '.' && q[1] == '/')
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
q += 2; /* Skip "./". */
|
q += 2; /* Skip "./". */
|
||||||
while (q < p && *q == '/')
|
while (q < p && *q == '/')
|
||||||
@ -1556,10 +1589,40 @@ parse_file_seq (stringp, stopchar, size, strip)
|
|||||||
/* Extract the filename just found, and skip it. */
|
/* Extract the filename just found, and skip it. */
|
||||||
|
|
||||||
if (q == p)
|
if (q == p)
|
||||||
/* ".///" was stripped to "". */
|
/* ".///" was stripped to "". */
|
||||||
|
#ifdef VMS
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
name = savestring ("./", 2);
|
name = savestring ("./", 2);
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
|
#ifdef VMS
|
||||||
|
/* VMS filenames can have a ':' in them but they have to be '\'ed but we need
|
||||||
|
* to remove this '\' before we can use the filename.
|
||||||
|
* Savestring called because q may be read-only string constant.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char *qbase = savestring(q, strlen(q));
|
||||||
|
char *pbase = qbase + (p-q);
|
||||||
|
char *q1 = qbase;
|
||||||
|
char *q2 = q1;
|
||||||
|
char *p1 = pbase;
|
||||||
|
|
||||||
|
while (q1 != pbase)
|
||||||
|
{
|
||||||
|
if (*q1 == '\\' && *(q1+1) == ':')
|
||||||
|
{
|
||||||
|
q1++;
|
||||||
|
p1--;
|
||||||
|
}
|
||||||
|
*q2++ = *q1++;
|
||||||
|
}
|
||||||
|
name = savestring (qbase, p1 - qbase);
|
||||||
|
free (qbase);
|
||||||
|
}
|
||||||
|
#else
|
||||||
name = savestring (q, p - q);
|
name = savestring (q, p - q);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Add it to the front of the chain. */
|
/* Add it to the front of the chain. */
|
||||||
new1 = (struct nameseq *) xmalloc (size);
|
new1 = (struct nameseq *) xmalloc (size);
|
||||||
@ -1787,8 +1850,11 @@ construct_include_path (arg_dirs)
|
|||||||
char **arg_dirs;
|
char **arg_dirs;
|
||||||
{
|
{
|
||||||
register unsigned int i;
|
register unsigned int i;
|
||||||
|
#ifdef VAXC /* just don't ask ... */
|
||||||
|
stat_t stbuf;
|
||||||
|
#else
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
#endif
|
||||||
/* Table to hold the dirs. */
|
/* Table to hold the dirs. */
|
||||||
|
|
||||||
register unsigned int defsize = (sizeof (default_include_directories)
|
register unsigned int defsize = (sizeof (default_include_directories)
|
||||||
@ -1860,6 +1926,7 @@ char *
|
|||||||
tilde_expand (name)
|
tilde_expand (name)
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
|
#ifndef VMS
|
||||||
if (name[1] == '/' || name[1] == '\0')
|
if (name[1] == '/' || name[1] == '\0')
|
||||||
{
|
{
|
||||||
extern char *getenv ();
|
extern char *getenv ();
|
||||||
@ -1919,7 +1986,7 @@ tilde_expand (name)
|
|||||||
else if (userend != 0)
|
else if (userend != 0)
|
||||||
*userend = '/';
|
*userend = '/';
|
||||||
}
|
}
|
||||||
|
#endif /* !VMS */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2037,7 +2104,7 @@ multi_glob (chain, size)
|
|||||||
}
|
}
|
||||||
globfree (&gl);
|
globfree (&gl);
|
||||||
free (old->name);
|
free (old->name);
|
||||||
free (old);
|
free ((char *)old);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
62
readme.vms
Normal file
62
readme.vms
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
This is the VMS port of GNU Make version 3.74.
|
||||||
|
|
||||||
|
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
|
||||||
|
|
||||||
|
This port was done by Klaus Kämpf (kkaempf@didymus.rmi.de)
|
||||||
|
|
||||||
|
To build Make, simply type @makefile. This should compile all the
|
||||||
|
necessary files and link Make.
|
||||||
|
There is also a file called makefile.vms. If you already have GNU
|
||||||
|
Make 3.74 built you can just use Make with this makefile to rebuild.
|
||||||
|
|
||||||
|
Here are some notes about GNU Make for VMS:
|
||||||
|
|
||||||
|
Libraries are not supported. They were in GNU Make 3.60 but somehow I didn't
|
||||||
|
care porting the code. If there is enough interest, I'll do it at some
|
||||||
|
later time.
|
||||||
|
|
||||||
|
The variable $^ separates files with commas instead of spaces (It's the
|
||||||
|
natural thing to do for VMS).
|
||||||
|
|
||||||
|
See defaults.c for VMS default suffixes and my definitions for default
|
||||||
|
rules and variables.
|
||||||
|
|
||||||
|
The shell function is not implemented yet.
|
||||||
|
|
||||||
|
Load average routines haven't been implemented for VMS yet.
|
||||||
|
|
||||||
|
The default include directory for including other makefiles is
|
||||||
|
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
|
||||||
|
SYS$LIBRARY: instead; maybe it wouldn't work that way).
|
||||||
|
|
||||||
|
The default makefiles make looks for are: makefile.vms, gnumakefile, makefile.,
|
||||||
|
and gnumakefile. .
|
||||||
|
|
||||||
|
The stat() function and handling of time stamps in VMS is broken, so I
|
||||||
|
replaced it with a hack in vmsfunctions.c. I will provide a full rewrite
|
||||||
|
somewhere in the future. Be warned, the time resolution inside make is
|
||||||
|
less than what vms provides. This might be a problem on the faster Alphas.
|
||||||
|
|
||||||
|
You can use a : in a filename only if you preceed it with a backslash ('\').
|
||||||
|
E.g.- hobbes\:[bogas.files]
|
||||||
|
|
||||||
|
None of the stuff in vpath.c has been implemented yet.
|
||||||
|
|
||||||
|
Make ignores success, informational, or warning errors (-S-, -I-, or -W-).
|
||||||
|
But it will stop on -E- and -F- errors. (unless you do something to override
|
||||||
|
this in your makefile, or whatever).
|
||||||
|
|
||||||
|
Remote stuff isn't implemented yet.
|
||||||
|
|
||||||
|
Multiple line DCL commands, such as "if" statements, must be put inside
|
||||||
|
command files. You can run a command file by using \@.
|
||||||
|
|
||||||
|
|
||||||
|
VMS changes made for 3.74.3
|
||||||
|
|
||||||
|
Lots of default settings are adapted for VMS. See default.c.
|
||||||
|
|
||||||
|
Long command lines are now converted to command files.
|
||||||
|
|
||||||
|
Comma (',') as a separator is now allowed. See makefile.vms for an example.
|
||||||
|
|
52
remake.c
52
remake.c
@ -17,10 +17,10 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "commands.h"
|
#include "filedef.h"
|
||||||
#include "job.h"
|
#include "job.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "file.h"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
@ -29,17 +29,30 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int try_implicit_rule ();
|
#ifdef VMS
|
||||||
|
#include <starlet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int try_implicit_rule PARAMS ((struct file *file, unsigned int depth));
|
||||||
|
|
||||||
|
|
||||||
/* Incremented when a command is started (under -n, when one would be). */
|
/* Incremented when a command is started (under -n, when one would be). */
|
||||||
unsigned int commands_started = 0;
|
unsigned int commands_started = 0;
|
||||||
|
|
||||||
static int update_file (), update_file_1 (), check_dep (), touch_file ();
|
static int update_file PARAMS ((struct file *file, unsigned int depth));
|
||||||
static void remake_file ();
|
static int update_file_1 PARAMS ((struct file *file, unsigned int depth));
|
||||||
static time_t name_mtime ();
|
static int check_dep PARAMS ((struct file *file, unsigned int depth, time_t this_mtime, int *must_make_ptr));
|
||||||
static int library_search ();
|
static int touch_file PARAMS ((struct file *file));
|
||||||
extern time_t f_mtime ();
|
static void remake_file PARAMS ((struct file *file));
|
||||||
|
static time_t name_mtime PARAMS ((char *name));
|
||||||
|
static int library_search PARAMS ((char **lib, time_t *mtime_ptr));
|
||||||
|
|
||||||
|
extern time_t f_mtime PARAMS ((struct file *file, int search));
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
extern int vms_stat PARAMS ((char *name, struct stat *buf));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing
|
/* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing
|
||||||
was done, 0 if all goals were updated successfully, or 1 if a goal failed.
|
was done, 0 if all goals were updated successfully, or 1 if a goal failed.
|
||||||
@ -100,6 +113,7 @@ update_goal_chain (goals, makefiles)
|
|||||||
/* Iterate over all double-colon entries for this file. */
|
/* Iterate over all double-colon entries for this file. */
|
||||||
struct file *file = g->file;
|
struct file *file = g->file;
|
||||||
int stop, any_not_updated = 0;
|
int stop, any_not_updated = 0;
|
||||||
|
|
||||||
for (file = g->file->double_colon ? g->file->double_colon : g->file;
|
for (file = g->file->double_colon ? g->file->double_colon : g->file;
|
||||||
file != NULL;
|
file != NULL;
|
||||||
file = file->prev)
|
file = file->prev)
|
||||||
@ -108,7 +122,6 @@ update_goal_chain (goals, makefiles)
|
|||||||
int x;
|
int x;
|
||||||
time_t mtime = MTIME (file);
|
time_t mtime = MTIME (file);
|
||||||
check_renamed (file);
|
check_renamed (file);
|
||||||
|
|
||||||
if (makefiles)
|
if (makefiles)
|
||||||
{
|
{
|
||||||
if (file->cmd_target)
|
if (file->cmd_target)
|
||||||
@ -229,7 +242,6 @@ update_goal_chain (goals, makefiles)
|
|||||||
just_print_flag = n;
|
just_print_flag = n;
|
||||||
job_slots = j;
|
job_slots = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1015,12 +1027,28 @@ f_mtime (file, search)
|
|||||||
unrecoverably absent. */
|
unrecoverably absent. */
|
||||||
|
|
||||||
static time_t now;
|
static time_t now;
|
||||||
|
#ifdef VMS
|
||||||
|
/* Handle vms 64bit to 32bit time hack introduced in vms_stat() ... */
|
||||||
|
static unsigned long vms_now[2]; /* assumes 32 bit long ! */
|
||||||
|
static int vms_now_set = 0;
|
||||||
|
|
||||||
|
if (!vms_now_set)
|
||||||
|
{
|
||||||
|
sys$gettim(vms_now);
|
||||||
|
now = ((vms_now[0]>>24) & 0xff) + ((vms_now[1]<<8) & 0xffffff00);
|
||||||
|
vms_now_set = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (mtime > now && ! file->updated)
|
if (mtime > now && ! file->updated)
|
||||||
{
|
{
|
||||||
/* This file's time appears to be in the future.
|
/* This file's time appears to be in the future.
|
||||||
Update our concept of the present, and compare again. */
|
Update our concept of the present, and compare again. */
|
||||||
|
#ifndef VMS
|
||||||
extern time_t time ();
|
extern time_t time ();
|
||||||
if (mtime > time (&now))
|
if (mtime > time (&now))
|
||||||
|
#else
|
||||||
|
if ((mtime != -1) && (mtime > now))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
error ("*** File `%s' has modification time in the future",
|
error ("*** File `%s' has modification time in the future",
|
||||||
file->name);
|
file->name);
|
||||||
@ -1050,7 +1078,11 @@ name_mtime (name)
|
|||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
if (vms_stat (name, &st) < 0)
|
||||||
|
#else
|
||||||
if (stat (name, &st) < 0)
|
if (stat (name, &st) < 0)
|
||||||
|
#endif
|
||||||
return (time_t) -1;
|
return (time_t) -1;
|
||||||
|
|
||||||
return (time_t) st.st_mtime;
|
return (time_t) st.st_mtime;
|
||||||
|
@ -17,6 +17,8 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
|
#include "filedef.h"
|
||||||
|
#include "job.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
|
|
||||||
|
23
rule.c
23
rule.c
@ -17,13 +17,14 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "commands.h"
|
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
|
#include "job.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
|
|
||||||
static void freerule ();
|
static void freerule PARAMS ((struct rule *rule, struct rule *lastrule));
|
||||||
|
|
||||||
/* Chain of all pattern rules. */
|
/* Chain of all pattern rules. */
|
||||||
|
|
||||||
@ -96,9 +97,13 @@ count_implicit_rule_limits ()
|
|||||||
for (dep = rule->deps; dep != 0; dep = dep->next)
|
for (dep = rule->deps; dep != 0; dep = dep->next)
|
||||||
{
|
{
|
||||||
unsigned int len = strlen (dep->name);
|
unsigned int len = strlen (dep->name);
|
||||||
char *p = rindex (dep->name, '/');
|
|
||||||
char *p2 = p != 0 ? index (dep->name, '%') : 0;
|
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
char *p = rindex (dep->name, ']');
|
||||||
|
#else
|
||||||
|
char *p = rindex (dep->name, '/');
|
||||||
|
#endif
|
||||||
|
char *p2 = p != 0 ? index (dep->name, '%') : 0;
|
||||||
ndeps++;
|
ndeps++;
|
||||||
|
|
||||||
if (len > max_pattern_dep_length)
|
if (len > max_pattern_dep_length)
|
||||||
@ -125,7 +130,11 @@ count_implicit_rule_limits ()
|
|||||||
nonexistent subdirectory. */
|
nonexistent subdirectory. */
|
||||||
|
|
||||||
dep->changed = !dir_file_exists_p (name, "");
|
dep->changed = !dir_file_exists_p (name, "");
|
||||||
|
#ifdef VMS
|
||||||
|
if (dep->changed && *name == ']')
|
||||||
|
#else
|
||||||
if (dep->changed && *name == '/')
|
if (dep->changed && *name == '/')
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* The name is absolute and the directory does not exist.
|
/* The name is absolute and the directory does not exist.
|
||||||
This rule can never possibly match, since this dependency
|
This rule can never possibly match, since this dependency
|
||||||
@ -173,7 +182,11 @@ convert_suffix_rule (target, source, cmds)
|
|||||||
/* Special case: TARGET being nil means we are defining a
|
/* Special case: TARGET being nil means we are defining a
|
||||||
`.X.a' suffix rule; the target pattern is always `(%.o)'. */
|
`.X.a' suffix rule; the target pattern is always `(%.o)'. */
|
||||||
{
|
{
|
||||||
|
#ifdef VMS
|
||||||
|
targname = savestring ("(%.obj)", 7);
|
||||||
|
#else
|
||||||
targname = savestring ("(%.o)", 5);
|
targname = savestring ("(%.o)", 5);
|
||||||
|
#endif
|
||||||
targpercent = targname + 1;
|
targpercent = targname + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
4
rule.h
4
rule.h
@ -49,5 +49,5 @@ extern struct file *suffix_file;
|
|||||||
extern unsigned int maxsuffix;
|
extern unsigned int maxsuffix;
|
||||||
|
|
||||||
|
|
||||||
extern void install_pattern_rule ();
|
extern void install_pattern_rule PARAMS ((struct pspec *p, int terminal));
|
||||||
int new_pattern_rule ();
|
extern int new_pattern_rule PARAMS ((struct rule *rule, int override));
|
||||||
|
10
variable.c
10
variable.c
@ -17,10 +17,11 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
|
#include "dep.h"
|
||||||
|
#include "filedef.h"
|
||||||
|
#include "job.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "dep.h"
|
|
||||||
#include "file.h"
|
|
||||||
|
|
||||||
/* Hash table of all global variable definitions. */
|
/* Hash table of all global variable definitions. */
|
||||||
|
|
||||||
@ -39,6 +40,11 @@ static struct variable_set global_variable_set
|
|||||||
static struct variable_set_list global_setlist
|
static struct variable_set_list global_setlist
|
||||||
= { 0, &global_variable_set };
|
= { 0, &global_variable_set };
|
||||||
struct variable_set_list *current_variable_set_list = &global_setlist;
|
struct variable_set_list *current_variable_set_list = &global_setlist;
|
||||||
|
|
||||||
|
static struct variable *define_variable_in_set PARAMS ((char *name, unsigned int length,
|
||||||
|
char *value, enum variable_origin origin,
|
||||||
|
int recursive, struct variable_set *set));
|
||||||
|
|
||||||
|
|
||||||
/* Implement variables. */
|
/* Implement variables. */
|
||||||
|
|
||||||
|
49
variable.h
49
variable.h
@ -70,31 +70,40 @@ struct variable_set_list
|
|||||||
|
|
||||||
extern struct variable_set_list *current_variable_set_list;
|
extern struct variable_set_list *current_variable_set_list;
|
||||||
|
|
||||||
|
/* expand.c */
|
||||||
extern void push_new_variable_scope (), pop_variable_scope ();
|
extern char *variable_buffer_output PARAMS ((char *ptr, char *string, unsigned int length));
|
||||||
|
extern char *variable_expand PARAMS ((char *line));
|
||||||
extern int handle_function ();
|
extern char *variable_expand_for_file PARAMS ((char *line, struct file *file));
|
||||||
|
extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file));
|
||||||
extern char *variable_buffer_output ();
|
|
||||||
extern char *variable_expand (), *variable_expand_for_file ();
|
|
||||||
extern char *allocated_variable_expand_for_file ();
|
|
||||||
#define allocated_variable_expand(line) \
|
#define allocated_variable_expand(line) \
|
||||||
allocated_variable_expand_for_file (line, (struct file *) 0)
|
allocated_variable_expand_for_file (line, (struct file *) 0)
|
||||||
extern char *expand_argument ();
|
extern char *expand_argument PARAMS ((char *str, char *end));
|
||||||
|
|
||||||
extern void define_automatic_variables ();
|
/* function.c */
|
||||||
extern void initialize_file_variables ();
|
extern int handle_function PARAMS ((char **op, char **stringp));
|
||||||
extern void print_file_variables ();
|
extern int pattern_matches PARAMS ((char *pattern, char *percent, char *word));
|
||||||
|
extern char *subst_expand PARAMS ((char *o, char *text, char *subst, char *replace,
|
||||||
|
unsigned int slen, unsigned int rlen, int by_word, int suffix_only));
|
||||||
|
extern char *patsubst_expand PARAMS ((char *o, char *text, char *pattern, char *replace,
|
||||||
|
char *pattern_percent, char *replace_percent));
|
||||||
|
|
||||||
extern void merge_variable_set_lists ();
|
/* expand.c */
|
||||||
|
extern char *recursively_expand PARAMS ((struct variable *v));
|
||||||
|
|
||||||
extern struct variable *try_variable_definition ();
|
/* variable.c */
|
||||||
|
extern void push_new_variable_scope PARAMS ((void));
|
||||||
|
extern void pop_variable_scope PARAMS ((void));
|
||||||
|
extern void define_automatic_variables PARAMS ((void));
|
||||||
|
extern void initialize_file_variables PARAMS ((struct file *file));
|
||||||
|
extern void print_file_variables PARAMS ((struct file *file));
|
||||||
|
extern void merge_variable_set_lists PARAMS ((struct variable_set_list **setlist0, struct variable_set_list *setlist1));
|
||||||
|
extern struct variable *try_variable_definition PARAMS ((char *filename, unsigned int lineno, char *line, enum variable_origin origin));
|
||||||
|
|
||||||
extern struct variable *lookup_variable (), *define_variable ();
|
extern struct variable *lookup_variable PARAMS ((char *name, unsigned int length));
|
||||||
extern struct variable *define_variable_for_file ();
|
extern struct variable *define_variable PARAMS ((char *name, unsigned int length, char *value,
|
||||||
|
enum variable_origin origin, int recursive));
|
||||||
|
extern struct variable *define_variable_for_file PARAMS ((char *name, unsigned int length,
|
||||||
|
char *value, enum variable_origin origin, int recursive, struct file *file));
|
||||||
|
extern char **target_environment PARAMS ((struct file *file));
|
||||||
|
|
||||||
extern int pattern_matches ();
|
|
||||||
extern char *subst_expand (), *patsubst_expand (), *recursively_expand ();
|
|
||||||
|
|
||||||
extern char **target_environment ();
|
|
||||||
extern int export_all_variables;
|
extern int export_all_variables;
|
||||||
|
40
vmsdir.h
Normal file
40
vmsdir.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* dirent.h for vms */
|
||||||
|
|
||||||
|
#include <rms.h>
|
||||||
|
|
||||||
|
#define MAXNAMLEN 255
|
||||||
|
|
||||||
|
typedef unsigned long u_long;
|
||||||
|
typedef unsigned short u_short;
|
||||||
|
|
||||||
|
struct direct {
|
||||||
|
off_t d_off;
|
||||||
|
u_long d_fileno;
|
||||||
|
u_short d_reclen;
|
||||||
|
u_short d_namlen;
|
||||||
|
char d_name[MAXNAMLEN + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef DIRSIZ
|
||||||
|
#define DIRSIZ(dp) \
|
||||||
|
(((sizeof (struct direct) - (MAXNAMLEN+1) + ((dp)->d_namlen+1)) + 3) & ~3)
|
||||||
|
|
||||||
|
#define d_ino d_fileno /* compatability */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions for library routines operating on directories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct FAB DIR;
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
extern DIR *opendir PARAMS (());
|
||||||
|
extern struct direct *readdir PARAMS ((DIR *dfd));
|
||||||
|
#define rewinddir(dirp) seekdir((dirp), (long)0)
|
||||||
|
extern int closedir PARAMS ((DIR *dfd));
|
||||||
|
extern char *vmsify PARAMS ((char *name, int type));
|
||||||
|
|
||||||
|
/* EOF */
|
234
vmsfunctions.c
Normal file
234
vmsfunctions.c
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#define KDEBUG 0
|
||||||
|
/* vmsfunctions.c */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "make.h"
|
||||||
|
#ifdef __DECC
|
||||||
|
#include <starlet.h>
|
||||||
|
#endif
|
||||||
|
#include <descrip.h>
|
||||||
|
#include <rms.h>
|
||||||
|
#include <iodef.h>
|
||||||
|
#include <atrdef.h>
|
||||||
|
#include <fibdef.h>
|
||||||
|
#include "vmsdir.h"
|
||||||
|
|
||||||
|
DIR *opendir(char *dspec)
|
||||||
|
{
|
||||||
|
static struct FAB *dfab;
|
||||||
|
struct NAM *dnam;
|
||||||
|
char *searchspec;
|
||||||
|
|
||||||
|
if ((dfab = (struct FAB *)xmalloc(sizeof (struct FAB))) == NULL) {
|
||||||
|
printf("Error mallocing for FAB\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
if ((dnam = (struct NAM *)xmalloc(sizeof (struct NAM))) == NULL) {
|
||||||
|
printf("Error mallocing for NAM\n");
|
||||||
|
free(dfab);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
if ((searchspec = (char *)xmalloc(MAXNAMLEN+1)) == NULL) {
|
||||||
|
printf("Error mallocing for searchspec\n");
|
||||||
|
free(dfab);
|
||||||
|
free(dnam);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(searchspec,"%s*.*;",dspec);
|
||||||
|
|
||||||
|
*dfab = cc$rms_fab;
|
||||||
|
dfab->fab$l_fna = searchspec;
|
||||||
|
dfab->fab$b_fns = strlen(searchspec);
|
||||||
|
dfab->fab$l_nam = dnam;
|
||||||
|
|
||||||
|
*dnam = cc$rms_nam;
|
||||||
|
dnam->nam$l_esa = searchspec;
|
||||||
|
dnam->nam$b_ess = MAXNAMLEN;
|
||||||
|
|
||||||
|
if (!(sys$parse(dfab) & 1)) {
|
||||||
|
free(dfab);
|
||||||
|
free(dnam);
|
||||||
|
free(searchspec);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(dfab);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#define uppercasify(str) { char *tmp; for(tmp = (str); *tmp != '\0'; tmp++) if(islower(*tmp)) *tmp = toupper(*tmp); }
|
||||||
|
|
||||||
|
struct direct *readdir(DIR *dfd)
|
||||||
|
{
|
||||||
|
static struct direct *dentry;
|
||||||
|
static char resultspec[MAXNAMLEN+1];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ((dentry = (struct direct *)xmalloc(sizeof (struct direct))) == NULL) {
|
||||||
|
printf("Error mallocing for direct\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
dfd->fab$l_nam->nam$l_rsa = resultspec;
|
||||||
|
dfd->fab$l_nam->nam$b_rss = MAXNAMLEN;
|
||||||
|
|
||||||
|
if (debug_flag)
|
||||||
|
printf(".");
|
||||||
|
|
||||||
|
if (!((i = sys$search(dfd)) & 1)) {
|
||||||
|
if (debug_flag)
|
||||||
|
printf("sys$search failed with %d\n", i);
|
||||||
|
free(dentry);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
dentry->d_off = 0;
|
||||||
|
if (dfd->fab$l_nam->nam$w_fid == 0)
|
||||||
|
dentry->d_fileno = 1;
|
||||||
|
else dentry->d_fileno = dfd->fab$l_nam->nam$w_fid[0]
|
||||||
|
+dfd->fab$l_nam->nam$w_fid[1]<<16;
|
||||||
|
dentry->d_reclen = sizeof (struct direct);
|
||||||
|
/*
|
||||||
|
if (!strcmp(dfd->fab$l_nam->nam$l_type,".DIR"))
|
||||||
|
dentry->d_namlen = dfd->fab$l_nam->nam$b_name;
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
dentry->d_namlen = dfd->fab$l_nam->nam$b_name+dfd->fab$l_nam->nam$b_type;
|
||||||
|
strncpy(dentry->d_name,dfd->fab$l_nam->nam$l_name,dentry->d_namlen);
|
||||||
|
dentry->d_name[dentry->d_namlen] = '\0';
|
||||||
|
uppercasify(dentry->d_name);
|
||||||
|
/* uvUnFixRCSSeparator(dentry->d_name);*/
|
||||||
|
|
||||||
|
return(dentry);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(DIR *dfd)
|
||||||
|
{
|
||||||
|
if (dfd != NULL) {
|
||||||
|
if (dfd->fab$l_nam != NULL)
|
||||||
|
free(dfd->fab$l_nam->nam$l_esa);
|
||||||
|
free(dfd->fab$l_nam);
|
||||||
|
free(dfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *getwd(char *cwd)
|
||||||
|
{
|
||||||
|
static char buf[512];
|
||||||
|
|
||||||
|
if (cwd)
|
||||||
|
return(getcwd(cwd,512));
|
||||||
|
else
|
||||||
|
return(getcwd(buf,512));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vms_stat (name, buf)
|
||||||
|
char *name;
|
||||||
|
struct stat *buf;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
static struct FAB Fab;
|
||||||
|
static struct NAM Nam;
|
||||||
|
static struct fibdef Fib; /* short fib */
|
||||||
|
static struct dsc$descriptor FibDesc =
|
||||||
|
{sizeof(Fib), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *)&Fib};
|
||||||
|
static struct dsc$descriptor_s DevDesc =
|
||||||
|
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, &Nam.nam$t_dvi[1]};
|
||||||
|
static char EName[NAM$C_MAXRSS];
|
||||||
|
static char RName[NAM$C_MAXRSS];
|
||||||
|
static struct dsc$descriptor_s FileName =
|
||||||
|
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
|
||||||
|
static struct dsc$descriptor_s string =
|
||||||
|
{0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
|
||||||
|
static unsigned long Rdate[2];
|
||||||
|
static unsigned long Cdate[2];
|
||||||
|
static struct atrdef Atr[] = {
|
||||||
|
{sizeof(Rdate),ATR$C_REVDATE,&Rdate[0]}, /* Revision date */
|
||||||
|
{sizeof(Cdate),ATR$C_CREDATE,&Cdate[0]}, /* Creation date */
|
||||||
|
{0,0,0}
|
||||||
|
};
|
||||||
|
static short int DevChan;
|
||||||
|
static short int iosb[4];
|
||||||
|
|
||||||
|
name = vmsify (name, 0);
|
||||||
|
|
||||||
|
/* initialize RMS structures, we need a NAM to retrieve the FID */
|
||||||
|
Fab = cc$rms_fab;
|
||||||
|
Fab.fab$l_fna = name ; /* name of file */
|
||||||
|
Fab.fab$b_fns = strlen(name);
|
||||||
|
Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
|
||||||
|
|
||||||
|
Nam = cc$rms_nam;
|
||||||
|
Nam.nam$l_esa = EName; /* expanded filename */
|
||||||
|
Nam.nam$b_ess = sizeof(EName);
|
||||||
|
Nam.nam$l_rsa = RName; /* resultant filename */
|
||||||
|
Nam.nam$b_rss = sizeof(RName);
|
||||||
|
|
||||||
|
/* do $PARSE and $SEARCH here */
|
||||||
|
status = sys$parse(&Fab);
|
||||||
|
if (!(status & 1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
|
||||||
|
status = sys$assign(&DevDesc,&DevChan,0,0);
|
||||||
|
if (!(status & 1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FileName.dsc$a_pointer = Nam.nam$l_name;
|
||||||
|
FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
|
||||||
|
|
||||||
|
/* Initialize the FIB */
|
||||||
|
for (i=0;i<3;i++)
|
||||||
|
{
|
||||||
|
#if __DECC
|
||||||
|
Fib.fib$w_fid[i]=Nam.nam$w_fid[i];
|
||||||
|
Fib.fib$w_did[i]=Nam.nam$w_did[i];
|
||||||
|
#else
|
||||||
|
Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
|
||||||
|
Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
|
||||||
|
&FibDesc,&FileName,0,0,&Atr,0);
|
||||||
|
if (!(status & 1))
|
||||||
|
return -1;
|
||||||
|
status = iosb[0];
|
||||||
|
if (!(status & 1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
status = stat (name, buf);
|
||||||
|
if (status)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
buf->st_mtime = ((Rdate[0]>>24) & 0xff) + ((Rdate[1]<<8) & 0xffffff00);
|
||||||
|
buf->st_ctime = ((Cdate[0]>>24) & 0xff) + ((Cdate[1]<<8) & 0xffffff00);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
cvt_time(tval)
|
||||||
|
unsigned long tval;
|
||||||
|
{
|
||||||
|
static long int date[2];
|
||||||
|
static char str[27];
|
||||||
|
static struct dsc$descriptor date_str =
|
||||||
|
{26, DSC$K_DTYPE_T, DSC$K_CLASS_S, str};
|
||||||
|
|
||||||
|
date[0] = (tval & 0xff) << 24;
|
||||||
|
date[1] = ((tval>>8) & 0xffffff);
|
||||||
|
|
||||||
|
if ((date[0]==0) && (date[1]==0))
|
||||||
|
return("never");
|
||||||
|
|
||||||
|
sys$asctim(0,&date_str,date,0);
|
||||||
|
str[26]='\0';
|
||||||
|
|
||||||
|
return(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
925
vmsify.c
Normal file
925
vmsify.c
Normal file
@ -0,0 +1,925 @@
|
|||||||
|
/*
|
||||||
|
vmsify.c
|
||||||
|
|
||||||
|
Module for vms <-> unix file name conversion
|
||||||
|
|
||||||
|
Written by Klaus Kämpf (kkaempf@didymus.rmi.de)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#if VMS
|
||||||
|
#include <unixlib.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <jpidef.h>
|
||||||
|
#include <descrip.h>
|
||||||
|
#include <uaidef.h>
|
||||||
|
#include <ssdef.h>
|
||||||
|
#include <starlet.h>
|
||||||
|
#include <lib$routines.h>
|
||||||
|
/* Initialize a string descriptor (struct dsc$descriptor_s) for an
|
||||||
|
arbitrary string. ADDR is a pointer to the first character
|
||||||
|
of the string, and LEN is the length of the string. */
|
||||||
|
|
||||||
|
#define INIT_DSC_S(dsc, addr, len) do { \
|
||||||
|
(dsc).dsc$b_dtype = DSC$K_DTYPE_T; \
|
||||||
|
(dsc).dsc$b_class = DSC$K_CLASS_S; \
|
||||||
|
(dsc).dsc$w_length = (len); \
|
||||||
|
(dsc).dsc$a_pointer = (addr); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Initialize a string descriptor (struct dsc$descriptor_s) for a
|
||||||
|
NUL-terminated string. S is a pointer to the string; the length
|
||||||
|
is determined by calling strlen(). */
|
||||||
|
|
||||||
|
#define INIT_DSC_CSTRING(dsc, s) INIT_DSC_S(dsc, s, strlen(s))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
copy 'from' to 'to' up to but not including 'upto'
|
||||||
|
return 0 if eos on from
|
||||||
|
return 1 if upto found
|
||||||
|
|
||||||
|
return 'to' at last char + 1
|
||||||
|
return 'from' at match + 1 or eos if no match
|
||||||
|
|
||||||
|
if as_dir == 1, change all '.' to '_'
|
||||||
|
else change all '.' but the last to '_'
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
copyto (char **to, char **from, char upto, int as_dir)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
s = strrchr (*from, '.');
|
||||||
|
|
||||||
|
while (**from)
|
||||||
|
{
|
||||||
|
if (**from == upto)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
(*from)++;
|
||||||
|
}
|
||||||
|
while (**from == upto);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (**from == '.')
|
||||||
|
{
|
||||||
|
if ((as_dir == 1)
|
||||||
|
|| (*from != s))
|
||||||
|
**to = '_';
|
||||||
|
else
|
||||||
|
**to = '.';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (islower (**from))
|
||||||
|
**to = toupper (**from);
|
||||||
|
else
|
||||||
|
**to = **from;
|
||||||
|
}
|
||||||
|
(*to)++;
|
||||||
|
(*from)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
get translation of logical name
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char *
|
||||||
|
trnlog (char *name)
|
||||||
|
{
|
||||||
|
int stat;
|
||||||
|
static char reslt[1024];
|
||||||
|
$DESCRIPTOR (reslt_dsc, reslt);
|
||||||
|
short resltlen;
|
||||||
|
struct dsc$descriptor_s name_dsc;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
INIT_DSC_CSTRING (name_dsc, name);
|
||||||
|
|
||||||
|
stat = lib$sys_trnlog (&name_dsc, &resltlen, &reslt_dsc);
|
||||||
|
|
||||||
|
if ((stat&1) == 0)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (stat == SS$_NOTRAN)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
reslt[resltlen] = '\0';
|
||||||
|
|
||||||
|
s = (char *)malloc (resltlen+1);
|
||||||
|
if (s == 0)
|
||||||
|
return "";
|
||||||
|
strcpy (s, reslt);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum namestate { N_START, N_DEVICE, N_OPEN, N_DOT, N_CLOSED, N_DONE };
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert unix style name to vms style
|
||||||
|
type = 0 -> name is a full name (directory and filename part)
|
||||||
|
type = 1 -> name is a directory
|
||||||
|
type = 2 -> name is a filename without directory
|
||||||
|
|
||||||
|
The following conversions are applied
|
||||||
|
(0) (1) (2)
|
||||||
|
input full name dir name file name
|
||||||
|
|
||||||
|
1 ./ <cwd> [] <current directory>.dir
|
||||||
|
2 ../ <home of cwd> <home of cwd> <home of cwd>.dir
|
||||||
|
|
||||||
|
3 // <dev of cwd>: <dev of cwd>:[000000] <dev of cwd>:000000.dir
|
||||||
|
4 //a a: a: a:
|
||||||
|
5 //a/ a: a: a:000000.dir
|
||||||
|
|
||||||
|
9 / [000000] [000000] 000000.dir
|
||||||
|
10 /a [000000]a [a] [000000]a
|
||||||
|
11 /a/ [a] [a] [000000]a.dir
|
||||||
|
12 /a/b [a]b [a.b] [a]b
|
||||||
|
13 /a/b/ [a.b] [a.b] [a]b.dir
|
||||||
|
14 /a/b/c [a.b]c [a.b.c] [a.b]c
|
||||||
|
15 /a/b/c/ [a.b.c] [a.b.c] [a.b]c.dir
|
||||||
|
|
||||||
|
16 a a [.a] a
|
||||||
|
17 a/ [.a] [.a] a.dir
|
||||||
|
18 a/b [.a]b [.a.b] [.a]b
|
||||||
|
19 a/b/ [.a.b] [.a.b] [.a]b.dir
|
||||||
|
20 a/b/c [.a.b]c [.a.b.c] [.a.b]c
|
||||||
|
21 a/b/c/ [.a.b.c] [.a.b.c] [.a.b]c.dir
|
||||||
|
|
||||||
|
22 a.b.c a_b.c [.a_b_c] a_b_c.dir
|
||||||
|
|
||||||
|
23 [x][y]z [x.y]z [x.y]z [x.y]z
|
||||||
|
24 [x][.y]z [x.y]z [x.y]z [x.y]z
|
||||||
|
|
||||||
|
25 filenames with '$' are left unchanged if they contain no '/'
|
||||||
|
25 filenames with ':' are left unchanged
|
||||||
|
26 filenames with a single pair of '[' ']' are left unchanged
|
||||||
|
|
||||||
|
the input string is not written to
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
vmsify (name, type)
|
||||||
|
char *name;
|
||||||
|
int type;
|
||||||
|
{
|
||||||
|
/* max 255 device
|
||||||
|
max 39 directory
|
||||||
|
max 39 filename
|
||||||
|
max 39 filetype
|
||||||
|
max 5 version
|
||||||
|
*/
|
||||||
|
#define MAXPATHLEN 512
|
||||||
|
|
||||||
|
enum namestate nstate;
|
||||||
|
static char vmsname[MAXPATHLEN+1];
|
||||||
|
char *fptr;
|
||||||
|
char *vptr;
|
||||||
|
char *s,*s1;
|
||||||
|
int as_dir;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (name == 0)
|
||||||
|
return 0;
|
||||||
|
fptr = name;
|
||||||
|
vptr = vmsname;
|
||||||
|
nstate = N_START;
|
||||||
|
|
||||||
|
/* case 25a */
|
||||||
|
|
||||||
|
s = strpbrk (name, "$:");
|
||||||
|
if (s != 0)
|
||||||
|
{
|
||||||
|
if (*s == '$')
|
||||||
|
{
|
||||||
|
if (strchr (name, '/') == 0)
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* case 26 */
|
||||||
|
|
||||||
|
s = strchr (name, '[');
|
||||||
|
|
||||||
|
if (s != 0)
|
||||||
|
{
|
||||||
|
s1 = strchr (s+1, '[');
|
||||||
|
if (s1 == 0)
|
||||||
|
{
|
||||||
|
return name; /* single [, keep unchanged */
|
||||||
|
}
|
||||||
|
s1--;
|
||||||
|
if (*s1 != ']')
|
||||||
|
{
|
||||||
|
return name; /* not ][, keep unchanged */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we have ][ */
|
||||||
|
|
||||||
|
s = name;
|
||||||
|
|
||||||
|
/* s -> starting char
|
||||||
|
s1 -> ending ']' */
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
strncpy (vptr, s, s1-s); /* copy up to but not including ']' */
|
||||||
|
vptr += s1-s;
|
||||||
|
if (*s1 == 0)
|
||||||
|
break;
|
||||||
|
s = s1 + 1; /* s -> char behind ']' */
|
||||||
|
if (*s != '[') /* was '][' ? */
|
||||||
|
break; /* no, last ] found, exit */
|
||||||
|
s++;
|
||||||
|
if (*s != '.')
|
||||||
|
*vptr++ = '.';
|
||||||
|
s1 = strchr (s, ']');
|
||||||
|
if (s1 == 0) /* no closing ] */
|
||||||
|
s1 = s + strlen (s);
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
*vptr++ = ']';
|
||||||
|
|
||||||
|
fptr = s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else /* no [ in name */
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
int state;
|
||||||
|
int rooted = 1; /* flag if logical is rooted, else insert [000000] */
|
||||||
|
|
||||||
|
state = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case 0: /* start of loop */
|
||||||
|
if (*fptr == '/')
|
||||||
|
{
|
||||||
|
fptr++;
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
else if (*fptr == '.')
|
||||||
|
{
|
||||||
|
fptr++;
|
||||||
|
state = 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* '/' at start */
|
||||||
|
if (*fptr == '/')
|
||||||
|
{
|
||||||
|
fptr++;
|
||||||
|
state = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* no '/' at start */
|
||||||
|
s = strchr (fptr, '/');
|
||||||
|
if (s == 0) /* no '/' (16) */
|
||||||
|
{
|
||||||
|
if (type == 1)
|
||||||
|
{
|
||||||
|
strcpy (vptr, "[.");
|
||||||
|
vptr += 2;
|
||||||
|
}
|
||||||
|
copyto (&vptr, &fptr, 0, (type==1));
|
||||||
|
if (type == 1)
|
||||||
|
*vptr++ = ']';
|
||||||
|
state = -1;
|
||||||
|
}
|
||||||
|
else /* found '/' (17..21) */
|
||||||
|
{
|
||||||
|
if ((type == 2)
|
||||||
|
&& (*(s+1) == 0)) /* 17(2) */
|
||||||
|
{
|
||||||
|
copyto (&vptr, &fptr, '/', 1);
|
||||||
|
state = 7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (vptr, "[.");
|
||||||
|
nstate = N_DOT;
|
||||||
|
vptr += 2;
|
||||||
|
copyto (&vptr, &fptr, '/', 1);
|
||||||
|
state = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: /* '//' at start */
|
||||||
|
while (*fptr == '/') /* collapse all '/' */
|
||||||
|
fptr++;
|
||||||
|
if (*fptr == 0) /* just // */
|
||||||
|
{
|
||||||
|
char cwdbuf[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
s1 = getcwd(cwdbuf, MAXPATHLEN);
|
||||||
|
if (s1 == 0)
|
||||||
|
{
|
||||||
|
return ""; /* FIXME, err getcwd */
|
||||||
|
}
|
||||||
|
s = strchr (s1, ':');
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
return ""; /* FIXME, err no device */
|
||||||
|
}
|
||||||
|
strncpy (vptr, s1, s-s1+1);
|
||||||
|
vptr += s-s1+1;
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = vptr;
|
||||||
|
|
||||||
|
if (copyto (&vptr, &fptr, '/', 1) == 0) /* copy device part */
|
||||||
|
{
|
||||||
|
*vptr++ = ':';
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*vptr = ':';
|
||||||
|
nstate = N_DEVICE;
|
||||||
|
if (*fptr == 0) /* just '//a/' */
|
||||||
|
{
|
||||||
|
strcpy (vptr+1, "[000000]");
|
||||||
|
vptr += 9;
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*vptr = 0;
|
||||||
|
/* check logical for [000000] insertion */
|
||||||
|
s1 = trnlog (s);
|
||||||
|
if (*s1 != 0)
|
||||||
|
{ /* found translation */
|
||||||
|
char *s2;
|
||||||
|
for (;;) /* loop over all nested logicals */
|
||||||
|
{
|
||||||
|
s2 = s1 + strlen (s1) - 1;
|
||||||
|
if (*s2 == ':') /* translation ends in ':' */
|
||||||
|
{
|
||||||
|
s2 = trnlog (s1);
|
||||||
|
free (s1);
|
||||||
|
if (*s2 == 0)
|
||||||
|
{
|
||||||
|
rooted = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s1 = s2;
|
||||||
|
continue; /* next iteration */
|
||||||
|
}
|
||||||
|
if (*s2 == ']') /* translation ends in ']' */
|
||||||
|
{
|
||||||
|
if (*(s2-1) == '.') /* ends in '.]' */
|
||||||
|
{
|
||||||
|
if (strncmp (fptr, "000000", 6) != 0)
|
||||||
|
rooted = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (vmsname, s1);
|
||||||
|
s = strchr (vmsname, ']');
|
||||||
|
*s = '.';
|
||||||
|
nstate = N_DOT;
|
||||||
|
vptr = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free (s1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rooted = 0;
|
||||||
|
|
||||||
|
if (*vptr == 0)
|
||||||
|
{
|
||||||
|
nstate = N_DEVICE;
|
||||||
|
*vptr++ = ':';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vptr++;
|
||||||
|
|
||||||
|
if (rooted == 0)
|
||||||
|
{
|
||||||
|
strcpy (vptr, "[000000.");
|
||||||
|
vptr += 8;
|
||||||
|
s1 = vptr-1;
|
||||||
|
nstate = N_DOT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s1 = 0;
|
||||||
|
|
||||||
|
/* s1-> '.' after 000000 or NULL */
|
||||||
|
|
||||||
|
s = strchr (fptr, '/');
|
||||||
|
if (s == 0)
|
||||||
|
{ /* no next '/' */
|
||||||
|
if (*(vptr-1) == '.')
|
||||||
|
*(vptr-1) = ']';
|
||||||
|
else if (rooted == 0)
|
||||||
|
*vptr++ = ']';
|
||||||
|
copyto (&vptr, &fptr, 0, (type == 1));
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (*(s+1) == '/') /* skip multiple '/' */
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rooted != 0)
|
||||||
|
&& (*(vptr-1) != '.'))
|
||||||
|
{
|
||||||
|
*vptr++ = '[';
|
||||||
|
nstate = N_DOT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ((nstate == N_DOT)
|
||||||
|
&& (s1 != 0)
|
||||||
|
&& (*(s+1) == 0))
|
||||||
|
{
|
||||||
|
if (type == 2)
|
||||||
|
{
|
||||||
|
*s1 = ']';
|
||||||
|
nstate = N_CLOSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = 9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: /* single '/' at start (9..15) */
|
||||||
|
if (*fptr == 0)
|
||||||
|
state = 5;
|
||||||
|
else
|
||||||
|
state = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: /* just '/' at start (9) */
|
||||||
|
if (type != 2)
|
||||||
|
{
|
||||||
|
*vptr++ = '[';
|
||||||
|
nstate = N_OPEN;
|
||||||
|
}
|
||||||
|
strcpy (vptr, "000000");
|
||||||
|
vptr += 6;
|
||||||
|
if (type == 2)
|
||||||
|
state = 7;
|
||||||
|
else
|
||||||
|
state = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: /* chars following '/' at start 10..15 */
|
||||||
|
*vptr++ = '[';
|
||||||
|
nstate = N_OPEN;
|
||||||
|
s = strchr (fptr, '/');
|
||||||
|
if (s == 0) /* 10 */
|
||||||
|
{
|
||||||
|
if (type != 1)
|
||||||
|
{
|
||||||
|
strcpy (vptr, "000000]");
|
||||||
|
vptr += 7;
|
||||||
|
}
|
||||||
|
copyto (&vptr, &fptr, 0, (type == 1));
|
||||||
|
if (type == 1)
|
||||||
|
{
|
||||||
|
*vptr++ = ']';
|
||||||
|
}
|
||||||
|
state = -1;
|
||||||
|
}
|
||||||
|
else /* 11..15 */
|
||||||
|
{
|
||||||
|
if ( (type == 2)
|
||||||
|
&& (*(s+1) == 0)) /* 11(2) */
|
||||||
|
{
|
||||||
|
strcpy (vptr, "000000]");
|
||||||
|
nstate = N_CLOSED;
|
||||||
|
vptr += 7;
|
||||||
|
}
|
||||||
|
copyto (&vptr, &fptr, '/', (*(vptr-1) != ']'));
|
||||||
|
state = 9;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: /* add '.dir' and exit */
|
||||||
|
if ((nstate == N_OPEN)
|
||||||
|
|| (nstate == N_DOT))
|
||||||
|
{
|
||||||
|
s = vptr-1;
|
||||||
|
while (s > vmsname)
|
||||||
|
{
|
||||||
|
if (*s == ']')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*s == '.')
|
||||||
|
{
|
||||||
|
*s = ']';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcpy (vptr, ".dir");
|
||||||
|
vptr += 4;
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8: /* add ']' and exit */
|
||||||
|
*vptr++ = ']';
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9: /* 17..21, fptr -> 1st '/' + 1 */
|
||||||
|
if (*fptr == 0)
|
||||||
|
{
|
||||||
|
if (type == 2)
|
||||||
|
{
|
||||||
|
state = 7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s = strchr (fptr, '/');
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
if (type != 1)
|
||||||
|
{
|
||||||
|
if (nstate == N_OPEN)
|
||||||
|
{
|
||||||
|
*vptr++ = ']';
|
||||||
|
nstate = N_CLOSED;
|
||||||
|
}
|
||||||
|
as_dir = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nstate == N_OPEN)
|
||||||
|
{
|
||||||
|
*vptr++ = '.';
|
||||||
|
nstate = N_DOT;
|
||||||
|
}
|
||||||
|
as_dir = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (*(s+1) == '/')
|
||||||
|
s++;
|
||||||
|
if ( (type == 2)
|
||||||
|
&& (*(s+1) == 0)) /* 19(2), 21(2)*/
|
||||||
|
{
|
||||||
|
if (nstate != N_CLOSED)
|
||||||
|
{
|
||||||
|
*vptr++ = ']';
|
||||||
|
nstate = N_CLOSED;
|
||||||
|
}
|
||||||
|
as_dir = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nstate == N_OPEN)
|
||||||
|
{
|
||||||
|
*vptr++ = '.';
|
||||||
|
nstate = N_DOT;
|
||||||
|
}
|
||||||
|
as_dir = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( (*fptr == '.') /* check for '..' or '../' */
|
||||||
|
&& (*(fptr+1) == '.')
|
||||||
|
&& ((*(fptr+2) == '/')
|
||||||
|
|| (*(fptr+2) == 0)) )
|
||||||
|
{
|
||||||
|
fptr += 2;
|
||||||
|
if (*fptr == '/')
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
fptr++;
|
||||||
|
}
|
||||||
|
while (*fptr == '/');
|
||||||
|
}
|
||||||
|
else if (*fptr == 0)
|
||||||
|
type = 1;
|
||||||
|
vptr--; /* vptr -> '.' or ']' */
|
||||||
|
s1 = vptr;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
s1--;
|
||||||
|
if (*s1 == '.') /* one back */
|
||||||
|
{
|
||||||
|
vptr = s1;
|
||||||
|
nstate = N_OPEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*s1 == '[') /* top level reached */
|
||||||
|
{
|
||||||
|
if (*fptr == 0)
|
||||||
|
{
|
||||||
|
strcpy (s1, "[000000]");
|
||||||
|
vptr = s1 + 8;
|
||||||
|
nstate = N_CLOSED;
|
||||||
|
s = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vptr = s1+1;
|
||||||
|
nstate = N_OPEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copyto (&vptr, &fptr, '/', as_dir);
|
||||||
|
if (nstate == N_DOT)
|
||||||
|
nstate = N_OPEN;
|
||||||
|
}
|
||||||
|
if (s == 0)
|
||||||
|
{ /* 18,20 */
|
||||||
|
if (type == 1)
|
||||||
|
*vptr++ = ']';
|
||||||
|
state = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*(s+1) == 0)
|
||||||
|
{
|
||||||
|
if (type == 2) /* 19,21 */
|
||||||
|
{
|
||||||
|
state = 7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*vptr++ = ']';
|
||||||
|
state = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 10: /* 1,2 first is '.' */
|
||||||
|
if (*fptr == '.')
|
||||||
|
{
|
||||||
|
fptr++;
|
||||||
|
state = 11;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state = 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11: /* 2, '..' at start */
|
||||||
|
count = 1;
|
||||||
|
if (*fptr != 0)
|
||||||
|
{
|
||||||
|
if (*fptr != '/') /* got ..xxx */
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
do /* got ../ */
|
||||||
|
{
|
||||||
|
fptr++;
|
||||||
|
while (*fptr == '/') fptr++;
|
||||||
|
if (*fptr != '.')
|
||||||
|
break;
|
||||||
|
if (*(fptr+1) != '.')
|
||||||
|
break;
|
||||||
|
fptr += 2;
|
||||||
|
if ((*fptr == 0)
|
||||||
|
|| (*fptr == '/'))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
while (*fptr == '/');
|
||||||
|
}
|
||||||
|
{ /* got '..' or '../' */
|
||||||
|
char cwdbuf[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
s1 = getcwd(cwdbuf, MAXPATHLEN);
|
||||||
|
if (s1 == 0)
|
||||||
|
{
|
||||||
|
return ""; /* FIXME, err getcwd */
|
||||||
|
}
|
||||||
|
strcpy (vptr, s1);
|
||||||
|
s = strchr (vptr, ']');
|
||||||
|
if (s != 0)
|
||||||
|
{
|
||||||
|
while (s > vptr)
|
||||||
|
{
|
||||||
|
s--;
|
||||||
|
if (*s == '[')
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
strcpy (s, "000000]");
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (*s == '.')
|
||||||
|
{
|
||||||
|
if (--count == 0)
|
||||||
|
{
|
||||||
|
if (*fptr == 0) /* had '..' or '../' */
|
||||||
|
{
|
||||||
|
*s++ = ']';
|
||||||
|
state = -1;
|
||||||
|
}
|
||||||
|
else /* had '../xxx' */
|
||||||
|
{
|
||||||
|
state = 9;
|
||||||
|
}
|
||||||
|
*s = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vptr += strlen (vptr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 12: /* 1, '.' at start */
|
||||||
|
if (*fptr != 0)
|
||||||
|
{
|
||||||
|
if (*fptr != '/')
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
fptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char cwdbuf[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
s1 = getcwd(cwdbuf, MAXPATHLEN);
|
||||||
|
if (s1 == 0)
|
||||||
|
{
|
||||||
|
return ""; /*FIXME, err getcwd */
|
||||||
|
}
|
||||||
|
strcpy (vptr, s1);
|
||||||
|
if (*fptr == 0)
|
||||||
|
{
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = strchr (vptr, ']');
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
state = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*s = 0;
|
||||||
|
nstate = N_OPEN;
|
||||||
|
vptr += strlen (vptr);
|
||||||
|
state = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
while (state > 0);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* directory conversion done
|
||||||
|
fptr -> filename part of input string
|
||||||
|
vptr -> free space in vmsname
|
||||||
|
*/
|
||||||
|
|
||||||
|
*vptr++ = 0;
|
||||||
|
|
||||||
|
return vmsname;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert from vms-style to unix-style
|
||||||
|
|
||||||
|
dev:[dir1.dir2] //dev/dir1/dir2/
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
unixify (char *name)
|
||||||
|
{
|
||||||
|
static char piece[512];
|
||||||
|
char *s, *p;
|
||||||
|
|
||||||
|
if (strchr (name, '/') != 0) /* already in unix style */
|
||||||
|
return name;
|
||||||
|
|
||||||
|
p = piece;
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
/* device part */
|
||||||
|
|
||||||
|
s = strchr (name, ':');
|
||||||
|
|
||||||
|
if (s != 0)
|
||||||
|
{
|
||||||
|
*s = 0;
|
||||||
|
*p++ = '/';
|
||||||
|
*p++ = '/';
|
||||||
|
strcpy (p, name);
|
||||||
|
p += strlen (p);
|
||||||
|
*s = ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* directory part */
|
||||||
|
|
||||||
|
*p++ = '/';
|
||||||
|
s = strchr (name, '[');
|
||||||
|
|
||||||
|
if (s != 0)
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
switch (*s)
|
||||||
|
{
|
||||||
|
case ']': /* [] */
|
||||||
|
strcat (p, "./");
|
||||||
|
break;
|
||||||
|
case '-': /* [- */
|
||||||
|
strcat (p, "../");
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
strcat (p, "./"); /* [. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
if (*s == '.')
|
||||||
|
*p++ = '/';
|
||||||
|
else
|
||||||
|
*p++ = *s;
|
||||||
|
s++;
|
||||||
|
if (*s == ']')
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*s != 0) /* more after ']' ?? */
|
||||||
|
{
|
||||||
|
if (*(p-1) != '/')
|
||||||
|
*p++ = '/';
|
||||||
|
strcpy (p, s); /* copy it anyway */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else /* no '[' anywhere */
|
||||||
|
|
||||||
|
{
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* force end with '/' */
|
||||||
|
|
||||||
|
if (*(p-1) != '/')
|
||||||
|
*p++ = '/';
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
return piece;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
4
vpath.c
4
vpath.c
@ -17,7 +17,7 @@ along with GNU Make; see the file COPYING. If not, write to
|
|||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "file.h"
|
#include "filedef.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ static struct vpath *vpaths;
|
|||||||
|
|
||||||
static struct vpath *general_vpath;
|
static struct vpath *general_vpath;
|
||||||
|
|
||||||
static int selective_vpath_search ();
|
static int selective_vpath_search PARAMS ((struct vpath *path, char **file, time_t *mtime_ptr));
|
||||||
|
|
||||||
/* Reverse the chain of selective VPATH lists so they
|
/* Reverse the chain of selective VPATH lists so they
|
||||||
will be searched in the order given in the makefiles
|
will be searched in the order given in the makefiles
|
||||||
|
Loading…
Reference in New Issue
Block a user