home *** CD-ROM | disk | FTP | other *** search
- Subject: v07i038: Release 2.0 of patch, Part01/03
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: sdcrdcf!lwall (Larry Wall)
- Mod.sources: Volume 7, Issue 38
- Archive-name: patch2/Part01
-
- Here is the official 2.0 release of patch. It supersedes the 1.5 beta
- version posted to net.sources, and the version that comes with 4.3bsd.
-
- Larry Wall
- sdcrdcf!lwall
-
- --------------------------CUT HERE---------------------------
- #! /bin/sh
-
- # Make a new directory for the patch sources, cd to it, and run kits 1 thru 3
- # through sh. When all 3 kits have been run, read README.
-
- echo "This is patch kit 1 (of 3). If kit 1 is complete, the line"
- echo '"'"End of kit 1 (of 3)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- echo Extracting pch.c
- sed >pch.c <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: pch.c,v 2.0 86/09/17 15:39:37 lwall Exp $
- X *
- X * $Log: pch.c,v $
- X * Revision 2.0 86/09/17 15:39:37 lwall
- X * Baseline for netwide release.
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "common.h"
- X#include "util.h"
- X#include "INTERN.h"
- X#include "pch.h"
- X
- X/* Patch (diff listing) abstract type. */
- X
- Xstatic long p_filesize; /* size of the patch file */
- Xstatic LINENUM p_first; /* 1st line number */
- Xstatic LINENUM p_newfirst; /* 1st line number of replacement */
- Xstatic LINENUM p_ptrn_lines; /* # lines in pattern */
- Xstatic LINENUM p_repl_lines; /* # lines in replacement text */
- Xstatic LINENUM p_end = -1; /* last line in hunk */
- Xstatic LINENUM p_max; /* max allowed value of p_end */
- Xstatic LINENUM p_context = 3; /* # of context lines */
- Xstatic LINENUM p_input_line = 0; /* current line # from patch file */
- Xstatic char **p_line = Null(char**); /* the text of the hunk */
- Xstatic short *p_len = Null(short*); /* length of each line */
- Xstatic char *p_char = Nullch; /* +, -, and ! */
- Xstatic int hunkmax = INITHUNKMAX; /* size of above arrays to begin with */
- Xstatic int p_indent; /* indent to patch */
- Xstatic LINENUM p_base; /* where to intuit this time */
- Xstatic LINENUM p_start; /* where intuit found a patch */
- X
- X/* Prepare to look for the next patch in the patch file. */
- X
- Xvoid
- Xre_patch()
- X{
- X p_first = Nulline;
- X p_newfirst = Nulline;
- X p_ptrn_lines = Nulline;
- X p_repl_lines = Nulline;
- X p_end = (LINENUM)-1;
- X p_max = Nulline;
- X p_indent = 0;
- X}
- X
- X/* Open the patch file at the beginning of time. */
- X
- Xvoid
- Xopen_patch_file(filename)
- Xchar *filename;
- X{
- X if (filename == Nullch || !*filename || strEQ(filename, "-")) {
- X pfp = fopen(TMPPATNAME, "w");
- X if (pfp == Nullfp)
- X fatal2("patch: can't create %s.\n", TMPPATNAME);
- X while (fgets(buf, sizeof buf, stdin) != Nullch)
- X fputs(buf, pfp);
- X Fclose(pfp);
- X filename = TMPPATNAME;
- X }
- X pfp = fopen(filename, "r");
- X if (pfp == Nullfp)
- X fatal2("patch file %s not found\n", filename);
- X Fstat(fileno(pfp), &filestat);
- X p_filesize = filestat.st_size;
- X next_intuit_at(0L); /* start at the beginning */
- X set_hunkmax();
- X}
- X
- X/* Make sure our dynamically realloced tables are malloced to begin with. */
- X
- Xvoid
- Xset_hunkmax()
- X{
- X#ifndef lint
- X if (p_line == Null(char**))
- X p_line = (char**) malloc((MEM)hunkmax * sizeof(char *));
- X if (p_len == Null(short*))
- X p_len = (short*) malloc((MEM)hunkmax * sizeof(short));
- X#endif
- X if (p_char == Nullch)
- X p_char = (char*) malloc((MEM)hunkmax * sizeof(char));
- X}
- X
- X/* Enlarge the arrays containing the current hunk of patch. */
- X
- Xvoid
- Xgrow_hunkmax()
- X{
- X hunkmax *= 2;
- X /*
- X * Note that on most systems, only the p_line array ever gets fresh memory
- X * since p_len can move into p_line's old space, and p_char can move into
- X * p_len's old space. Not on PDP-11's however. But it doesn't matter.
- X */
- X assert(p_line != Null(char**) && p_len != Null(short*) && p_char != Nullch);
- X#ifndef lint
- X p_line = (char**) realloc((char*)p_line, (MEM)hunkmax * sizeof(char *));
- X p_len = (short*) realloc((char*)p_len, (MEM)hunkmax * sizeof(short));
- X p_char = (char*) realloc((char*)p_char, (MEM)hunkmax * sizeof(char));
- X#endif
- X if (p_line != Null(char**) && p_len != Null(short*) && p_char != Nullch)
- X return;
- X if (!using_plan_a)
- X fatal1("patch: out of memory (grow_hunkmax)\n");
- X out_of_mem = TRUE; /* whatever is null will be allocated again */
- X /* from within plan_a(), of all places */
- X}
- X
- X/* True if the remainder of the patch file contains a diff of some sort. */
- X
- Xbool
- Xthere_is_another_patch()
- X{
- X if (p_base != 0L && p_base >= p_filesize) {
- X if (verbose)
- X say1("done\n");
- X return FALSE;
- X }
- X if (verbose)
- X say1("Hmm...");
- X diff_type = intuit_diff_type();
- X if (!diff_type) {
- X if (p_base != 0L) {
- X if (verbose)
- X say1(" Ignoring the trailing garbage.\ndone\n");
- X }
- X else
- X say1(" I can't seem to find a patch in there anywhere.\n");
- X return FALSE;
- X }
- X if (verbose)
- X say3(" %sooks like %s to me...\n",
- X (p_base == 0L ? "L" : "The next patch l"),
- X diff_type == CONTEXT_DIFF ? "a context diff" :
- X diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" :
- X diff_type == NORMAL_DIFF ? "a normal diff" :
- X "an ed script" );
- X if (p_indent && verbose)
- X say3("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s");
- X skip_to(p_start);
- X while (filearg[0] == Nullch) {
- X if (force) {
- X say1("No file to patch. Skipping...\n");
- X filearg[0] = savestr(bestguess);
- X return TRUE;
- X }
- X ask1("File to patch: ");
- X if (*buf != '\n') {
- X if (bestguess)
- X free(bestguess);
- X bestguess = savestr(buf);
- X filearg[0] = fetchname(buf, 0, FALSE);
- X }
- X if (filearg[0] == Nullch) {
- X ask1("No file found--skip this patch? [n] ");
- X if (*buf != 'y') {
- X continue;
- X }
- X if (verbose)
- X say1("Skipping patch...\n");
- X filearg[0] = fetchname(bestguess, 0, TRUE);
- X skip_rest_of_patch = TRUE;
- X return TRUE;
- X }
- X }
- X return TRUE;
- X}
- X
- X/* Determine what kind of diff is in the remaining part of the patch file. */
- X
- Xint
- Xintuit_diff_type()
- X{
- X Reg4 long this_line = 0;
- X Reg5 long previous_line;
- X Reg6 long first_command_line = -1;
- X Reg7 bool last_line_was_command = FALSE;
- X Reg8 bool this_is_a_command = FALSE;
- X Reg9 bool stars_last_line = FALSE;
- X Reg10 bool stars_this_line = FALSE;
- X Reg3 int indent;
- X Reg1 char *s;
- X Reg2 char *t;
- X char *indtmp = Nullch;
- X char *oldtmp = Nullch;
- X char *newtmp = Nullch;
- X char *indname = Nullch;
- X char *oldname = Nullch;
- X char *newname = Nullch;
- X Reg11 int retval;
- X bool no_filearg = (filearg[0] == Nullch);
- X
- X ok_to_create_file = FALSE;
- X Fseek(pfp, p_base, 0);
- X for (;;) {
- X previous_line = this_line;
- X last_line_was_command = this_is_a_command;
- X stars_last_line = stars_this_line;
- X this_line = ftell(pfp);
- X indent = 0;
- X if (fgets(buf, sizeof buf, pfp) == Nullch) {
- X if (first_command_line >= 0L) {
- X /* nothing but deletes!? */
- X p_start = first_command_line;
- X retval = ED_DIFF;
- X goto scan_exit;
- X }
- X else {
- X p_start = this_line;
- X retval = 0;
- X goto scan_exit;
- X }
- X }
- X for (s = buf; *s == ' ' || *s == '\t'; s++) {
- X if (*s == '\t')
- X indent += 8 - (indent % 8);
- X else
- X indent++;
- X }
- X for (t=s; isdigit(*t) || *t == ','; t++) ;
- X this_is_a_command = (isdigit(*s) &&
- X (*t == 'd' || *t == 'c' || *t == 'a') );
- X if (first_command_line < 0L && this_is_a_command) {
- X first_command_line = this_line;
- X p_indent = indent; /* assume this for now */
- X }
- X if (!stars_last_line && strnEQ(s, "*** ", 4))
- X oldtmp = savestr(s+4);
- X else if (strnEQ(s, "--- ", 4))
- X newtmp = savestr(s+4);
- X else if (strnEQ(s, "Index:", 6))
- X indtmp = savestr(s+6);
- X else if (strnEQ(s, "Prereq:", 7)) {
- X for (t=s+7; isspace(*t); t++) ;
- X revision = savestr(t);
- X for (t=revision; *t && !isspace(*t); t++) ;
- X *t = '\0';
- X if (!*revision) {
- X free(revision);
- X revision = Nullch;
- X }
- X }
- X if ((!diff_type || diff_type == ED_DIFF) &&
- X first_command_line >= 0L &&
- X strEQ(s, ".\n") ) {
- X p_indent = indent;
- X p_start = first_command_line;
- X retval = ED_DIFF;
- X goto scan_exit;
- X }
- X stars_this_line = strnEQ(s, "********", 8);
- X if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line &&
- X strnEQ(s, "*** ", 4)) {
- X if (!atol(s+4))
- X ok_to_create_file = TRUE;
- X /* if this is a new context diff the character just before */
- X /* the newline is a '*'. */
- X while (*s != '\n')
- X s++;
- X p_indent = indent;
- X p_start = previous_line;
- X retval = (*(s-1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF);
- X goto scan_exit;
- X }
- X if ((!diff_type || diff_type == NORMAL_DIFF) &&
- X last_line_was_command &&
- X (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2)) ) {
- X p_start = previous_line;
- X p_indent = indent;
- X retval = NORMAL_DIFF;
- X goto scan_exit;
- X }
- X }
- X scan_exit:
- X if (no_filearg) {
- X if (indtmp != Nullch)
- X indname = fetchname(indtmp, strippath, ok_to_create_file);
- X if (oldtmp != Nullch)
- X oldname = fetchname(oldtmp, strippath, ok_to_create_file);
- X if (newtmp != Nullch)
- X newname = fetchname(newtmp, strippath, ok_to_create_file);
- X if (oldname && newname) {
- X if (strlen(oldname) < strlen(newname))
- X filearg[0] = savestr(oldname);
- X else
- X filearg[0] = savestr(newname);
- X }
- X else if (oldname)
- X filearg[0] = savestr(oldname);
- X else if (newname)
- X filearg[0] = savestr(newname);
- X else if (indname)
- X filearg[0] = savestr(indname);
- X }
- X if (bestguess) {
- X free(bestguess);
- X bestguess = Nullch;
- X }
- X if (filearg[0] != Nullch)
- X bestguess = savestr(filearg[0]);
- X else if (indtmp != Nullch)
- X bestguess = fetchname(indtmp, strippath, TRUE);
- X else {
- X if (oldtmp != Nullch)
- X oldname = fetchname(oldtmp, strippath, TRUE);
- X if (newtmp != Nullch)
- X newname = fetchname(newtmp, strippath, TRUE);
- X if (oldname && newname) {
- X if (strlen(oldname) < strlen(newname))
- X bestguess = savestr(oldname);
- X else
- X bestguess = savestr(newname);
- X }
- X else if (oldname)
- X bestguess = savestr(oldname);
- X else if (newname)
- X bestguess = savestr(newname);
- X }
- X if (indtmp != Nullch)
- X free(indtmp);
- X if (oldtmp != Nullch)
- X free(oldtmp);
- X if (newtmp != Nullch)
- X free(newtmp);
- X if (indname != Nullch)
- X free(indname);
- X if (oldname != Nullch)
- X free(oldname);
- X if (newname != Nullch)
- X free(newname);
- X return retval;
- X}
- X
- X/* Remember where this patch ends so we know where to start up again. */
- X
- Xvoid
- Xnext_intuit_at(file_pos)
- Xlong file_pos;
- X{
- X p_base = file_pos;
- X}
- X
- X/* Basically a verbose fseek() to the actual diff listing. */
- X
- Xvoid
- Xskip_to(file_pos)
- Xlong file_pos;
- X{
- X char *ret;
- X
- X assert(p_base <= file_pos);
- X if (verbose && p_base < file_pos) {
- X Fseek(pfp, p_base, 0);
- X say1("The text leading up to this was:\n--------------------------\n");
- X while (ftell(pfp) < file_pos) {
- X ret = fgets(buf, sizeof buf, pfp);
- X assert(ret != Nullch);
- X say2("|%s", buf);
- X }
- X say1("--------------------------\n");
- X }
- X else
- X Fseek(pfp, file_pos, 0);
- X}
- X
- X/* True if there is more of the current diff listing to process. */
- X
- Xbool
- Xanother_hunk()
- X{
- X Reg1 char *s;
- X Reg8 char *ret;
- X Reg2 int context = 0;
- X
- X while (p_end >= 0) {
- X free(p_line[p_end]); /* Changed from postdecrement */
- X p_end--; /* by Keenan Ross for BSD2.9 */
- X }
- X assert(p_end == -1);
- X
- X p_max = hunkmax; /* gets reduced when --- found */
- X if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
- X long line_beginning = ftell(pfp);
- X /* file pos of the current line */
- X LINENUM repl_beginning = 0; /* index of --- line */
- X Reg4 LINENUM fillcnt = 0; /* #lines of missing ptrn or repl */
- X Reg5 LINENUM fillsrc; /* index of first line to copy */
- X Reg6 LINENUM filldst; /* index of first missing line */
- X bool ptrn_spaces_eaten = FALSE; /* ptrn was slightly misformed */
- X Reg9 bool repl_could_be_missing = TRUE;
- X /* no + or ! lines in this hunk */
- X bool repl_missing = FALSE; /* we are now backtracking */
- X long repl_backtrack_position = 0;
- X /* file pos of first repl line */
- X Reg7 LINENUM ptrn_copiable = 0;
- X /* # of copiable lines in ptrn */
- X
- X ret = pgets(buf, sizeof buf, pfp);
- X if (ret == Nullch || strnNE(buf, "********", 8)) {
- X next_intuit_at(line_beginning);
- X return FALSE;
- X }
- X p_context = 100;
- X while (p_end < p_max) {
- X line_beginning = ftell(pfp);
- X ret = pgets(buf, sizeof buf, pfp);
- X if (ret == Nullch) {
- X if (p_max - p_end < 4)
- X Strcpy(buf, " \n"); /* assume blank lines got chopped */
- X else {
- X if (repl_beginning && repl_could_be_missing) {
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X fatal1("Unexpected end of file in patch.\n");
- X }
- X }
- X p_input_line++;
- X p_char[++p_end] = *buf;
- X p_line[p_end] = Nullch;
- X switch (*buf) {
- X case '*':
- X if (strnEQ(buf, "********", 8)) {
- X if (repl_beginning && repl_could_be_missing) {
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X else
- X fatal2("Unexpected end of hunk at line %ld.\n",
- X p_input_line);
- X }
- X if (p_end != 0) {
- X if (repl_beginning && repl_could_be_missing) {
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X fatal3("Unexpected *** at line %ld: %s", p_input_line, buf);
- X }
- X context = 0;
- X p_line[p_end] = savestr(buf);
- X if (out_of_mem) {
- X p_end--;
- X return FALSE;
- X }
- X for (s=buf; *s && !isdigit(*s); s++) ;
- X if (!*s)
- X goto malformed;
- X p_first = (LINENUM) atol(s);
- X while (isdigit(*s)) s++;
- X if (*s == ',') {
- X for (; *s && !isdigit(*s); s++) ;
- X if (!*s)
- X goto malformed;
- X p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1;
- X }
- X else if (p_first)
- X p_ptrn_lines = 1;
- X else {
- X p_ptrn_lines = 0;
- X p_first = 1;
- X }
- X break;
- X case '-':
- X if (buf[1] == '-') {
- X if (p_end != p_ptrn_lines + 1 &&
- X p_end != p_ptrn_lines + 2) {
- X if (p_end == 1) {
- X /* `old' lines were omitted - set up to fill */
- X /* them in from 'new' context lines. */
- X p_end = p_ptrn_lines + 1;
- X fillsrc = p_end + 1;
- X filldst = 1;
- X fillcnt = p_ptrn_lines;
- X }
- X else {
- X if (repl_beginning && repl_could_be_missing){
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X fatal3("Unexpected --- at line %ld: %s",
- X p_input_line, buf);
- X }
- X }
- X repl_beginning = p_end;
- X repl_backtrack_position = ftell(pfp);
- X p_line[p_end] = savestr(buf);
- X if (out_of_mem) {
- X p_end--;
- X return FALSE;
- X }
- X p_char[p_end] = '=';
- X for (s=buf; *s && !isdigit(*s); s++) ;
- X if (!*s)
- X goto malformed;
- X p_newfirst = (LINENUM) atol(s);
- X while (isdigit(*s)) s++;
- X if (*s == ',') {
- X for (; *s && !isdigit(*s); s++) ;
- X if (!*s)
- X goto malformed;
- X p_repl_lines = ((LINENUM)atol(s)) - p_newfirst + 1;
- X }
- X else if (p_newfirst)
- X p_repl_lines = 1;
- X else {
- X p_repl_lines = 0;
- X p_newfirst = 1;
- X }
- X p_max = p_repl_lines + p_end;
- X if (p_max > MAXHUNKSIZE)
- X fatal4("Hunk too large (%ld lines) at line %ld: %s",
- X p_max, p_input_line, buf);
- X while (p_max >= hunkmax)
- X grow_hunkmax();
- X if (p_repl_lines != ptrn_copiable)
- X repl_could_be_missing = FALSE;
- X break;
- X }
- X goto change_line;
- X case '+': case '!':
- X repl_could_be_missing = FALSE;
- X change_line:
- X if (!isspace(buf[1]) && buf[1] != '>' && buf[1] != '<' &&
- X repl_beginning && repl_could_be_missing) {
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X if (context > 0) {
- X if (context < p_context)
- X p_context = context;
- X context = -1000;
- X }
- X p_line[p_end] = savestr(buf+2);
- X if (out_of_mem) {
- X p_end--;
- X return FALSE;
- X }
- X break;
- X case '\t': case '\n': /* assume the 2 spaces got eaten */
- X if (repl_beginning && repl_could_be_missing &&
- X (!ptrn_spaces_eaten || diff_type == NEW_CONTEXT_DIFF) ) {
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X p_line[p_end] = savestr(buf);
- X if (out_of_mem) {
- X p_end--;
- X return FALSE;
- X }
- X if (p_end != p_ptrn_lines + 1) {
- X ptrn_spaces_eaten |= (repl_beginning != 0);
- X context++;
- X if (!repl_beginning)
- X ptrn_copiable++;
- X p_char[p_end] = ' ';
- X }
- X break;
- X case ' ':
- X if (!isspace(buf[1]) &&
- X repl_beginning && repl_could_be_missing) {
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X context++;
- X if (!repl_beginning)
- X ptrn_copiable++;
- X p_line[p_end] = savestr(buf+2);
- X if (out_of_mem) {
- X p_end--;
- X return FALSE;
- X }
- X break;
- X default:
- X if (repl_beginning && repl_could_be_missing) {
- X repl_missing = TRUE;
- X goto hunk_done;
- X }
- X goto malformed;
- X }
- X /* set up p_len for strncmp() so we don't have to */
- X /* assume null termination */
- X if (p_line[p_end])
- X p_len[p_end] = strlen(p_line[p_end]);
- X else
- X p_len[p_end] = 0;
- X }
- X
- X hunk_done:
- X if (p_end >=0 && !repl_beginning)
- X fatal2("No --- found in patch at line %ld\n", pch_hunk_beg());
- X
- X if (repl_missing) {
- X
- X /* reset state back to just after --- */
- X for (p_end--; p_end > repl_beginning; p_end--)
- X free(p_line[p_end]);
- X Fseek(pfp, repl_backtrack_position, 0);
- X
- X /* redundant 'new' context lines were omitted - set */
- X /* up to fill them in from the old file context */
- X fillsrc = 1;
- X filldst = repl_beginning+1;
- X fillcnt = p_repl_lines;
- X p_end = p_max;
- X }
- X
- X if (diff_type == CONTEXT_DIFF &&
- X (fillcnt || ptrn_copiable > 2*p_context) ) {
- X if (verbose)
- X say1("\
- X(Fascinating--this is really a new-style context diff but without the telltale\n\
- Xextra asterisks on the *** line that usually indicate the new style...)\n");
- X diff_type = NEW_CONTEXT_DIFF;
- X }
- X
- X /* if there were omitted context lines, fill them in now */
- X if (fillcnt) {
- X while (fillcnt-- > 0) {
- X while (p_char[fillsrc] != ' ')
- X fillsrc++;
- X p_line[filldst] = p_line[fillsrc];
- X p_char[filldst] = p_char[fillsrc];
- X p_len[filldst] = p_len[fillsrc];
- X fillsrc++; filldst++;
- X }
- X while (fillsrc <= p_end && p_char[fillsrc] != ' ')
- X fillsrc++;
- X#ifdef DEBUGGING
- X if (debug & 64)
- X printf("fillsrc %ld, filldst %ld, rb %ld, e+1 %ld\n",
- X fillsrc,filldst,repl_beginning,p_end+1);
- X#endif
- X assert(fillsrc==p_end+1 || fillsrc==repl_beginning);
- X assert(filldst==p_end+1 || filldst==repl_beginning);
- X }
- X }
- X else { /* normal diff--fake it up */
- X char hunk_type;
- X Reg3 int i;
- X LINENUM min, max;
- X long line_beginning = ftell(pfp);
- X
- X p_context = 0;
- X ret = pgets(buf, sizeof buf, pfp);
- X p_input_line++;
- X if (ret == Nullch || !isdigit(*buf)) {
- X next_intuit_at(line_beginning);
- X return FALSE;
- X }
- X p_first = (LINENUM)atol(buf);
- X for (s=buf; isdigit(*s); s++) ;
- X if (*s == ',') {
- X p_ptrn_lines = (LINENUM)atol(++s) - p_first + 1;
- X while (isdigit(*s)) s++;
- X }
- X else
- X p_ptrn_lines = (*s != 'a');
- X hunk_type = *s;
- X if (hunk_type == 'a')
- X p_first++; /* do append rather than insert */
- X min = (LINENUM)atol(++s);
- X for (; isdigit(*s); s++) ;
- X if (*s == ',')
- X max = (LINENUM)atol(++s);
- X else
- X max = min;
- X if (hunk_type == 'd')
- X min++;
- X p_end = p_ptrn_lines + 1 + max - min + 1;
- X if (p_end > MAXHUNKSIZE)
- X fatal4("Hunk too large (%ld lines) at line %ld: %s",
- X p_end, p_input_line, buf);
- X while (p_end >= hunkmax)
- X grow_hunkmax();
- X p_newfirst = min;
- X p_repl_lines = max - min + 1;
- X Sprintf(buf, "*** %ld,%ld\n", p_first, p_first + p_ptrn_lines - 1);
- X p_line[0] = savestr(buf);
- X if (out_of_mem) {
- X p_end = -1;
- X return FALSE;
- X }
- X p_char[0] = '*';
- X for (i=1; i<=p_ptrn_lines; i++) {
- X ret = pgets(buf, sizeof buf, pfp);
- X p_input_line++;
- X if (ret == Nullch)
- X fatal2("Unexpected end of file in patch at line %ld.\n",
- X p_input_line);
- X if (*buf != '<')
- X fatal2("< expected at line %ld of patch.\n", p_input_line);
- X p_line[i] = savestr(buf+2);
- X if (out_of_mem) {
- X p_end = i-1;
- X return FALSE;
- X }
- X p_len[i] = strlen(p_line[i]);
- X p_char[i] = '-';
- X }
- X if (hunk_type == 'c') {
- X ret = pgets(buf, sizeof buf, pfp);
- X p_input_line++;
- X if (ret == Nullch)
- X fatal2("Unexpected end of file in patch at line %ld.\n",
- X p_input_line);
- X if (*buf != '-')
- X fatal2("--- expected at line %ld of patch.\n", p_input_line);
- X }
- X Sprintf(buf, "--- %ld,%ld\n", min, max);
- X p_line[i] = savestr(buf);
- X if (out_of_mem) {
- X p_end = i-1;
- X return FALSE;
- X }
- X p_char[i] = '=';
- X for (i++; i<=p_end; i++) {
- X ret = pgets(buf, sizeof buf, pfp);
- X p_input_line++;
- X if (ret == Nullch)
- X fatal2("Unexpected end of file in patch at line %ld.\n",
- X p_input_line);
- X if (*buf != '>')
- X fatal2("> expected at line %ld of patch.\n", p_input_line);
- X p_line[i] = savestr(buf+2);
- X if (out_of_mem) {
- X p_end = i-1;
- X return FALSE;
- X }
- X p_len[i] = strlen(p_line[i]);
- X p_char[i] = '+';
- X }
- X }
- X if (reverse) /* backwards patch? */
- X if (!pch_swap())
- X say1("Not enough memory to swap next hunk!\n");
- X#ifdef DEBUGGING
- X if (debug & 2) {
- X int i;
- X char special;
- X
- X for (i=0; i <= p_end; i++) {
- X if (i == p_ptrn_lines)
- X special = '^';
- X else
- X special = ' ';
- X fprintf(stderr, "%3d %c %c %s", i, p_char[i], special, p_line[i]);
- X Fflush(stderr);
- X }
- X }
- X#endif
- X if (p_end+1 < hunkmax) /* paranoia reigns supreme... */
- X p_char[p_end+1] = '^'; /* add a stopper for apply_hunk */
- X return TRUE;
- X
- Xmalformed:
- X fatal3("Malformed patch at line %ld: %s", p_input_line, buf);
- X /* about as informative as "Syntax error" in C */
- X return FALSE; /* for lint */
- X}
- X
- X/* Input a line from the patch file, worrying about indentation. */
- X
- Xchar *
- Xpgets(bf,sz,fp)
- Xchar *bf;
- Xint sz;
- XFILE *fp;
- X{
- X char *ret = fgets(bf, sz, fp);
- X Reg1 char *s;
- X Reg2 int indent = 0;
- X
- X if (p_indent && ret != Nullch) {
- X for (s=buf; indent < p_indent && (*s == ' ' || *s == '\t'); s++) {
- X if (*s == '\t')
- X indent += 8 - (indent % 7);
- X else
- X indent++;
- X }
- X if (buf != s)
- X Strcpy(buf, s);
- X }
- X return ret;
- X}
- X
- X/* Reverse the old and new portions of the current hunk. */
- X
- Xbool
- Xpch_swap()
- X{
- X char **tp_line; /* the text of the hunk */
- X short *tp_len; /* length of each line */
- X char *tp_char; /* +, -, and ! */
- X Reg1 LINENUM i;
- X Reg2 LINENUM n;
- X bool blankline = FALSE;
- X Reg3 char *s;
- X
- X i = p_first;
- X p_first = p_newfirst;
- X p_newfirst = i;
- X
- X /* make a scratch copy */
- X
- X tp_line = p_line;
- X tp_len = p_len;
- X tp_char = p_char;
- X p_line = Null(char**); /* force set_hunkmax to allocate again */
- X p_len = Null(short*);
- X p_char = Nullch;
- X set_hunkmax();
- X if (p_line == Null(char**) || p_len == Null(short*) || p_char == Nullch) {
- X#ifndef lint
- X if (p_line == Null(char**))
- X free((char*)p_line);
- X p_line = tp_line;
- X if (p_len == Null(short*))
- X free((char*)p_len);
- X p_len = tp_len;
- X#endif
- X if (p_char == Nullch)
- X free((char*)p_char);
- X p_char = tp_char;
- X return FALSE; /* not enough memory to swap hunk! */
- X }
- X
- X /* now turn the new into the old */
- X
- X i = p_ptrn_lines + 1;
- X if (tp_char[i] == '\n') { /* account for possible blank line */
- X blankline = TRUE;
- X i++;
- X }
- X for (n=0; i <= p_end; i++,n++) {
- X p_line[n] = tp_line[i];
- X p_char[n] = tp_char[i];
- X if (p_char[n] == '+')
- X p_char[n] = '-';
- X p_len[n] = tp_len[i];
- X }
- X if (blankline) {
- X i = p_ptrn_lines + 1;
- X p_line[n] = tp_line[i];
- X p_char[n] = tp_char[i];
- X p_len[n] = tp_len[i];
- X n++;
- X }
- X assert(p_char[0] == '=');
- X p_char[0] = '*';
- X for (s=p_line[0]; *s; s++)
- X if (*s == '-')
- X *s = '*';
- X
- X /* now turn the old into the new */
- X
- X assert(tp_char[0] == '*');
- X tp_char[0] = '=';
- X for (s=tp_line[0]; *s; s++)
- X if (*s == '*')
- X *s = '-';
- X for (i=0; n <= p_end; i++,n++) {
- X p_line[n] = tp_line[i];
- X p_char[n] = tp_char[i];
- X if (p_char[n] == '-')
- X p_char[n] = '+';
- X p_len[n] = tp_len[i];
- X }
- X assert(i == p_ptrn_lines + 1);
- X i = p_ptrn_lines;
- X p_ptrn_lines = p_repl_lines;
- X p_repl_lines = i;
- X#ifndef lint
- X if (tp_line == Null(char**))
- X free((char*)tp_line);
- X if (tp_len == Null(short*))
- X free((char*)tp_len);
- X#endif
- X if (tp_char == Nullch)
- X free((char*)tp_char);
- X return TRUE;
- X}
- X
- X/* Return the specified line position in the old file of the old context. */
- X
- XLINENUM
- Xpch_first()
- X{
- X return p_first;
- X}
- X
- X/* Return the number of lines of old context. */
- X
- XLINENUM
- Xpch_ptrn_lines()
- X{
- X return p_ptrn_lines;
- X}
- X
- X/* Return the probable line position in the new file of the first line. */
- X
- XLINENUM
- Xpch_newfirst()
- X{
- X return p_newfirst;
- X}
- X
- X/* Return the number of lines in the replacement text including context. */
- X
- XLINENUM
- Xpch_repl_lines()
- X{
- X return p_repl_lines;
- X}
- X
- X/* Return the number of lines in the whole hunk. */
- X
- XLINENUM
- Xpch_end()
- X{
- X return p_end;
- X}
- X
- X/* Return the number of context lines before the first changed line. */
- X
- XLINENUM
- Xpch_context()
- X{
- X return p_context;
- X}
- X
- X/* Return the length of a particular patch line. */
- X
- Xshort
- Xpch_line_len(line)
- XLINENUM line;
- X{
- X return p_len[line];
- X}
- X
- X/* Return the control character (+, -, *, !, etc) for a patch line. */
- X
- Xchar
- Xpch_char(line)
- XLINENUM line;
- X{
- X return p_char[line];
- X}
- X
- X/* Return a pointer to a particular patch line. */
- X
- Xchar *
- Xpfetch(line)
- XLINENUM line;
- X{
- X return p_line[line];
- X}
- X
- X/* Return where in the patch file this hunk began, for error messages. */
- X
- XLINENUM
- Xpch_hunk_beg()
- X{
- X return p_input_line - p_end - 1;
- X}
- X
- !STUFFY!FUNK!
- echo Extracting Configure
- sed >Configure <<'!STUFFY!FUNK!' -e 's/X//'
- X#! /bin/sh
- X#
- X# If these # comments don't work, trim them. Don't worry about any other
- X# shell scripts, Configure will trim # comments from them for you.
- X#
- X# Note: if you are running ksh, be sure to say "sh Configure".
- X#
- X# (If you are trying to port this package to a machine without sh, I would
- X# suggest you cut out the prototypical config.h from the end of Configure
- X# and edit it to reflect your system. Some packages may include samples
- X# of config.h for certain machines, so you might look for one of those.)
- X#
- X# $Header: Configure,v 2.0 86/09/17 15:32:58 lwall Exp $
- X#
- X# $Log: Configure,v $
- X# Revision 2.0 86/09/17 15:32:58 lwall
- X# Baseline for netwide release.
- X#
- X#
- X# Yes, you may rip this off to use in other distribution packages.
- X#
- X# (Note: this Configure script was generated automatically. Rather than
- X# working with this copy of Configure, you may wish to get metaconfig.)
- X
- Xdefine='define'
- Xundef='/*undef'
- X
- Xd_eunice=''
- Xeunicefix=''
- Xloclist=''
- Xexpr=''
- Xsed=''
- Xecho=''
- Xcat=''
- Xrm=''
- Xmv=''
- Xcp=''
- Xtail=''
- Xtr=''
- Xmkdir=''
- Xsort=''
- Xuniq=''
- Xgrep=''
- Xtrylist=''
- Xtest=''
- Xinews=''
- Xegrep=''
- Xmore=''
- Xpg=''
- XMcc=''
- Xvi=''
- Xmailx=''
- XLog=''
- XHeader=''
- Xbin=''
- Xcc=''
- Xcontains=''
- Xcpp=''
- Xd_index=''
- Xd_void=''
- Xiandd=''
- Xlibc=''
- Xmansrc=''
- Xmanext=''
- Xn=''
- Xc=''
- Xpackage=''
- Xregisters=''
- Xreg1=''
- Xreg2=''
- Xreg3=''
- Xreg4=''
- Xreg5=''
- Xreg6=''
- Xreg7=''
- Xreg8=''
- Xreg9=''
- Xreg10=''
- Xreg11=''
- Xreg12=''
- Xreg13=''
- Xreg14=''
- Xreg15=''
- Xreg16=''
- Xspitshell=''
- Xshsharp=''
- Xsharpbang=''
- Xstartsh=''
- XCONFIG=''
- X
- Xpackage=patch
- X
- Xecho "Beginning of configuration questions for $package kit."
- X: Eunice requires " " instead of "", can you believe it
- Xecho " "
- X
- X: sanity checks
- XPATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc'
- Xexport PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0; kill $$)
- X
- Xif test ! -t 0; then
- X echo "Say 'sh Configure', not 'sh <Configure'"
- X exit 1
- Xfi
- X
- X: some greps do not return status, grrr.
- Xecho "grimblepritz" >grimble
- Xif grep blurfldyick grimble >/dev/null 2>&1 ; then
- X contains=contains
- Xelse
- X if grep grimblepritz grimble >/dev/null 2>&1 ; then
- X contains=grep
- X else
- X contains=contains
- X fi
- Xfi
- Xrm -f grimble
- X: the following should work in any shell
- Xcase "$contains" in
- Xcontains*)
- X echo " "
- X echo "AGH! Grep doesn't return a status. Attempting remedial action."
- X cat >contains <<'EOSS'
- Xgrep "$1" "$2" >.greptmp && cat .greptmp && test -s .greptmp
- XEOSS
- Xchmod 755 contains
- Xesac
- X
- X: first determine how to suppress newline on echo command
- Xecho "Checking echo to see how to suppress newlines..."
- X(echo "hi there\c" ; echo " ") >.echotmp
- Xif $contains c .echotmp >/dev/null 2>&1 ; then
- X echo "...using -n."
- X n='-n'
- X c=''
- Xelse
- X echo "...using \\\c"
- X echo "c."
- X n=''
- X c='\c'
- Xfi
- Xecho $n "Type carriage return to continue. Your cursor should be here-->$c"
- Xread ans
- Xrm -f .echotmp
- X
- X: now set up to do reads with possible shell escape
- X: if this does not work on your machine, 1,$ s/. myread/read ans/
- Xcat <<EOSC >myread
- Xans='!'
- Xwhile expr "X\$ans" : "X!" >/dev/null; do
- X read ans
- X case "\$ans" in
- X !)
- X sh
- X echo " "
- X echo $n "\$rp $c"
- X ;;
- X !*)
- X set \`expr "X\$ans" : "X!\(.*\)\$"\`
- X sh -c "\$*"
- X echo " "
- X echo $n "\$rp $c"
- X ;;
- X esac
- Xdone
- Xrp='Your answer:'
- XEOSC
- X
- X: general instructions
- Xcat <<EOH
- X
- XThis installation shell script will examine your system and ask you questions
- Xto determine how $package and any auxiliary files should be installed. If you
- Xget stuck on a question, you may use a ! shell escape to start a subshell or
- Xexecute a command. Many of the questions will have default answers in
- Xsquare brackets--typing carriage return will give you the default.
- X
- XOn some of the questions which ask for file or directory names you are
- Xallowed to use the ~name construct to specify the login directory belonging
- Xto "name", even if you don't have a shell which knows about that. Questions
- Xwhere this is allowed will be marked "(~name ok)".
- XEOH
- Xrp="[Type carriage return to continue]"
- Xecho $n "$rp $c"
- X. myread
- Xcat <<EOH
- XMuch effort has been expended to ensure that this shell script will run
- Xon any Unix system. If despite that it blows up on you, your best bet is
- Xto edit Configure and run it again. (Trying to install this package
- Xwithout having run Configure may be well nigh impossible.) Also, let me
- X(lwall@sdcrdcf.UUCP) know how I blew it.
- X
- XThis installation script affects things in two ways: 1) it may do direct
- Xvariable substitutions on some of the files included in this kit, and
- X2) it builds a config.h file for inclusion in C programs. You may edit
- Xany of these files as the need arises after running this script.
- X
- XEOH
- Xrp="[Type carriage return to continue]"
- Xecho $n "$rp $c"
- X. myread
- X
- X: get old answers, if there is a config file out there
- Xif test -f config.sh; then
- X echo " "
- X rp="I see a config.sh file. Did Configure make it on THIS system? [y]"
- X echo $n "$rp $c"
- X . myread
- X case "$ans" in
- X n*) echo "OK, I'll ignore it.";;
- X *) echo "Fetching default answers from your old config.sh file..."
- X . config.sh
- X ;;
- X esac
- Xfi
- X
- X: get list of predefined functions in a handy place
- Xecho " "
- Xif test -f /lib/libc.a; then
- X echo "Your C library is in /lib/libc.a. You're normal."
- X libc=/lib/libc.a
- Xelse
- X if test -f /usr/lib/libc.a; then
- X echo "Your C library is in /usr/lib/libc.a, of all places."
- X libc=/usr/lib/libc.a
- X else
- X if test -f "$libc"; then
- X echo "Your C library is in $libc, like you said before."
- X else
- X cat <<'EOM'
- X
- XI can't seem to find your C library. I've looked for /lib/libc.a and
- X/usr/lib/libc.a, but neither of those are there. What is the full name
- XEOM
- X echo $n "of your C library? $c"
- X rp='C library full name?'
- X . myread
- X libc="$ans"
- X fi
- X fi
- Xfi
- Xecho " "
- Xecho $n "Extracting names from $libc for later perusal...$c"
- Xif ar t $libc > libc.list; then
- X echo "done"
- Xelse
- X echo " "
- X echo "The archiver doesn't think $libc is a reasonable library."
- X exit 1
- Xfi
- X
- X: make some quick guesses about what we are up against
- Xecho " "
- Xecho $n "Hmm... $c"
- Xif $contains SIGTSTP /usr/include/signal.h >/dev/null 2>&1 ; then
- X echo "Looks kind of like a BSD system, but we'll see..."
- X echo exit 0 >bsd
- X echo exit 1 >usg
- X echo exit 1 >v7
- Xelse
- X if $contains fcntl libc.list >/dev/null 2>&1 ; then
- X echo "Looks kind of like a USG system, but we'll see..."
- X echo exit 1 >bsd
- X echo exit 0 >usg
- X echo exit 1 >v7
- X else
- X echo "Looks kind of like a version 7 system, but we'll see..."
- X echo exit 1 >bsd
- X echo exit 1 >usg
- X echo exit 0 >v7
- X fi
- Xfi
- Xif $contains vmssystem libc.list >/dev/null 2>&1 ; then
- X cat <<'EOI'
- XThere is, however, a strange, musty smell in the air that reminds me of
- Xsomething...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit.
- XEOI
- X echo "exit 0" >eunice
- X eunicefix=unixtovms
- X d_eunice="$define"
- X: it so happens the Eunice I know will not run shell scripts in Unix format
- Xelse
- X echo " "
- X echo "Congratulations. You aren't running Eunice."
- X eunicefix=':'
- X d_eunice="$undef"
- X echo "exit 1" >eunice
- Xfi
- Xchmod 755 bsd usg v7 eunice
- X$eunicefix bsd usg v7 eunice
- X
- X: see if sh knows # comments
- Xecho " "
- Xecho "Checking your sh to see if it knows about # comments..."
- Xif sh -c '#' >/dev/null 2>&1 ; then
- X echo "Your sh handles # comments correctly."
- X shsharp=true
- X spitshell=cat
- X echo " "
- X echo "Okay, let's see if #! works on this system..."
- X echo "#!/bin/echo hi" > try
- X $eunicefix try
- X chmod 755 try
- X try > today
- X if test -s today; then
- X echo "It does."
- X sharpbang='#!'
- X else
- X echo "#! /bin/echo hi" > try
- X $eunicefix try
- X chmod 755 try
- X try > today
- X if test -s today; then
- X echo "It does."
- X sharpbang='#! '
- X else
- X echo "It doesn't."
- X sharpbang=': use '
- X fi
- X fi
- Xelse
- X echo "Your sh doesn't grok # comments--I will strip them later on."
- X shsharp=false
- X echo "exec grep -v '^#'" >spitshell
- X chmod 755 spitshell
- X $eunicefix spitshell
- X spitshell=`pwd`/spitshell
- X echo "I presume that if # doesn't work, #! won't work either!"
- X sharpbang=': use '
- Xfi
- X
- X: figure out how to guarantee sh startup
- Xecho " "
- Xecho "Checking out how to guarantee sh startup..."
- Xstartsh=$sharpbang'/bin/sh'
- Xecho "Let's see if '$startsh' works..."
- Xcat >try <<EOSS
- X$startsh
- Xset abc
- Xtest "$?abc" != 1
- XEOSS
- X
- Xchmod 755 try
- X$eunicefix try
- Xif try; then
- X echo "Yup, it does."
- Xelse
- X echo "Nope. You may have to fix up the shell scripts to make sure sh runs them."
- Xfi
- Xrm -f try today
- X
- X: find out where common programs are
- Xecho " "
- Xecho "Locating common programs..."
- Xpth="/usr/ucb /bin /usr/bin /usr/local /usr/local/bin /usr/lbin /etc /usr/lib"
- Xcat <<EOSC >loc
- X$startsh
- Xthing=\$1
- Xshift
- Xdflt=\$1
- Xshift
- Xfor dir in \$*; do
- X case "\$thing" in
- X .)
- X if test -d \$dir/\$thing; then
- X echo \$dir
- X exit 0
- X fi
- X ;;
- X *)
- X if test -f \$dir/\$thing; then
- X echo \$dir/\$thing
- X exit 0
- X fi
- X ;;
- X esac
- Xdone
- Xecho \$dflt
- Xexit 1
- XEOSC
- Xchmod 755 loc
- X$eunicefix loc
- Xloclist="
- Xexpr
- Xsed
- Xecho
- Xcat
- Xrm
- Xgrep
- X"
- Xtrylist="
- Xtest
- XMcc
- X"
- Xfor file in $loclist; do
- X xxx=`loc $file $file $pth`
- X eval $file=$xxx
- X case "$xxx" in
- X /*)
- X echo $file is in $xxx.
- X ;;
- X *)
- X echo "I don't know where $file is. I hope it's in everyone's PATH."
- X ;;
- X esac
- Xdone
- Xecho " "
- Xecho "Don't worry if any of the following aren't found..."
- Xans=offhand
- Xfor file in $trylist; do
- X xxx=`loc $file $file $pth`
- X eval $file=$xxx
- X case "$xxx" in
- X /*)
- X echo $file is in $xxx.
- X ;;
- X *)
- X echo "I don't see $file out there, $ans."
- X ans=either
- X ;;
- X esac
- Xdone
- Xcase "$egrep" in
- Xegrep)
- X echo "Substituting grep for egrep."
- X egrep=$grep
- X ;;
- Xesac
- Xcase "$test" in
- Xtest)
- X echo "Hopefully test is built into your sh."
- X ;;
- X/bin/test)
- X echo " "
- X echo $n 'Is your "test" built into sh? [n] (OK to guess) '"$c"
- X rp='test built into sh? [n]'
- X . myread
- X case "$ans" in
- X y*) test=test ;;
- X esac
- X ;;
- X*)
- X test=test
- X ;;
- Xesac
- Xcase "$echo" in
- Xecho)
- X echo "Hopefully echo is built into your sh."
- X ;;
- X/bin/echo)
- X echo " "
- X echo "Checking compatibility between /bin/echo and builtin echo (if any)..."
- X $echo $n "hi there$c" >foo1
- X echo $n "hi there$c" >foo2
- X if cmp foo1 foo2 >/dev/null 2>&1; then
- X echo "They are compatible. In fact, they may be identical."
- X else
- X echo "They are not compatible--the echo builtin will be used."
- X echo=echo
- X fi
- X $rm -f foo1 foo2
- X ;;
- X*)
- X echo=echo
- X ;;
- Xesac
- X
- X: index or strcpy
- X$echo " "
- Xif $contains index libc.list >/dev/null 2>&1 ; then
- X $echo "Your system appears to use index() and rindex() rather than strchr()"
- X $echo $n "and strrchr(). Is this correct? [y] $c"
- X rp='index() rather than strchr()? [y]'
- X . myread
- X case "$ans" in
- X n*|f*) d_index="$define" ;;
- X *) d_index="$undef" ;;
- X esac
- Xelse
- X $echo "Your system appears to use strchr() and strrchr() rather than index()"
- X $echo $n "and rindex(). Is this correct? [y] $c"
- X rp='strchr() rather than index()? [y]'
- X . myread
- X case "$ans" in
- X n*|f*) d_index="$undef" ;;
- X *) d_index="$define" ;;
- X esac
- Xfi
- X
- X: check for void type
- X$echo " "
- X$echo "Checking to see if your C compiler groks the void type..."
- X$cat >try.c <<'EOCP'
- Xvoid main();
- XEOCP
- Xif cc -c try.c >/dev/null 2>&1 ; then
- X d_void="$undef"
- X $echo "Yup, it does."
- Xelse
- X d_void="$define"
- X $echo "Nope, it doesn't (boo hiss). I will substitute int."
- Xfi
- X$rm -f try.*
- X
- X: see how we invoke the C preprocessor
- Xecho " "
- Xecho "Checking to see how your C preprocessor is invoked..."
- Xcat <<'EOT' >testcpp.c
- X#define ABC abc
- X#define XYZ xyz
- XABC.XYZ
- XEOT
- Xecho 'Maybe "cc -E" will work...'
- Xcc -E testcpp.c >testcpp.out 2>&1
- Xif $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
- X echo "Yup, it does."
- X cpp='cc -E'
- Xelse
- X echo 'Nope...maybe "cc -P" will work...'
- X cc -P testcpp.c >testcpp.out 2>&1
- X if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
- X echo "Yup, that does."
- X cpp='cc -P'
- X else
- X echo 'Nixed again...maybe "/lib/cpp" will work...'
- X /lib/cpp testcpp.c >testcpp.out 2>&1
- X if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
- X echo "Hooray, it works! I was beginning to wonder."
- X cpp='/lib/cpp'
- X else
- X echo 'Hmm...maybe you already told me...'
- X case "$cpp" in
- X '') ;;
- X *) $cpp testcpp.c >testcpp.out 2>&1;;
- X esac
- X if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
- X echo "Hooray, you did! I was beginning to wonder."
- X else
- X echo $n "Nope. I can't find a C preprocessor. Name one: $c"
- X rp='Name a C preprocessor:'
- X . myread
- X cpp="$ans"
- X $cpp testcpp.c >testcpp.out 2>&1
- X if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
- X echo "OK, that will do."
- X else
- X echo "Sorry, I can't get that to work. Go find one."
- X exit 1
- X fi
- X fi
- X fi
- X fi
- Xfi
- Xrm -f testcpp.c testcpp.out
- X
- X: get C preprocessor symbols handy
- Xecho " "
- Xcat <<'EOT' >Cppsym.c
- Xchar *sym[] = {
- X#ifdef mc68000
- X "mc68000",
- X#endif
- X#ifdef sun
- X "sun",
- X#endif
- X#ifdef gcos
- X "gcos",
- X#endif
- X#ifdef unix
- X "unix",
- X#endif
- X#ifdef ibm
- X "ibm",
- X#endif
- X#ifdef gimpel
- X "gimpel",
- X#endif
- X#ifdef interdata
- X "interdata",
- X#endif
- X#ifdef tss
- X "tss",
- X#endif
- X#ifdef os
- X "os",
- X#endif
- X#ifdef mert
- X "mert",
- X#endif
- X#ifdef pyr
- X "pyr",
- X#endif
- X#ifdef vax
- X "vax",
- X#endif
- X#ifdef pdp11
- X "pdp11",
- X#endif
- X#ifdef i8086
- X "i8086",
- X#endif
- X#ifdef z8000
- X "z8000",
- X#endif
- X#ifdef 3b2
- X "3b2",
- X#endif
- X#ifdef 3b5
- X "3b5",
- X#endif
- X#ifdef 3b20
- X "3b20",
- X#endif
- X#ifdef 3b200
- X "3b200",
- X#endif
- X0};
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X int i;
- X
- X for (argc--,argv++; argc; argc--,argv++) {
- X for (i=0; sym[i]; i++) {
- X if (strcmp(argv[0],sym[i]) == 0)
- X exit(0);
- X }
- X }
- X exit(1);
- X}
- XEOT
- Xecho "Your machine appears to have the following attributes:"
- X$cpp Cppsym.c | sed -n -e 's/^ "\(.*\)",$/\1/p'
- Xcc Cppsym.c -o Cppsym
- Xrm -f Cppsym.c
- X
- X: see how many register declarations we want to use
- Xcase "$registers" in
- X'')
- X if Cppsym pdp11 i8086 z8000; then
- X dflt=3
- X else
- X if Cppsym sun mc68000; then
- X dflt=10
- X else
- X : if you have any other numbers for me, send them in
- X dflt=6
- X fi
- X fi
- X ;;
- X*) dflt=$registers ;;
- Xesac
- Xcat <<EOM
- X
- XDifferent C compilers on different machines pay attention to different
- Xnumbers of register declarations. About how many register declarations in
- XEOM
- X$echo $n "each routine does your C compiler pay attention to? (OK to guess) [$dflt] $c"
- Xrp="# register declarations used? [$dflt]"
- X. myread
- Xcase "$ans" in
- X'') ans=$dflt;;
- Xesac
- Xregisters=$ans
- Xreg1=''
- Xawk "END { for (i=1; i<=16; i++) printf \"reg%d=''\n\", i}" </dev/null >.foo
- X. .foo
- Xawk "END { for (i=1; i<=$registers; i++) printf \"reg%d=register\n\", i}" \
- X </dev/null >.foo
- X. .foo
- Xrm -f .foo
- X
- X: preserve RCS keywords in files with variable substitution, grrr
- XLog='$Log'
- XHeader='$Header'
- X
- X: set up shell script to do ~ expansion
- Xcat >filexp <<EOSS
- X$startsh
- X: expand filename
- Xcase "\$1" in
- X~/*|~)
- X $echo \$1 | $sed "s|~|\${HOME-\$LOGDIR}|"
- X ;;
- X~*)
- X if $test -f /bin/csh; then
- X /bin/csh -f -c "glob \$1"
- X $echo ""
- X else
- X name=\`$expr x\$1 : '..\([^/]*\)'\`
- X dir=\`$sed </etc/passwd -n -e "/^\${name}:/{s/^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\).*"'\$'"/\1/" -e p -e q -e '}'\`
- X if $test ! -d "\$dir"; then
- X me=\`basename \$0\`
- X $echo "\$me: can't locate home directory for: \$name" >&2
- X exit 1
- X fi
- X case "\$1" in
- X */*)
- X $echo \$dir/\`$expr x\$1 : '..[^/]*/\(.*\)'\`
- X ;;
- X *)
- X $echo \$dir
- X ;;
- X esac
- X fi
- X ;;
- X*)
- X $echo \$1
- X ;;
- Xesac
- XEOSS
- Xchmod 755 filexp
- X$eunicefix filexp
- X
- X: determine where public executables go
- Xcase "$bin" in
- X'')
- X dflt=`loc . /bin /usr/local/bin /usr/lbin /usr/local /usr/bin`
- X ;;
- X*) dflt="$bin"
- X ;;
- Xesac
- Xbin='blurfl/dyick'
- Xwhile $test ! -d "$bin" ; do
- X case "$bin" in
- X blurfl*) ;;
- X *) $echo "$bin does not appear to exist." ;;
- X esac
- X $echo " "
- X rp="Where do you want to put the public executables? [$dflt]"
- X $echo $n "$rp $c"
- X . myread
- X bin="$ans"
- X bin=`filexp $bin`
- X case "$bin" in
- X '') bin=$dflt ;;
- X esac
- Xdone
- X
- X: determine where manual pages go
- Xcase "$mansrc" in
- X'')
- X dflt=`loc . /usr/man/man1 /usr/man/mann /usr/man/local/man1 /usr/man/u_man/man1 /usr/man/man1`
- X ;;
- X*) dflt="$mansrc"
- X ;;
- Xesac
- Xmansrc='blurfl/dyick'
- Xwhile $test ! -d "$mansrc" ; do
- X case "$mansrc" in
- X blurfl*) ;;
- X *) $echo "$mansrc does not appear to exist." ;;
- X esac
- X $echo " "
- X rp="Where do the manual pages (source) go? [$dflt]"
- X $echo $n "$rp $c"
- X . myread
- X mansrc=`filexp "$ans"`
- X case "$mansrc" in
- X '') mansrc=$dflt ;;
- X esac
- Xdone
- Xcase "$mansrc" in
- X*l)
- X manext=l
- X ;;
- X*n)
- X manext=n
- X ;;
- X*)
- X manext=1
- X ;;
- Xesac
- X
- X: see if we need a special compiler
- X$echo " "
- Xif usg; then
- X case "$cc" in
- X '')
- X case "$Mcc" in
- X /*) dflt='Mcc'
- X ;;
- X *)
- X if $contains '\-M' $mansrc/cc.1 >/dev/null 2>&1 ; then
- X dflt='cc -M'
- X else
- X dflt='cc'
- X fi
- X ;;
- X esac
- X ;;
- X *) dflt="$cc";;
- X esac
- X $cat <<'EOM'
- X
- XOn some systems the default C compiler will not resolve multiple global
- Xreferences that happen to have the same name. On some such systems the
- X"Mcc" command may be used to force these to be resolved. On other systems
- Xa "cc -M" command is required. What command will force resolution on
- XEOM
- X $echo $n "this system? [$dflt] $c"
- X rp="Command to resolve multiple refs? [$dflt]"
- X . myread
- X cc="$ans"
- X case "$cc" in
- X '') cc="$dflt" ;;
- X esac
- Xelse
- X $echo "Not a USG system--assuming cc can resolve multiple definitions."
- X cc=cc
- Xfi
- X
- X: see if we should throw a -i into the Makefile
- X$echo " "
- Xif Cppsym pdp11 i8086 z8000; then
- X if $contains '\-i' $mansrc/cc.1 >/dev/null 2>&1 ; then
- X rp="Your system appears to have separate I and D space. Is this true? [y]"
- X $echo $n "$rp $c"
- X . myread
- X case "$ans" in
- X n*|f*) iandd='' ;;
- X *) iandd='-i' ;;
- X esac
- X else
- X $echo "Your system appears to NOT have separate I and D space."
- X $echo $n "Is this correct? [y] $c"
- X rp='No separate I and D. Correct? [y]'
- X . myread
- X case "$ans" in
- X n*|f*) iandd='-i' ;;
- X *) iandd='' ;;
- X esac
- X fi
- Xelse
- X $echo $n "Does your machine have separate I and D space? [n] $c"
- X . myread
- X case "$ans" in
- X y*) iandd='-i' ;;
- X *) iandd='' ;;
- X esac
- Xfi
- X
- X$echo " "
- X$echo "End of configuration questions."
- X$echo " "
- X
- X: create config.sh file
- X$echo " "
- X$echo "Creating config.sh..."
- X$spitshell <<EOT >config.sh
- X$startsh
- X# config.sh
- X# This file was produced by running the Configure script.
- X
- Xd_eunice='$d_eunice'
- Xeunicefix='$eunicefix'
- Xloclist='$loclist'
- Xexpr='$expr'
- Xsed='$sed'
- Xecho='$echo'
- Xcat='$cat'
- Xrm='$rm'
- Xmv='$mv'
- Xcp='$cp'
- Xtail='$tail'
- Xtr='$tr'
- Xmkdir='$mkdir'
- Xsort='$sort'
- Xuniq='$uniq'
- Xgrep='$grep'
- Xtrylist='$trylist'
- Xtest='$test'
- Xinews='$inews'
- Xegrep='$egrep'
- Xmore='$more'
- Xpg='$pg'
- XMcc='$Mcc'
- Xvi='$vi'
- Xmailx='$mailx'
- XLog='$Log'
- XHeader='$Header'
- Xbin='$bin'
- Xcc='$cc'
- Xcontains='$contains'
- Xcpp='$cpp'
- Xd_index='$d_index'
- Xd_void='$d_void'
- Xiandd='$iandd'
- Xlibc='$libc'
- Xmansrc='$mansrc'
- Xmanext='$manext'
- Xn='$n'
- Xc='$c'
- Xpackage='$package'
- Xregisters='$registers'
- Xreg1='$reg1'
- Xreg2='$reg2'
- Xreg3='$reg3'
- Xreg4='$reg4'
- Xreg5='$reg5'
- Xreg6='$reg6'
- Xreg7='$reg7'
- Xreg8='$reg8'
- Xreg9='$reg9'
- Xreg10='$reg10'
- Xreg11='$reg11'
- Xreg12='$reg12'
- Xreg13='$reg13'
- Xreg14='$reg14'
- Xreg15='$reg15'
- Xreg16='$reg16'
- Xspitshell='$spitshell'
- Xshsharp='$shsharp'
- Xsharpbang='$sharpbang'
- Xstartsh='$startsh'
- XCONFIG=true
- XEOT
- X
- X: create config.h file
- X$echo " "
- X$echo "Creating config.h..."
- X$cat <<EOT >config.h
- X/* config.h
- X * This file was produced by running the Configure script.
- X * Feel free to modify any of this as the need arises.
- X */
- X
- X
- X#$d_eunice EUNICE /* no file linking? */
- X#$d_eunice VMS /* other assorted ickies? */
- X
- X#$d_index index strchr /* cultural */
- X#$d_index rindex strrchr /* differences? */
- X
- X#$d_void void int /* is void to be avoided? */
- X
- X/* How many register declarations are paid attention to? */
- X
- X#define Reg1 $reg1 /**/
- X#define Reg2 $reg2 /**/
- X#define Reg3 $reg3 /**/
- X#define Reg4 $reg4 /**/
- X#define Reg5 $reg5 /**/
- X#define Reg6 $reg6 /**/
- X#define Reg7 $reg7 /**/
- X#define Reg8 $reg8 /**/
- X#define Reg9 $reg9 /**/
- X#define Reg10 $reg10 /**/
- X#define Reg11 $reg11 /**/
- X#define Reg12 $reg12 /**/
- X#define Reg13 $reg13 /**/
- X#define Reg14 $reg14 /**/
- X#define Reg15 $reg15 /**/
- X#define Reg16 $reg16 /**/
- X
- XEOT
- XCONFIG=true
- X
- Xif $contains '\.SH' MANIFEST >/dev/null 2>&1; then
- X $echo " "
- X $echo "Doing variable substitutions on .SH files..."
- X set `$grep <MANIFEST '\.SH' | awk '{print $1}'`
- X for file in $*; do
- X case "$file" in
- X */*)
- X dir=`$expr X$file : 'X\(.*\)/'`
- X file=`$expr X$file : 'X.*/\(.*\)'`
- X (cd $dir && . $file)
- X ;;
- X *)
- X . $file
- X ;;
- X esac
- X done
- Xfi
- X
- Xif $contains '^depend:' Makefile >/dev/null 2>&1; then
- X $echo " "
- X $echo 'Now you need to generate make dependencies by running "make depend".'
- X $echo 'You might prefer to run it in background: "make depend > makedepend.out &"'
- X $echo $n "Would you like me to run it for you (it takes quite a while)? [n] $c"
- X rp="Run make depend now? [n]"
- X . myread
- X case "$ans" in
- X y*) make depend;;
- X esac
- Xfi
- X
- X$rm -f libc.list kit*isdone bsd usg v7 eunice loc Cppsym
- X
- Xif test -f Makefile; then
- X $echo " "
- X $echo "Now you must run a make."
- Xelse
- X $echo "Done."
- Xfi
- X: end of Configure
- !STUFFY!FUNK!
- echo Extracting util.h
- sed >util.h <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: util.h,v 2.0 86/09/17 15:40:06 lwall Exp $
- X *
- X * $Log: util.h,v $
- X * Revision 2.0 86/09/17 15:40:06 lwall
- X * Baseline for netwide release.
- X *
- X */
- X
- X/* and for those machine that can't handle a variable argument list */
- X
- X#ifdef CANVARARG
- X
- X#define say1 say
- X#define say2 say
- X#define say3 say
- X#define say4 say
- X#define ask1 ask
- X#define ask2 ask
- X#define ask3 ask
- X#define ask4 ask
- X#define fatal1 fatal
- X#define fatal2 fatal
- X#define fatal3 fatal
- X#define fatal4 fatal
- X
- X#else /* hope they allow multi-line macro actual arguments */
- X
- X#ifdef lint
- X
- X#define say1(a) say(a, 0, 0, 0)
- X#define say2(a,b) say(a, (b)==(b), 0, 0)
- X#define say3(a,b,c) say(a, (b)==(b), (c)==(c), 0)
- X#define say4(a,b,c,d) say(a, (b)==(b), (c)==(c), (d)==(d))
- X#define ask1(a) ask(a, 0, 0, 0)
- X#define ask2(a,b) ask(a, (b)==(b), 0, 0)
- X#define ask3(a,b,c) ask(a, (b)==(b), (c)==(c), 0)
- X#define ask4(a,b,c,d) ask(a, (b)==(b), (c)==(c), (d)==(d))
- X#define fatal1(a) fatal(a, 0, 0, 0)
- X#define fatal2(a,b) fatal(a, (b)==(b), 0, 0)
- X#define fatal3(a,b,c) fatal(a, (b)==(b), (c)==(c), 0)
- X#define fatal4(a,b,c,d) fatal(a, (b)==(b), (c)==(c), (d)==(d))
- X
- X#else /* lint */
- X /* if this doesn't work, try defining CANVARARG above */
- X#define say1(a) say(a, Nullch, Nullch, Nullch)
- X#define say2(a,b) say(a, b, Nullch, Nullch)
- X#define say3(a,b,c) say(a, b, c, Nullch)
- X#define say4 say
- X#define ask1(a) ask(a, Nullch, Nullch, Nullch)
- X#define ask2(a,b) ask(a, b, Nullch, Nullch)
- X#define ask3(a,b,c) ask(a, b, c, Nullch)
- X#define ask4 ask
- X#define fatal1(a) fatal(a, Nullch, Nullch, Nullch)
- X#define fatal2(a,b) fatal(a, b, Nullch, Nullch)
- X#define fatal3(a,b,c) fatal(a, b, c, Nullch)
- X#define fatal4 fatal
- X
- X#endif /* lint */
- X
- X/* if neither of the above work, join all multi-line macro calls. */
- X#endif
- X
- XEXT char serrbuf[BUFSIZ]; /* buffer for stderr */
- X
- Xchar *fetchname();
- Xint move_file();
- Xvoid copy_file();
- Xvoid say();
- Xvoid fatal();
- Xvoid ask();
- Xchar *savestr();
- Xvoid set_signals();
- Xvoid ignore_signals();
- Xvoid makedirs();
- !STUFFY!FUNK!
- echo Extracting EXTERN.h
- sed >EXTERN.h <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: EXTERN.h,v 2.0 86/09/17 15:35:37 lwall Exp $
- X *
- X * $Log: EXTERN.h,v $
- X * Revision 2.0 86/09/17 15:35:37 lwall
- X * Baseline for netwide release.
- X *
- X */
- X
- X#undef EXT
- X#define EXT extern
- X
- X#undef INIT
- X#define INIT(x)
- X
- X#undef DOINIT
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 1 (of 3)"
- cat /dev/null >kit1isdone
- config=true
- for iskit in 1 2 3; do
- if test -f kit${iskit}isdone; then
- echo "You have run kit ${iskit}."
- else
- echo "You still need to run kit ${iskit}."
- config=false
- fi
- done
- case $config in
- true)
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- esac
- : I do not append .signature, but someone might mail this.
- exit
-