rsalz@uunet.UU.NET (Rich Salz) (10/16/87)
Submitted-by: Zoltan Somogyi <zs@munnari.oz>
Posting-number: Volume 12, Issue 10
Archive-name: cake/part04
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# README
# Makefile
# base.c
# ccincl.c
# ccincl_s.l
# gsrc.c
# later.c
# need.c
# needed.c
# pattern_s.l
# refs.c
# std.h
# sub.c
# subcmd.c
# usrc.c
# This archive created: Wed Oct 14 20:49:51 1987
export PATH; PATH=/bin:/usr/bin:$PATH
echo mkdir Aux
mkdir Aux
echo cd Aux
cd Aux
echo shar: "extracting 'README'" '(172 characters)'
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XThis directory contains the sources for commands used by some
X"standard" cakefiles. You shouldn't need to do more than modify
XDEST in the Makefile and type "make install".
SHAR_EOF
if test 172 -ne "`wc -c < 'README'`"
then
echo shar: "error transmitting 'README'" '(should have been 172 characters)'
fi
fi
echo shar: "extracting 'Makefile'" '(836 characters)'
if test -f 'Makefile'
then
echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# Makefile for some of cake's auxiliary programs
X
XPROGS = base ccincl later need needed sub subcmd usrc gsrc
XDEST = /mip/usr/bin
X
Xall: $(PROGS)
X
Xinstall: $(PROGS)
X cp $(PROGS) $(DEST)
X
Xbase: base.o pattern_s.o
X cc -o base base.o pattern_s.o
X
Xccincl: ccincl.o ccincl_s.o
X cc -o ccincl ccincl.o ccincl_s.o
X
Xlater: later.c
X cc -o later later.c
X
Xneed: need.c
X cc -o need need.c
X
Xneeded: needed.c
X cc -o needed needed.c
X
Xrefs: refs.o pattern_s.o
X cc -o refs refs.o pattern_s.o
X
Xsub: sub.c
X cc -o sub sub.c
X
Xsubcmd: subcmd.c
X cc -o subcmd subcmd.c
X
Xusrc: usrc.c
X cc -o usrc usrc.c
X
Xgsrc: gsrc.c
X cc -o gsrc gsrc.c
X
Xccincl_s.c: ccincl_s.l
X lex ccincl_s.l
X @mv lex.yy.c ccincl_s.c
X
Xpattern_s.c: pattern_s.l
X lex pattern_s.l
X @mv lex.yy.c pattern_s.c
X
Xclean:
X /bin/rm Make_errs *.o *_s.c
X
Xgclean:
X /bin/rm *_s.c
SHAR_EOF
if test 836 -ne "`wc -c < 'Makefile'`"
then
echo shar: "error transmitting 'Makefile'" '(should have been 836 characters)'
fi
fi
echo shar: "extracting 'base.c'" '(754 characters)'
if test -f 'base.c'
then
echo shar: "will not over-write existing file 'base.c'"
else
sed 's/^X//' << \SHAR_EOF > 'base.c'
X/*
X** A program to prepare a base for spell and style
X*/
X
X#include <stdio.h>
X#include "std.h"
X
Xtypedef struct s_entry
X{
X bool reflexive;
X char *replacement;
X} Entry;
X
XEntry table[5] = /* we use subscripts 1 to 4 */
X{
X { FALSE, "" },
X { TRUE, "EQUATION" },
X { FALSE, "(REFERENCE)" },
X { FALSE, "PROGRAM" },
X { FALSE, "PICTURE" },
X};
X
Xint more = TRUE;
X
Xmain()
X{
X extern char yytext[];
X reg int code;
X
X code = yylex();
X while (more)
X {
X if (code <= 0)
X fputs(yytext, stdout);
X else
X {
X reg int oldcode;
X reg int newcode;
X
X oldcode = code;
X newcode = table[code].reflexive? code: -code;
X
X code = yylex();
X while (more && code != newcode)
X code = yylex();
X
X printf(table[oldcode].replacement);
X }
X
X code = yylex();
X }
X
X exit(0);
X}
SHAR_EOF
if test 754 -ne "`wc -c < 'base.c'`"
then
echo shar: "error transmitting 'base.c'" '(should have been 754 characters)'
fi
fi
echo shar: "extracting 'ccincl.c'" '(5068 characters)'
if test -f 'ccincl.c'
then
echo shar: "will not over-write existing file 'ccincl.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ccincl.c'
X/*
X** Ccincl main file.
X*/
X
Xstatic char
Xrcs_id[] = "$Header$";
X
X#include <ctype.h>
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "std.h"
X
Xtypedef struct stat Stat;
X
X#define MAXDIRS 10
X#define MAXSTOPS 10
X#define MAXIGNORES 10
X#define MAXFILES 64
X#define MAXBUF 512
X
Xchar *dir_list[MAXDIRS];
Xchar *stop_list[MAXSTOPS];
Xchar *ign_list[MAXIGNORES];
Xchar *file_list[MAXFILES];
Xbool search_list[MAXFILES];
Xino_t ino_list[MAXFILES];
Xint dircount = 0;
Xint stopcount = 0;
Xint igncount = 0;
Xint filecount = 0;
X
Xchar *currdir = ".";
Xchar *filename;
XStat statbuf;
Xint rflag = FALSE;
Xint fflag = FALSE;
Xint errorcount = 0;
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X extern FILE *yyin;
X reg int i;
X
X dir_list[dircount++] = ".";
X while (argc > 1 && argv[1][0] == '-')
X {
X for (i = 1; argv[1][i] != '\0'; i++)
X {
X switch (argv[1][i])
X {
X
X when 'f':
X fflag = TRUE;
X when 'r':
X rflag = TRUE;
X when 'i':
X if (i != 1)
X usage();
X
X ign_list[igncount++] = &argv[1][2];
X file_list[filecount] = &argv[1][2];
X
X if (stat(&argv[1][2], &statbuf) != 0)
X {
X printf("ccincl: cannot find %s\n", &argv[1][2]);
X exit(1);
X }
X
X search_list[filecount] = FALSE;
X ino_list[filecount] = statbuf.st_ino;
X filecount++;
X goto nextword;
X when 's':
X if (i != 1)
X usage();
X
X stop_list[stopcount++] = &argv[1][2];
X file_list[filecount] = &argv[1][2];
X
X if (stat(&argv[1][2], &statbuf) != 0)
X {
X printf("ccincl: cannot find %s\n", &argv[1][2]);
X exit(1);
X }
X
X search_list[filecount] = FALSE;
X ino_list[filecount] = statbuf.st_ino;
X filecount++;
X goto nextword;
X when 'C':
X if (i != 1)
X usage();
X
X currdir = &argv[1][2];
X goto nextword;
X when 'I':
X if (i != 1)
X usage();
X
X dir_list[dircount++] = &argv[1][2];
X goto nextword;
X otherwise:
X usage();
X }
X }
X
Xnextword:
X argc--;
X argv++;
X }
X
X dir_list[dircount++] = "/usr/include";
X if (dircount > MAXDIRS)
X {
X printf("ccincl: too many dir_list.\n");
X exit(1);
X }
X
X if (argc < 2)
X usage();
X
X while (argc > 1)
X {
X file_list[filecount] = argv[1];
X if (stat(argv[1], &statbuf) != 0)
X {
X printf("ccincl: cannot find %s\n", argv[1]);
X exit(1);
X }
X
X search_list[filecount] = TRUE;
X ino_list[filecount] = statbuf.st_ino;
X filecount++;
X argc--;
X argv++;
X }
X
X for (i = 0; i < filecount; i++)
X {
X if (! search_list[i])
X continue;
X
X filename = file_list[i];
X if ((yyin = fopen(filename, "r")) == NULL)
X {
X fflush(stdout);
X perror("ccincl");
X printf("ccincl: cannot open %s\n", filename);
X exit(1);
X }
X
X yylex();
X fclose(yyin);
X }
X
X exit(errorcount);
X}
X
Xprocess(line)
Xreg char *line;
X{
X extern char *malloc();
X extern int yylineno;
X char buf[MAXBUF];
X reg char *s, *start;
X reg int i, startdir;
X reg bool index;
X reg char endchar;
X reg bool found;
X
X for (s = line+1; *s != '\0' && isspace(*s); s++)
X ;
X
X if (strndiff(s, "include", 7))
X return;
X
X for (s += 7; *s != '\0' && isspace(*s); s++)
X ;
X
X if (*s == '<')
X endchar = '>', startdir = 1;
X else
X endchar = '"', startdir = 0;
X
X start = s+1;
X for (s = start; *s != '\0' && *s != endchar; s++)
X ;
X
X if (*s != endchar)
X {
X printf("ccincl: %s(%d) bad include syntax\n", filename, yylineno);
X errorcount++;
X return;
X }
X
X /* terminate arg (now pointed to by start) */
X *s = '\0';
X
X /* handle absolute pathnames */
X if (*start == '/')
X {
X sprintf(buf, "%s", start);
X goto end;
X }
X
X /* handle relative pathnames */
X if (*start == '.')
X {
X sprintf(buf, "%s/%s", currdir, start);
X goto end;
X }
X
X /* handle implicit pathnames */
X found = FALSE;
X for (i = startdir; i < dircount; i++)
X {
X if (i == 0)
X {
X if (streq(currdir, "."))
X strcpy(buf, "");
X else
X {
X strcpy(buf, dir_list[i]);
X strcat(buf, "/");
X }
X
X strcat(buf, start);
X }
X else
X {
X strcpy(buf, dir_list[i]);
X strcat(buf, "/");
X strcat(buf, start);
X }
X
X if (strlen(buf) > MAXBUF)
X {
X printf("ccincl: buffer length exceeded\n");
X exit(1);
X }
X
X if (stat(buf, &statbuf) == 0)
X {
X found = TRUE;
X break;
X }
X }
X
X if (! found)
X {
X printf("ccincl: cannot find %s\n", start);
X errorcount++;
X return;
X }
X
Xend:
X if (stat(buf, &statbuf) != 0)
X {
X printf("ccincl: cannot stat %s\n", buf);
X errorcount++;
X return;
X }
X
X found = FALSE;
X for (i = 0; i < filecount; i++)
X if (ino_list[i] == statbuf.st_ino)
X {
X found = TRUE;
X index = i;
X break;
X }
X
X if (! found)
X {
X index = filecount;
X ino_list[filecount] = statbuf.st_ino;
X search_list[filecount] = FALSE;
X file_list[filecount] = malloc(strlen(buf)+1);
X strcpy(file_list[filecount], buf);
X filecount++;
X }
X
X for (i = 0; i < igncount; i++)
X if (streq(file_list[index], ign_list[i]))
X return;
X
X if (fflag)
X printf("%s: ", filename);
X
X printf("%s\n", file_list[index]);
X
X if (rflag)
X {
X for (i = 0; i < stopcount; i++)
X if (streq(buf, stop_list[i]))
X return;
X
X search_list[filecount] = TRUE;
X }
X}
X
X/*
X** Tell the unfortunate user how to use ccincl.
X*/
X
Xusage()
X{
X printf("Usage: ccincl [-rf] [-ifile] [-sfile] [-Cdir] [-Idir] ... file ...\n");
X exit(1);
X}
SHAR_EOF
if test 5068 -ne "`wc -c < 'ccincl.c'`"
then
echo shar: "error transmitting 'ccincl.c'" '(should have been 5068 characters)'
fi
fi
echo shar: "extracting 'ccincl_s.l'" '(240 characters)'
if test -f 'ccincl_s.l'
then
echo shar: "will not over-write existing file 'ccincl_s.l'"
else
sed 's/^X//' << \SHAR_EOF > 'ccincl_s.l'
X%{
X/*
X** Scanner for ccincl
X*/
X
Xstatic char
Xrcs_id[] = "$Header$";
X
X#undef YYLMAX
X#define YYLMAX 512
X%}
X
Xnl [\n\f]
Xnonl [^\n\f]
X
X%%
X
X#{nonl}*{nl} {
X process(yytext);
X fflush(stdout);
X }
X
X{nonl}*{nl} ;
X
X%%
X
Xyywrap()
X{
X return 1;
X}
SHAR_EOF
if test 240 -ne "`wc -c < 'ccincl_s.l'`"
then
echo shar: "error transmitting 'ccincl_s.l'" '(should have been 240 characters)'
fi
fi
echo shar: "extracting 'gsrc.c'" '(807 characters)'
if test -f 'gsrc.c'
then
echo shar: "will not over-write existing file 'gsrc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'gsrc.c'
X/*
X** Track down ultimate source files.
X*/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "std.h"
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X char buf[80];
X struct stat statbuf;
X reg int i, j;
X reg int lastsuf, firstfile;
X reg bool found;
X
X lastsuf = 0;
X firstfile = argc;
X for (i = 1; i < argc; i++)
X {
X if (argv[i][0] == '.')
X lastsuf = i;
X or (firstfile == argc)
X firstfile = i;
X }
X
X if (lastsuf > firstfile)
X {
X fprintf(stderr, "gsrc: mixed suffixes and filenames\n");
X exit(1);
X }
X
X for (i = firstfile; i < argc; i++)
X {
X found = FALSE;
X for (j = lastsuf; j > 0; j--)
X {
X sprintf(buf, "%s%s", argv[i], argv[j]);
X if (stat(buf, &statbuf) == 0)
X {
X if (! found)
X found = TRUE;
X else
X printf("%s%s\n", argv[i], argv[j]);
X }
X }
X }
X
X exit(0);
X}
SHAR_EOF
if test 807 -ne "`wc -c < 'gsrc.c'`"
then
echo shar: "error transmitting 'gsrc.c'" '(should have been 807 characters)'
fi
fi
echo shar: "extracting 'later.c'" '(1244 characters)'
if test -f 'later.c'
then
echo shar: "will not over-write existing file 'later.c'"
else
sed 's/^X//' << \SHAR_EOF > 'later.c'
X/*
X** Find out which arg files are later than a reference file.
X*/
X
Xstatic char
Xrcs_id[] = "$Header$";
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "std.h"
X
Xtypedef struct stat Stat;
X
Xchar scratchbuf[128];
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X Stat statbuf;
X reg time_t reftime;
X reg int i, n;
X reg bool count = FALSE;
X reg bool silent = FALSE;
X
X while (argc > 1 && argv[1][0] == '-')
X {
X for (i = 1; argv[1][i] != '\0'; i++)
X {
X switch (argv[1][i])
X {
X
X when 'c': count = TRUE;
X
X when 's': silent = TRUE;
X
X otherwise: usage();
X
X }
X }
X
X argc--;
X argv++;
X }
X
X if (argc < 3)
X usage();
X
X if (stat(argv[1], &statbuf) != 0)
X {
X sprintf(scratchbuf, "later, stat %s", argv[1]);
X perror(scratchbuf);
X exit(127);
X }
X
X argv++;
X argc--;
X reftime = statbuf.st_mtime;
X n = 0;
X
X while (argc > 1)
X {
X if (stat(argv[1], &statbuf) != 0)
X {
X sprintf(scratchbuf, "later, stat %s", argv[1]);
X perror(scratchbuf);
X exit(127);
X }
X
X if (statbuf.st_mtime > reftime)
X {
X n++;
X if (! silent)
X printf("%s\n", argv[1]);
X }
X
X argc--;
X argv++;
X }
X
X exit(count? n: 0);
X}
X
X/*
X** Tell the unfortunate user how to use later.
X*/
X
Xusage()
X{
X printf("Usage: later [-cs] reffile file ...\n");
X exit(1);
X}
SHAR_EOF
if test 1244 -ne "`wc -c < 'later.c'`"
then
echo shar: "error transmitting 'later.c'" '(should have been 1244 characters)'
fi
fi
echo shar: "extracting 'need.c'" '(996 characters)'
if test -f 'need.c'
then
echo shar: "will not over-write existing file 'need.c'"
else
sed 's/^X//' << \SHAR_EOF > 'need.c'
X/*
X** need: a simple utility for text processing with cake
X*/
X
X#include <stdio.h>
X#include "std.h"
X
X#define MAXLINE 256
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X reg FILE *fp;
X char line[MAXLINE];
X
X if (argc != 2 && argc != 3)
X {
X printf("Usage: need program [file]\n");
X exit(127);
X }
X
X if (argc == 2)
X fp = stdin;
X else
X {
X if ((fp = fopen(argv[2], "r")) == NULL)
X {
X printf("need: cannot open %s\n", argv[2]);
X exit(127);
X }
X }
X
X while (getline(fp, line, MAXLINE) > 0)
X if (match(line, "NEED"))
X exit(match(line, argv[1])? 0: 1);
X
X exit(127);
X}
X
Xint
Xgetline(fp, s, lim)
Xreg FILE *fp;
Xchar s[];
Xreg int lim;
X{
X reg int c, i;
X
X i = 0;
X while (--lim > 0 && (c = getc(fp)) != EOF && c != '\n')
X s[i++] = c;
X
X if (c == '\n')
X s[i++] = c;
X
X s[i] = '\0';
X return i;
X}
X
Xint
Xmatch(s, t)
Xreg char *s;
Xreg char *t;
X{
X reg int i, j;
X
X for (; *s != '\0'; s++)
X {
X for (i = 0, j = 0; t[j] != '\0' && s[i] == t[j]; i++, j++)
X ;
X if (t[j] == '\0')
X return TRUE;
X }
X
X return FALSE;
X}
SHAR_EOF
if test 996 -ne "`wc -c < 'need.c'`"
then
echo shar: "error transmitting 'need.c'" '(should have been 996 characters)'
fi
fi
echo shar: "extracting 'needed.c'" '(1001 characters)'
if test -f 'needed.c'
then
echo shar: "will not over-write existing file 'needed.c'"
else
sed 's/^X//' << \SHAR_EOF > 'needed.c'
X/*
X** needed: an even simpler utility for text processing with cake
X*/
X
X#include <stdio.h>
X#include "std.h"
X
X#define MAXLINE 256
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X extern char *match();
X reg FILE *fp;
X reg char *rest;
X char line[MAXLINE];
X
X if (argc != 2)
X {
X printf("Usage: needed file\n");
X exit(127);
X }
X
X if ((fp = fopen(argv[1], "r")) == NULL)
X {
X printf("needed: cannot open %s\n", argv[1]);
X exit(127);
X }
X
X while (getline(fp, line, MAXLINE) > 0)
X if ((rest = match(line, "NEED")) != NULL)
X {
X printf("%s", rest);
X exit(0);
X }
X
X exit(0);
X}
X
Xint
Xgetline(fp, s, lim)
Xreg FILE *fp;
Xchar s[];
Xreg int lim;
X{
X reg int c, i;
X
X i = 0;
X while (--lim > 0 && (c = getc(fp)) != EOF && c != '\n')
X s[i++] = c;
X
X if (c == '\n')
X s[i++] = c;
X
X s[i] = '\0';
X return i;
X}
X
Xchar *
Xmatch(s, t)
Xreg char *s;
Xreg char *t;
X{
X reg int i, j;
X
X for (; *s != '\0'; s++)
X {
X for (i = 0, j = 0; t[j] != '\0' && s[i] == t[j]; i++, j++)
X ;
X
X if (t[j] == '\0')
X return s+j;
X }
X
X return NULL;
X}
SHAR_EOF
if test 1001 -ne "`wc -c < 'needed.c'`"
then
echo shar: "error transmitting 'needed.c'" '(should have been 1001 characters)'
fi
fi
echo shar: "extracting 'pattern_s.l'" '(389 characters)'
if test -f 'pattern_s.l'
then
echo shar: "will not over-write existing file 'pattern_s.l'"
else
sed 's/^X//' << \SHAR_EOF > 'pattern_s.l'
X%{
X/*
X** Scanner for base
X*/
X
X#include "std.h"
X
Xextern int more;
X%}
X
X%%
X
X"$" { return 1; }
X"[\." { return 2; }
X".\]" { return -2; }
X"\\f(as" { return 3; }
X"\\f(CW" { return 3; }
X"\\fP" { return -3; }
X"\\fR" { return -3; }
X".(p" { return 3; }
X".)p" { return -3; }
X".PS" { return 4; }
X".PE" { return -4; }
X.|\n { return 0; }
X
X%%
X
Xyywrap()
X{
X more = FALSE;
X return 1;
X}
SHAR_EOF
if test 389 -ne "`wc -c < 'pattern_s.l'`"
then
echo shar: "error transmitting 'pattern_s.l'" '(should have been 389 characters)'
fi
fi
echo shar: "extracting 'refs.c'" '(828 characters)'
if test -f 'refs.c'
then
echo shar: "will not over-write existing file 'refs.c'"
else
sed 's/^X//' << \SHAR_EOF > 'refs.c'
X/*
X** A program to filter out references.
X*/
X
X#include <stdio.h>
X#include "std.h"
X
Xint more = TRUE;
X
Xmain()
X{
X extern char yytext[];
X reg FILE *out;
X reg int code;
X reg bool init, ignore;
X
X out = popen("sed -e 's/[ ]*$//'", "w");
X
X code = yylex();
X while (more)
X {
X if (code == 2)
X {
X ignore = FALSE;
X init = TRUE;
X code = yylex();
X while (more && code != -2)
X {
X if (streq(yytext, "{"))
X ignore = TRUE;
X or (streq(yytext, "}"))
X ignore = FALSE;
X or (ignore)
X ;
X or (streq(yytext, ","))
X {
X putc('\n', out);
X init = TRUE;
X }
X or (streq(yytext, " "))
X {
X if (! init)
X putc(' ', out);
X }
X else
X {
X fprintf(out, "%s", yytext);
X init = FALSE;
X }
X
X code = yylex();
X }
X
X putc('\n', out);
X }
X
X code = yylex();
X }
X
X pclose(out);
X exit(0);
X}
SHAR_EOF
if test 828 -ne "`wc -c < 'refs.c'`"
then
echo shar: "error transmitting 'refs.c'" '(should have been 828 characters)'
fi
fi
echo shar: "extracting 'std.h'" '(1030 characters)'
if test -f 'std.h'
then
echo shar: "will not over-write existing file 'std.h'"
else
sed 's/^X//' << \SHAR_EOF > 'std.h'
X/*
X** Standard definitions for C
X**
X** $Header: /mip/zs/src/sys/cake/RCS/std.h,v 1.13 86/06/15 18:36:30 zs Exp $
X*/
X
X#define or else if
X#define when break;case
X#define otherwise break;default
X#define loop for(;;)
X#define until(expr) while(!(expr))
X#ifndef reg
X#define reg register
X#endif
X#ifndef bool
X#define bool char
X#endif
X
X#define uint unsigned int
X#define ushort unsigned short
X#define uchar unsigned char
X
X#define max(a, b) ((a) > (b) ? (a) : (b))
X#define min(a, b) ((a) < (b) ? (a) : (b))
X
X#define streq(s1, s2) (strcmp(s1, s2) == 0)
X#define strdiff(s1, s2) (strcmp(s1, s2) != 0)
X#define strneq(s1, s2, n) (strncmp(s1, s2, n) == 0)
X#define strndiff(s1, s2, n) (strncmp(s1, s2, n) != 0)
X
X#define ungetchar(c) ungetc(c, stdin)
X#define make(type) ((type *) newmem(sizeof(type)))
X#define make_many(type, count) ((type *) newmem(count * sizeof(type)))
X
X#ifndef TRUE
X#define TRUE 1
X#endif
X#ifndef FALSE
X#define FALSE 0
X#endif
X#ifndef NULL
X#define NULL 0
X#endif
X
X#define CNULL (char *) 0
X#define LNULL (List *) 0
SHAR_EOF
if test 1030 -ne "`wc -c < 'std.h'`"
then
echo shar: "error transmitting 'std.h'" '(should have been 1030 characters)'
fi
fi
echo shar: "extracting 'sub.c'" '(4337 characters)'
if test -f 'sub.c'
then
echo shar: "will not over-write existing file 'sub.c'"
else
sed 's/^X//' << \SHAR_EOF > 'sub.c'
X/*
X** Sub - do substitutions on arguments
X*/
X
Xstatic char
Xrcs_id[] = "$Header$";
X
X#include "std.h"
X#include <ctype.h>
X
Xchar var_char = 'X';
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X extern bool match();
X extern char *ground();
X reg char *old, *new;
X reg bool ignore;
X reg int unmatched, i;
X reg char *sep;
X
X ignore = FALSE;
X unmatched = 0;
X while (argc > 1 && argv[1][0] == '-')
X {
X for (i = 1; argv[1][i] != '\0'; i++)
X {
X switch (argv[1][i])
X {
X
X when 'i':
X ignore = TRUE;
X when 'v':
X if (argv[1][i+2] != '\0')
X usage();
X
X var_char = argv[1][i+1];
X goto nextword;
X otherwise:
X usage();
X }
X }
X
Xnextword:
X argc--;
X argv++;
X }
X
X if (argc < 2)
X usage();
X
X old = argv[1];
X new = argv[2];
X argv += 2;
X argc -= 2;
X
X sep = "";
X while (argc > 1)
X {
X if (! match(argv[1], old))
X unmatched++;
X else
X {
X printf("%s%s", sep, ground(new));
X sep = " ";
X }
X
X argc--;
X argv++;
X }
X
X printf("\n");
X exit(ignore? 0: unmatched);
X}
X
X/*
X** Tell the unfortunate user how to use sub.
X*/
X
Xusage()
X{
X printf("Usage: sub [-i] [-vX] oldpattern newpattern name ...\n");
X exit(1);
X}
X
X/*
X** Module to manipulate Cake patterns.
X*/
X
Xtypedef struct s_env
X{
X char *en_val;
X bool en_bound;
X} Env;
X
X#define NOVAR 10
X#define MAXVAR 11
X#define MAXSIZE 128
X
XEnv env[MAXVAR];
X
X/*
X** This function initialises the environment of domatch.
X*/
X
Xbool
Xmatch(str, pat)
Xreg char *str;
Xreg char *pat;
X{
X extern bool domatch();
X reg int i;
X reg char *s, *p;
X
X p = pat+strlen(pat)-1;
X if (*p != var_char && !isdigit(*p)) /* not part of a var */
X {
X s = str+strlen(str)-1;
X if (*s != *p) /* last chars differ */
X return FALSE;
X }
X
X for (i = 0; i < MAXVAR; i++)
X env[i].en_bound = FALSE;
X
X return domatch(str, pat);
X}
X
X/*
X** Match a string against a pattern.
X** The pattern is expected to have been dereferenced.
X** To handle nondeterminism, a brute force recursion approach
X** is taken.
X*/
X
Xbool
Xdomatch(str, patstr)
Xreg char *str;
Xreg char *patstr;
X{
X extern char *new_name();
X char buf[MAXSIZE];
X reg char *follow;
X reg char *s, *t;
X reg int varno;
X reg int i;
X reg bool more;
X
X if (patstr[0] == var_char)
X {
X if (isdigit(patstr[1]))
X {
X varno = patstr[1] - '0';
X follow = patstr + 2;
X }
X else
X {
X varno = NOVAR;
X follow = patstr + 1;
X }
X
X if (env[varno].en_bound)
X {
X /* lifetime of buf is local */
X strcpy(buf, env[varno].en_val);
X strcat(buf, follow);
X return domatch(str, buf);
X }
X
X i = 0;
X buf[0] = '\0';
X env[varno].en_bound = TRUE;
X env[varno].en_val = buf;
X
X /* keep invariant: buf = tentative value of var */
X /* must consider *s == \0, but do not overshoot */
X for (s = str, more = TRUE; more; s++)
X {
X if (domatch(s, follow))
X {
X /* lifetime of buf is now global */
X env[varno].en_val = new_name(buf);
X return TRUE;
X }
X
X /* maintain invariant */
X buf[i++] = *s;
X buf[i] = '\0';
X
X more = (*s != '\0');
X }
X
X /* no luck, match failed */
X env[varno].en_bound = FALSE;
X return FALSE;
X }
X
X /* here we have something other than a variable first off */
X for (s = str, t = patstr; *t != '\0' && *t != var_char; s++, t++)
X {
X if (*t == '\\')
X t++; /* the new *t is not checked for % */
X
X if (*s != *t)
X return FALSE;
X }
X
X /* see if we have come to the end of the pattern */
X if (*t == '\0')
X return *s == '\0';
X
X /* if not, recurse on the next variable */
X return domatch(s, t);
X}
X
X/*
X** Ground the argument string, i.e. replace all occurrences
X** of variables in it. It is fatal error for the string to
X** contain a variable which has no value.
X*/
X
Xchar *
Xground(str)
Xreg char *str;
X{
X extern char *new_name();
X reg char *s, *t;
X reg int i, var;
X char buf[MAXSIZE];
X
X i = 0;
X for (s = str; *s != '\0'; s++)
X {
X if (*s == var_char)
X {
X if (isdigit(s[1]))
X var = *++s - '0';
X else
X var = NOVAR;
X
X if (! env[var].en_bound)
X {
X printf("Attempt to use undefined value in %s\n", str);
X exit(1);
X }
X
X for (t = env[var].en_val; *t != '\0'; t++)
X buf[i++] = *t;
X }
X or (*s == '\\')
X {
X if (s[1] != '\0')
X buf[i++] = *++s;
X }
X else
X buf[i++] = *s;
X }
X
X if (i >= MAXSIZE)
X {
X printf("Ran out of buffer\n");
X exit(1);
X }
X
X buf[i] = '\0';
X return new_name(buf);
X}
X
Xchar *
Xnew_name(str)
Xreg char *str;
X{
X extern char *malloc();
X reg char *copy;
X
X copy = malloc(strlen(str) + 1);
X strcpy(copy, str);
X return copy;
X}
SHAR_EOF
if test 4337 -ne "`wc -c < 'sub.c'`"
then
echo shar: "error transmitting 'sub.c'" '(should have been 4337 characters)'
fi
fi
echo shar: "extracting 'subcmd.c'" '(5233 characters)'
if test -f 'subcmd.c'
then
echo shar: "will not over-write existing file 'subcmd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'subcmd.c'
X/*
X** Subcmd - execute commands with arguments based on substitutions
X*/
X
Xstatic char
Xrcs_id[] = "$Header$";
X
X#include <stdio.h>
X#include <ctype.h>
X#include "std.h"
X
X#define MAXLEN 1024
X
Xchar var_char = 'X';
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X extern bool match();
X extern char *ground();
X reg char *cmd, *old, *new;
X reg int unmatched, i;
X reg bool fast, general, ignore, noexec, needzero;
X reg FILE *csh;
X char buf[MAXLEN];
X
X fast = FALSE;
X general = FALSE;
X ignore = FALSE;
X noexec = FALSE;
X needzero = TRUE;
X unmatched = 0;
X while (argc > 1 && argv[1][0] == '-')
X {
X for (i = 1; argv[1][i] != '\0'; i++)
X {
X switch (argv[1][i])
X {
X
X when 'f': fast = TRUE;
X
X when 'g': general = TRUE;
X
X when 'i': ignore = TRUE;
X
X when 'n': noexec = TRUE;
X
X when 'v': if (i != 1)
X usage();
X
X var_char = argv[1][2];
X goto nextword;
X
X when 'z': needzero = FALSE;
X
X otherwise: usage();
X
X }
X }
X
Xnextword:
X argc--;
X argv++;
X }
X
X if (argc < 3)
X usage();
X
X cmd = argv[1];
X old = argv[2];
X new = argv[3];
X argv += 3;
X argc -= 3;
X
X if (fast)
X {
X csh = popen("/bin/csh -fs", "w");
X if (csh == (FILE *) NULL)
X {
X printf("subcmd: cannot popen csh\n");
X exit(1);
X }
X }
X
X while (argc > 1)
X {
X if (! match(argv[1], old))
X unmatched++;
X else
X {
X if (general)
X sprintf(buf, cmd, argv[1], ground(new));
X else
X sprintf(buf, "%s %s %s", cmd, argv[1], ground(new));
X
X if (strlen(buf) >= MAXLEN)
X printf("subcmd: command too long\n");
X or (noexec)
X printf("would be executing %s\n", buf);
X or (fast)
X {
X printf("executing %s\n", buf);
X fprintf(csh, "%s\n", buf);
X }
X else
X {
X printf("executing %s\n", buf);
X if (system(buf) != 0 && needzero)
X printf("subcmd: command failed\n");
X }
X }
X
X argv++;
X argc--;
X }
X
X if (fast)
X pclose(csh);
X
X exit(ignore? 0: unmatched);
X}
X
X/*
X** Tell the unfortunate user how to use subcmd.
X*/
X
Xusage()
X{
X printf("Usage: subcmd [-fginz] [-vX] cmd oldpattern newpattern files ...\n");
X exit(1);
X}
X
X/*
X** Module to manipulate Cake patterns.
X*/
X
Xtypedef struct s_env
X{
X char *en_val;
X bool en_bound;
X} Env;
X
X#define NOVAR 10
X#define MAXVAR 11
X#define MAXSIZE 128
X
XEnv env[MAXVAR];
X
X/*
X** This function initialises the environment of domatch.
X*/
X
Xbool
Xmatch(str, pat)
Xreg char *str;
Xreg char *pat;
X{
X extern bool domatch();
X reg int i;
X reg char *s, *p;
X
X p = pat+strlen(pat)-1;
X if (*p != var_char && !isdigit(*p)) /* not part of a var */
X {
X s = str+strlen(str)-1;
X if (*s != *p) /* last chars differ */
X return FALSE;
X }
X
X for (i = 0; i < MAXVAR; i++)
X env[i].en_bound = FALSE;
X
X return domatch(str, pat);
X}
X
X/*
X** Match a string against a pattern.
X** The pattern is expected to have been dereferenced.
X** To handle nondeterminism, a brute force recursion approach
X** is taken.
X*/
X
Xbool
Xdomatch(str, patstr)
Xreg char *str;
Xreg char *patstr;
X{
X extern char *new_name();
X char buf[MAXSIZE];
X reg char *follow;
X reg char *s, *t;
X reg int varno;
X reg int i;
X reg bool more;
X
X if (patstr[0] == var_char)
X {
X if (isdigit(patstr[1]))
X {
X varno = patstr[1] - '0';
X follow = patstr + 2;
X }
X else
X {
X varno = NOVAR;
X follow = patstr + 1;
X }
X
X if (env[varno].en_bound)
X {
X /* lifetime of buf is local */
X strcpy(buf, env[varno].en_val);
X strcat(buf, follow);
X return domatch(str, buf);
X }
X
X i = 0;
X buf[0] = '\0';
X env[varno].en_bound = TRUE;
X env[varno].en_val = buf;
X
X /* keep invariant: buf = tentative value of var */
X /* must consider *s == \0, but do not overshoot */
X for (s = str, more = TRUE; more; s++)
X {
X if (domatch(s, follow))
X {
X /* lifetime of buf is now global */
X env[varno].en_val = new_name(buf);
X return TRUE;
X }
X
X /* maintain invariant */
X buf[i++] = *s;
X buf[i] = '\0';
X
X more = (*s != '\0');
X }
X
X /* no luck, match failed */
X env[varno].en_bound = FALSE;
X return FALSE;
X }
X
X /* here we have something other than a variable first off */
X for (s = str, t = patstr; *t != '\0' && *t != var_char; s++, t++)
X {
X if (*t == '\\')
X t++; /* the new *t is not checked for % */
X
X if (*s != *t)
X return FALSE;
X }
X
X /* see if we have come to the end of the pattern */
X if (*t == '\0')
X return *s == '\0';
X
X /* if not, recurse on the next variable */
X return domatch(s, t);
X}
X
X/*
X** Ground the argument string, i.e. replace all occurrences
X** of variables in it. It is fatal error for the string to
X** contain a variable which has no value.
X*/
X
Xchar *
Xground(str)
Xreg char *str;
X{
X extern char *new_name();
X reg char *s, *t;
X reg int i, var;
X char buf[MAXSIZE];
X
X i = 0;
X for (s = str; *s != '\0'; s++)
X {
X if (*s == var_char)
X {
X if (isdigit(s[1]))
X var = *++s - '0';
X else
X var = NOVAR;
X
X if (! env[var].en_bound)
X {
X printf("Attempt to use undefined value in %s\n", str);
X exit(1);
X }
X
X for (t = env[var].en_val; *t != '\0'; t++)
X buf[i++] = *t;
X }
X or (*s == '\\')
X {
X if (s[1] != '\0')
X buf[i++] = *++s;
X }
X else
X buf[i++] = *s;
X }
X
X if (i >= MAXSIZE)
X {
X printf("Ran out of buffer\n");
X exit(1);
X }
X
X buf[i] = '\0';
X return new_name(buf);
X}
X
Xchar *
Xnew_name(str)
Xreg char *str;
X{
X extern char *malloc();
X reg char *copy;
X
X copy = malloc(strlen(str) + 1);
X strcpy(copy, str);
X return copy;
X}
SHAR_EOF
if test 5233 -ne "`wc -c < 'subcmd.c'`"
then
echo shar: "error transmitting 'subcmd.c'" '(should have been 5233 characters)'
fi
fi
echo shar: "extracting 'usrc.c'" '(904 characters)'
if test -f 'usrc.c'
then
echo shar: "will not over-write existing file 'usrc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'usrc.c'
X/*
X** Track down ultimate source files.
X*/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "std.h"
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X char buf[80];
X struct stat statbuf;
X reg int i, j, errcnt;
X reg int lastsuf, firstfile;
X reg bool found;
X
X lastsuf = 0;
X firstfile = argc;
X for (i = 1; i < argc; i++)
X {
X if (argv[i][0] == '.')
X lastsuf = i;
X or (firstfile == argc)
X firstfile = i;
X }
X
X if (lastsuf > firstfile)
X {
X fprintf(stderr, "usrc: mixed suffixes and filenames\n");
X exit(1);
X }
X
X errcnt = 0;
X for (i = firstfile; i < argc; i++)
X {
X found = FALSE;
X for (j = lastsuf; j > 0; j--)
X {
X sprintf(buf, "%s%s", argv[i], argv[j]);
X if (stat(buf, &statbuf) == 0)
X {
X found = TRUE;
X printf("%s\n", buf);
X break;
X }
X }
X
X if (! found)
X {
X fprintf(stderr, "usrc: cannot find source for %s\n", argv[i]);
X errcnt++;
X }
X }
X
X exit(errcnt);
X}
SHAR_EOF
if test 904 -ne "`wc -c < 'usrc.c'`"
then
echo shar: "error transmitting 'usrc.c'" '(should have been 904 characters)'
fi
fi
exit 0
# End of shell archive