+-+-+-+ Beginning of part 8 +-+-+-+
X    Reg4 long this_line = 0;
X    Reg5 long previous_line;
X    Reg6 long first_command_line = -1;
X    long fcl_line;
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    p_input_line = p_bline - 1;
X    for (;;) `123
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        p_input_line++;
X        if (fgets(buf, sizeof buf, pfp) == Nullch) `123
X            if (first_command_line >= 0L) `123
X                                        /* nothing but deletes!? */
X                p_start = first_command_line;
X                p_sline = fcl_line;
X                retval = ED_DIFF;
X                goto scan_exit;
X            `125
X            else `123
X                p_start = this_line;
X                p_sline = p_input_line;
X                retval = 0;
X                goto scan_exit;
X            `125
X        `125
V        for (s = buf; *s == ' ' `124`124 *s == '\t' `124`124 *s == 'X'; s++)
X `123
X            if (*s == '\t')
X                indent += 8 - (indent % 8);
X            else
X                indent++;
X        `125
X        for (t=s; isdigit(*t) `124`124 *t == ','; t++) ;
X        this_is_a_command = (isdigit(*s) &&
X          (*t == 'd' `124`124 *t == 'c' `124`124 *t == 'a') );
X        if (first_command_line < 0L && this_is_a_command) `123
X            first_command_line = this_line;
X            fcl_line = p_input_line;
X            p_indent = indent;          /* assume this for now */
X        `125
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)) `123
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) `123
X                free(revision);
X                revision = Nullch;
X            `125
X        `125
X        if ((!diff_type `124`124 diff_type == ED_DIFF) &&
X          first_command_line >= 0L &&
X          strEQ(s, ".\n") ) `123
X            p_indent = indent;
X            p_start = first_command_line;
X            p_sline = fcl_line;
X            retval = ED_DIFF;
X            goto scan_exit;
X        `125
X        stars_this_line = strnEQ(s, "********", 8);
V        if ((!diff_type `124`124 diff_type == CONTEXT_DIFF) && stars_last_lin
Xe &&
X                 strnEQ(s, "*** ", 4)) `123
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            p_sline = p_input_line - 1;
X            retval = (*(s-1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF);
X            goto scan_exit;
X        `125
X        if ((!diff_type `124`124 diff_type == NORMAL_DIFF) &&
X          last_line_was_command &&
X          (strnEQ(s, "< ", 2) `124`124 strnEQ(s, "> ", 2)) ) `123
X            p_start = previous_line;
X            p_sline = p_input_line - 1;
X            p_indent = indent;
X            retval = NORMAL_DIFF;
X            goto scan_exit;
X        `125
X    `125
X  scan_exit:
X    if (no_filearg) `123
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) `123
X            if (strlen(oldname) < strlen(newname))
X                filearg[0] = savestr(oldname);
X            else
X                filearg[0] = savestr(newname);
X        `125
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    `125
X    if (bestguess) `123
X        free(bestguess);
X        bestguess = Nullch;
X    `125
X    if (filearg[0] != Nullch)
X        bestguess = savestr(filearg[0]);
X    else if (indtmp != Nullch)
X        bestguess = fetchname(indtmp, strippath, TRUE);
X    else `123
X        if (oldtmp != Nullch)
X            oldname = fetchname(oldtmp, strippath, TRUE);
X        if (newtmp != Nullch)
X            newname = fetchname(newtmp, strippath, TRUE);
X        if (oldname && newname) `123
X            if (strlen(oldname) < strlen(newname))
X                bestguess = savestr(oldname);
X            else
X                bestguess = savestr(newname);
X        `125
X        else if (oldname)
X            bestguess = savestr(oldname);
X        else if (newname)
X            bestguess = savestr(newname);
X    `125
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`125
X
X/* Remember where this patch ends so we know where to start up again. */
X
Xvoid
Xnext_intuit_at(file_pos,file_line)
Xlong file_pos;
Xlong file_line;
X`123
X    p_base = file_pos;
X    p_bline = file_line;
X`125
X
X/* Basically a verbose fseek() to the actual diff listing. */
X
Xvoid
Xskip_to(file_pos,file_line)
Xlong file_pos;
Xlong file_line;
X`123
X    char *ret;
X
X    assert(p_base <= file_pos);
X    if (verbose && p_base < file_pos) `123
X        Fseek(pfp, p_base, 0);
V        say1("The text leading up to this was:\n--------------------------\n"
X);
X        while (ftell(pfp) < file_pos) `123
X            ret = fgets(buf, sizeof buf, pfp);
X            assert(ret != Nullch);
X            say2("`124%s", buf);
X        `125
X        say1("--------------------------\n");
X    `125
X    else
X        Fseek(pfp, file_pos, 0);
X    p_input_line = file_line - 1;
X`125
X
X/* True if there is more of the current diff listing to process. */
X
Xbool
Xanother_hunk()
X`123
X    Reg1 char *s;
X    Reg8 char *ret;
X    Reg2 int context = 0;
X
X    while (p_end >= 0) `123
X        if (p_end == p_efake)
X            p_end = p_bfake;            /* don't free twice */
X        else
X            free(p_line[p_end]);
X        p_end--;
X    `125
X    assert(p_end == -1);
X    p_efake = -1;
X
X    p_max = hunkmax;                    /* gets reduced when --- found */
V    if (diff_type == CONTEXT_DIFF `124`124 diff_type == NEW_CONTEXT_DIFF) `12
X3
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        LINENUM repl_patch_line;        /* input line number for same */
X        Reg7 LINENUM ptrn_copiable = 0;
X                                        /* # of copiable lines in ptrn */
X
X        ret = pgets(buf, sizeof buf, pfp);
X        p_input_line++;
X        if (ret == Nullch `124`124 strnNE(buf, "********", 8)) `123
X            next_intuit_at(line_beginning,p_input_line);
X            return FALSE;
X        `125
X        p_context = 100;
X        p_hunk_beg = p_input_line + 1;
X        while (p_end < p_max) `123
X            line_beginning = ftell(pfp);
X            ret = pgets(buf, sizeof buf, pfp);
X            p_input_line++;
X            if (ret == Nullch) `123
X                if (p_max - p_end < 4)
V                    Strcpy(buf, "  \n");  /* assume blank lines got chopped *
X/
X                else `123
X                    if (repl_beginning && repl_could_be_missing) `123
X                        repl_missing = TRUE;
X                        goto hunk_done;
X                    `125
X                    fatal1("Unexpected end of file in patch.\n");
X                `125
X            `125
X            p_end++;
X            assert(p_end < hunkmax);
X            p_char[p_end] = *buf;
X#ifdef zilog
X            p_line[(short)p_end] = Nullch;
X#else
X            p_line[p_end] = Nullch;
X#endif
X            switch (*buf) `123
X            case '*':
X                if (strnEQ(buf, "********", 8)) `123
X                    if (repl_beginning && repl_could_be_missing) `123
X                        repl_missing = TRUE;
X                        goto hunk_done;
X                    `125
X                    else
X                        fatal2("Unexpected end of hunk at line %ld.\n",
X                            p_input_line);
X                `125
X                if (p_end != 0) `123
X                    if (repl_beginning && repl_could_be_missing) `123
X                        repl_missing = TRUE;
X                        goto hunk_done;
X                    `125
V                    fatal3("Unexpected *** at line %ld: %s", p_input_line, bu
Xf);
X                `125
X                context = 0;
X                p_line[p_end] = savestr(buf);
X                if (out_of_mem) `123
X                    p_end--;
X                    return FALSE;
X                `125
X                for (s=buf; *s && !isdigit(*s); s++) ;
X                if (!*s)
X                    goto malformed;
X                if (strnEQ(s,"0,0",3))
X                    strcpy(s,s+2);
X                p_first = (LINENUM) atol(s);
X                while (isdigit(*s)) s++;
X                if (*s == ',') `123
X                    for (; *s && !isdigit(*s); s++) ;
X                    if (!*s)
X                        goto malformed;
X                    p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1;
X                `125
X                else if (p_first)
X                    p_ptrn_lines = 1;
X                else `123
X                    p_ptrn_lines = 0;
X                    p_first = 1;
X                `125
V                p_max = p_ptrn_lines + 6;       /* we need this much at least
X */
X                while (p_max >= hunkmax)
X                    grow_hunkmax();
X                p_max = hunkmax;
X                break;
X            case '-':
X                if (buf[1] == '-') `123
X                    if (repl_beginning `124`124
V                        (p_end != p_ptrn_lines + 1 + (p_char[p_end-1] == '\n'
X)))
X                    `123
X                        if (p_end == 1) `123
V                            /* `096old' lines were omitted - set up to fill *
X/
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                        `125
X                        else `123
X                            if (repl_beginning) `123
X                                if (repl_could_be_missing)`123
X                                    repl_missing = TRUE;
X                                    goto hunk_done;
X                                `125
X                                fatal3(
X"Duplicate \"---\" at line %ld--check line numbers at line %ld.\n",
V                                    p_input_line, p_hunk_beg + repl_beginning
X);
X                            `125
X                            else `123
X                                fatal4(
X"%s \"---\" at line %ld--check line numbers at line %ld.\n",
X                                    (p_end <= p_ptrn_lines
X                                        ? "Premature"
X                                        : "Overdue" ),
X                                    p_input_line, p_hunk_beg);
X                            `125
X                        `125
X                    `125
X                    repl_beginning = p_end;
X                    repl_backtrack_position = ftell(pfp);
X                    repl_patch_line = p_input_line;
X                    p_line[p_end] = savestr(buf);
X                    if (out_of_mem) `123
X                        p_end--;
X                        return FALSE;
X                    `125
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 == ',') `123
X                        for (; *s && !isdigit(*s); s++) ;
X                        if (!*s)
X                            goto malformed;
X                        p_repl_lines = ((LINENUM)atol(s)) - p_newfirst + 1;
X                    `125
X                    else if (p_newfirst)
X                        p_repl_lines = 1;
X                    else `123
X                        p_repl_lines = 0;
X                        p_newfirst = 1;
X                    `125
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                `125
X                goto change_line;
X            case '+':  case '!':
X                repl_could_be_missing = FALSE;
X              change_line:
X                if (buf[1] == '\n' && canonicalize)
X                    strcpy(buf+1," \n");
X                if (!isspace(buf[1]) && buf[1] != '>' && buf[1] != '<' &&
X                  repl_beginning && repl_could_be_missing) `123
X                    repl_missing = TRUE;
-+-+-+-+-+ End of part 8 +-+-+-+-+-
