File:  [Research Unix] / researchv10dc / cmd / icon / src / link / ilink.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:34 2018 UTC (8 years, 3 months ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Dan Cross

/*
 * Linker main program that controls the linking process.
 */

#include "ilink.h"
#include "../h/paths.h"
#include "../h/header.h"

#ifndef MaxHeader
#define MaxHeader MaxHdr
#endif MaxHeader



#define MaxName  256		/* maximum length of file name */

#ifndef Header
#define Header HeaderPath
#endif Header
FILE *infile;			/* input file (.u1 or .u2) */
FILE *outfile;			/* interpreter code output file */
FILE *dbgfile;			/* debug file */
char inname[MaxName];		/* input file name */
char outname[MaxName];		/* output file name */
char icnname[MaxName];		/* icon source file name */
char dbgname[MaxName];		/* debug file name */
#ifdef VMS
char *iconx = "VMS ICONX";                              /* pathname of iconx */
#else VMS
#ifdef MSDOS
char *iconx = "CCW";
#else MSDOS
char *iconx = "/bin/echo iconx path not in";            /* pathname of iconx */
#endif MSDOS
#endif VMS
struct lfile *lfiles;		/* List of files to link */

int line = 0;			/* current source program line number */
char *file = NULL;		/* current source program file */
int fatalerrs = 0;		/* number of errors encountered */
int Dflag = 0;			/* debug flag */

char *pname;			/* name of program that is running */
char **filep;			/* name of current input file */

main(argc, argv)
int argc;
char **argv;
   {
   register int i;
   extern char *maknam(), *maknam2();
   char *p, *getenv();
   struct lfile *lf,*lfls;

   pname = "ilink";
   meminit(argc, argv); /* Note that meminit also processes arguments. */

   /*
    * Phase I: load global information contained in .u2 files into
    *  data structures.
    *
    * The list of files to link is maintained as a queue with lfiles
    *  as the base.  lf moves along the list.  Each file is processed
    *  in turn by forming .u2 and .icn names from each file name, each
    *  of which ends in .u1.  The .u2 file is opened and globals is called
    *  to process it.  When the end of the list is reached, lf becomes
    *  NULL and the loop is terminated, completing phase I.  Note that
    *  link instructions in the .u2 file cause files to be added to list
    *  of files to link.
    */
   if (!(lf = lfiles))
      exit(NormalExit);
   while (lf) {
      filep = &(lf->lf_name);
      maknam2(inname, *filep, ".u2");
      maknam(icnname, *filep, ".icn");
      infile = fopen(inname, "r");
      if (infile == NULL) {
	 fprintf(stderr, "%s: cannot open %s\n", pname, inname);
	 exit(ErrorExit);
	 }
      globals(i);
      fclose(infile);
      lf = lf->lf_link;
      }

   /* Phase II: resolve undeclared variables and generate code. */

   /*
    * Open the output file.  If no file was named with -o, form the
    *  name from that of the first input file named.
    */
   if (!outname[0])
      maknam(outname, lfiles->lf_name, "");
   outfile = fopen(outname, "w");
#ifdef LATTICE
   fmode(outfile,1);   /* Set for untranslated mode */
#endif LATTICE
#ifdef MSoft
   setmode(fileno(outfile),0x8000);    /* Set for untranslated mode */
#endif MSoft
   if (outfile == NULL) {
      fprintf(stderr, "%s: cannot create %s\n", pname, outname);
      exit(ErrorExit);
      }
#ifndef NoHeader
   /*
    * Open Header, which contains the start-up program and copy it to the
    *  output file.  Then, set up for an fseek to the byte
    *  past the end of the start-up program.
    */
   {
   int hfile, hsize;
   char hdrdat[MaxHeader];


   hfile = open(Header,0);
   if (hfile == -1) {
      fprintf(stderr,"Can't open linker header file %s\n",Header);
      exit(ErrorExit);
      }
   hsize = read(hfile,hdrdat,MaxHeader);
   fwrite(hdrdat,sizeof(char),hsize,outfile);
   }
   fseek(outfile, (long)(MaxHeader + sizeof(struct header)), 0);
#else NoHeader
   fseek(outfile, (long)(sizeof(struct header)),0);
#endif NoHeader

   /*
    * Open the .ux file if debugging is on.
    */
   if (Dflag) {
      maknam(dbgname, lfiles->lf_name, ".ux");
      dbgfile = fopen(dbgname, "w");
      if (dbgfile == NULL) {
	 fprintf(stderr, "%s: cannot create %s\n", pname, dbgname);
	 exit(ErrorExit);
	 }
      }

   /*
    * Loop through input files and generate code for each.
    */
   lfls = lfiles;
   while (lf = getlfile(&lfls)) {
      filep = &(lf->lf_name);
      maknam2(inname, *filep, ".u1");
      maknam(icnname, *filep, ".icn");
      infile = fopen(inname, "r");
      if (infile == NULL) {
	 fprintf(stderr, "%s: cannot open %s\n", pname, inname);
	 exit(ErrorExit);
	 }
      gencode();
      fclose(infile);
      }
   gentables(); 	/* Generate record, field, global, global names,
			   static, and identifier tables. */
   if (fatalerrs > 0)
      exit(ErrorExit);
#ifndef VMS
   exit(NormalExit);
#else VMS
   exit(NormalExit);
#endif VMS
   }

/*
 * maknam - makes a file name from prefix and suffix.
 *
 * Uses only the last file specification if name is a path,
 * replaces suffix of name with suffix argument.
 */
char *maknam(dest, name, suffix)
char *dest, *name, *suffix;
   {
   register char *d, *pre, *suf;
   char *mark;

   d = dest;
   pre = name;
   suf = suffix;
   mark = pre;
   while (*pre) 		/* find last delimiter */
#ifndef VMS
#ifndef MSDOS
      if (*pre++ == '/')
	 mark = pre;
#else MSDOS
      if (*pre == '/' || *pre == '\\' || *pre == ':')
	 mark = ++pre;
      else
	 ++pre;
#endif MSDOS
#else VMS
      if (*pre == ']' || *pre == ':')
	 mark = ++pre;
      else
	 ++pre;
#endif VMS
   pre = mark;
   mark = 0;
   while (*d = *pre++)		/* copy from last slash into dest */
      if (*d++ == '.')          /*   look for last dot, too */
	 mark = d - 1;
   if (mark)			/* if no dot, just append suffix */
      d = mark;
   while (*d++ = *suf++) ;	/* copy suffix into dest */
   return dest;
   }

/*
 * maknam2 - makes a file name from prefix and suffix.
 *
 * Like maknam, but leaves initial pathname component intact.
 */
char *maknam2(dest, name, suffix)
char *dest, *name, *suffix;
   {
   register char *d, *pre, *suf;
   char *mark;

   d = dest;
   pre = name;
   suf = suffix;
   mark = 0;
   while (*d = *pre++) {
#ifndef VMS
#ifndef MSDOS
      if (*d == '/')
	 mark = 0;
#else MSDOS
      if (*d == ':' || *d == '/' || *d == '\\')
	 mark = 0;
#endif MSDOS
#else VMS
      if (*d == ']' || *d == ':')
	 mark = 0;
#endif VMS
      if (*d++ == '.')          /*   look for last dot, too */
	 mark = d - 1;
      }
   if (mark)			/* if no dot, just append suffix */
      d = mark;
   while (*d++ = *suf++) ;	/* copy suffix into dest */
   return dest;
   }

/*
 * syserr - issue error message and die.
 */
syserr(s)
char *s;
   {
   fprintf(stderr, "%s\n", s);
   exit(ErrorExit);
   }

/*
 * warn - issue a warning message.
 */
warn(s1, s2, s3)
char *s1, *s2, *s3;
   {
   fprintf(stderr, "%s: ", icnname);
   if (line)
      fprintf(stderr, "%d: ", line);
   if (s1)
      fprintf(stderr, "\"%s\": ", s1);
   if (s2)
      fprintf(stderr, "%s", s2);
   if (s3)
      fprintf(stderr, "%s", s3);
   fprintf(stderr, "\n");
   }

/*
 * err - issue an error message.
 */

err(s1, s2, s3)
char *s1, *s2, *s3;
   {
   fprintf(stderr, "%s: ", icnname);
   if (line)
      fprintf(stderr, "%d: ", line);
   if (s1)
      fprintf(stderr, "\"%s\": ", s1);
   if (s2)
      fprintf(stderr, "%s", s2);
   if (s3)
      fprintf(stderr, "%s", s3);
   fprintf(stderr, "\n");
   fatalerrs++;
   }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.