Example #1
0
/*
 * Apply an ed script by feeding ed itself.
 */
void
do_ed_script(void)
{
	char	*t;
	long	beginning_of_this_line;
	FILE	*pipefp = NULL;

	if (!skip_rest_of_patch) {
		if (copy_file(filearg[0], TMPOUTNAME) < 0) {
			unlink(TMPOUTNAME);
			fatal("can't create temp file %s", TMPOUTNAME);
		}
		snprintf(buf, buf_size, "%s%s%s", _PATH_ED,
		    verbose ? " " : " -s ", TMPOUTNAME);
		pipefp = popen(buf, "w");
	}
	for (;;) {
		beginning_of_this_line = ftell(pfp);
		if (pgets(true) == 0) {
			next_intuit_at(beginning_of_this_line, p_input_line);
			break;
		}
		p_input_line++;
		for (t = buf; isdigit((unsigned char)*t) || *t == ','; t++)
			;
		/* POSIX defines allowed commands as {a,c,d,i,s} */
		if (isdigit((unsigned char)*buf) && (*t == 'a' || *t == 'c' ||
		    *t == 'd' || *t == 'i' || *t == 's')) {
			if (pipefp != NULL)
				fputs(buf, pipefp);
			if (*t != 'd') {
				while (pgets(true)) {
					p_input_line++;
					if (pipefp != NULL)
						fputs(buf, pipefp);
					if (strEQ(buf, ".\n"))
						break;
				}
			}
		} else {
			next_intuit_at(beginning_of_this_line, p_input_line);
			break;
		}
	}
	if (pipefp == NULL)
		return;
	fprintf(pipefp, "w\n");
	fprintf(pipefp, "q\n");
	fflush(pipefp);
	pclose(pipefp);
	ignore_signals();
	if (!check_only) {
		if (move_file(TMPOUTNAME, outname) < 0) {
			toutkeep = true;
			chmod(TMPOUTNAME, filemode);
		} else
			chmod(outname, filemode);
	}
	set_signals(1);
}
/*................................... READF ................................*/
void  readf( FILE *Fp, double *next, ... )
{
va_list args;                                    /* Variable argument list  */
for( va_start(args,next);  next;  next=va_arg(args,double *) )
  pgets(Fp,next);
va_end(args);                          /* Help function make normal return  */
pgets(Fp,NULL);                        /* Always get a newline at the end   */
}
Example #3
0
void process_pending(struct pipe *p)
{
	struct pipes_res *res = NULL;

	switch(p->pending_cmd.command)
	{
		case PIPES_READ:
		res = pread((struct pipes_read *)&p->pending_cmd, p);
			break;
		case PIPES_SEEK:
		res = pseek((struct pipes_seek *)&p->pending_cmd, p, p->taskid2);
			break;
		case PIPES_GETS:
		res = pgets((struct pipes_gets *)&p->pending_cmd, p);
			break;
		case PIPES_GETC:
		res = pgetc((struct pipes_getc *)&p->pending_cmd, p);
			break;
	}

	if(res != NULL)
	{
		p->pending = 0;
		res->thr_id = p->pending_cmd.thr_id;
		res->command = p->pending_cmd.command;
		send_msg(p->taskid2, p->pending_cmd.ret_port, res);
	}
}
Example #4
0
/*
 * Basically a verbose fseek() to the actual diff listing.
 */
static void
skip_to(LINENUM file_pos, LINENUM file_line)
{
	size_t	len;

	if (p_base > file_pos)
		fatal("Internal error: seek %ld>%ld\n", p_base, file_pos);
	if (verbose && p_base < file_pos) {
		fseek(pfp, p_base, SEEK_SET);
		say("The text leading up to this was:\n--------------------------\n");
		while (ftell(pfp) < file_pos) {
			len = pgets(false);
			if (len == 0)
				fatal("Unexpected end of file\n");
			say("|%s", buf);
		}
		say("--------------------------\n");
	} else
		fseek(pfp, file_pos, SEEK_SET);
	p_input_line = file_line - 1;
}
Example #5
0
void process_pipes_cmd(struct pipes_cmd *pcmd, int task)
{
    struct pipes_res *res= NULL;
    struct pipe *p = NULL;

    // check for open
    if(pcmd->command == PIPES_OPENSHARED)
    {
        // create a new shared pipe
        struct pipe *p = (struct pipe*)malloc(sizeof(struct pipe));

        p->id = get_new_pipeid();
        p->type = PIPES_SHAREDPIPE;
        p->taskid = ((struct pipes_openshared*)pcmd)->task1;
        p->taskid2 = ((struct pipes_openshared*)pcmd)->task2;
        p->pf = NULL;
        p->creating_task = task;
        p->pending = 0;
        p->task1_closed = 0;
        p->task2_closed = 0;

        p->buffer = (struct pipe_buffer*)malloc(sizeof(struct pipe_buffer));
        p->buffer->rcursor = p->buffer->wcursor = p->buffer->size = 0;
        init(&p->buffer->blocks);

        avl_insert(&pipes, p, p->id);

        res = build_response_msg(PIPESERR_OK);
        ((struct pipes_open_res*)res)->pipeid = p->id;
    }
    else if(pcmd->command == PIPES_OPENFILE)
    {
        // create a new file pipe
        struct pipe *p = (struct pipe*)malloc(sizeof(struct pipe));

        char *filepath = get_string(((struct pipes_openfile*)pcmd)->path_smo);

        p->id = get_new_pipeid();
        p->type = PIPES_FILEPIPE;
        p->taskid = ((struct pipes_openshared*)pcmd)->task1;
        p->taskid2 = -1;
        p->pf = fopen(filepath, (char*)((struct pipes_openfile*)pcmd)->open_mode);
        p->creating_task = task;
        p->buffer = NULL;
        p->pending = 0;

        if(p->pf != NULL)
        {
            avl_insert(&pipes, p, p->id);
            res = build_response_msg(PIPESERR_OK);
            ((struct pipes_open_res*)res)->pipeid = p->id;
        }
        else
        {
            res = build_response_msg(PIPESERR_FSERROR);
            free(p);
        }

        free(filepath);
    }
    else
    {
        p = (struct pipe*)avl_getvalue(pipes, ((struct pipes_close*)pcmd)->pipeid);

        if(p != NULL)
        {
            /* Check permissions */
            switch(pcmd->command)
            {
            case PIPES_CLOSE:
                // a shared pipe must be closed on both ends or by the creating task
                if(p->type == PIPES_SHAREDPIPE)
                {
                    if(task != p->taskid && task != p->taskid2 && task != p->creating_task)
                    {
                        res = build_response_msg(PIPESERR_ERR);
                    }
                    else if((task == p->taskid && p->task1_closed) || (task == p->taskid2 && p->task2_closed))
                    {
                        res = build_response_msg(PIPESERR_PIPECLOSED);
                    }
                }
                else if(p->type == PIPES_FILEPIPE && task != p->taskid)
                {
                    res = build_response_msg(PIPESERR_ERR);
                }
                break;
            case PIPES_SEEK:
            case PIPES_TELL:
                break;
            case PIPES_WRITE:
            case PIPES_PUTS:
            case PIPES_PUTC:
                if(p->type == PIPES_SHAREDPIPE && task != p->taskid)
                {
                    res = build_response_msg(PIPESERR_ERR);
                }
                break;
            case PIPES_READ:
            case PIPES_GETS:
            case PIPES_GETC:
                if(p->type == PIPES_SHAREDPIPE && task != p->taskid2)
                {
                    res = build_response_msg(PIPESERR_ERR);
                }
                break;
            default:
                res = build_response_msg(PIPESERR_ERR);
            }

            if(res != NULL)
            {
                res->thr_id = pcmd->thr_id;
                res->command = pcmd->command;

                send_msg(task, pcmd->ret_port, res);
                return;
            }

            /* Process pipe command */
            switch(pcmd->command)
            {
            case PIPES_CLOSE:
                res = pclose((struct pipes_close *)pcmd, p, task);
                if(res->ret == PIPESERR_OK) p = NULL;
                break;
            case PIPES_READ:
                res = pread((struct pipes_read *)pcmd, p);
                break;
            case PIPES_WRITE:
                res = pwrite((struct pipes_write *)pcmd, p);
                break;
            case PIPES_SEEK:
                res = pseek((struct pipes_seek *)pcmd, p, task);
                break;
            case PIPES_TELL:
                res = ptell((struct pipes_tell *)pcmd, p, task);
                break;
            case PIPES_PUTS:
                res = pputs((struct pipes_puts *)pcmd, p);
                break;
            case PIPES_PUTC:
                res = pputc((struct pipes_putc *)pcmd, p);
                break;
            case PIPES_GETS:
                res = pgets((struct pipes_gets *)pcmd, p);
                break;
            case PIPES_GETC:
                res = pgetc((struct pipes_getc *)pcmd, p);
                break;
            default:
                res = build_response_msg(PIPESERR_ERR);
            }
        }
        else
        {
            res = build_response_msg(PIPESERR_PIPECLOSED);
        }
    }

    if(p == NULL || (p != NULL && !(p->pending && (pcmd->command == PIPES_READ
                                    || (pcmd->command == PIPES_SEEK && task == p->taskid2)
                                    || pcmd->command == PIPES_GETS
                                    || pcmd->command == PIPES_GETC))))
    {
        if(res == NULL)
        {
            res = build_response_msg(PIPESERR_ERR);
        }

        res->thr_id = pcmd->thr_id;
        res->command = pcmd->command;

        send_msg(task, pcmd->ret_port, res);

        if(res != NULL) free(res);
    }
    else
    {
        // check pending read
        if(p != NULL && p->pending && (pcmd->command == PIPES_WRITE
                                       || (pcmd->command == PIPES_SEEK && task == p->taskid2)
                                       || pcmd->command == PIPES_READ
                                       || pcmd->command == PIPES_PUTS
                                       || pcmd->command == PIPES_PUTC))
        {
            // process the pending message
            process_pending(p);
        }

        send_msg(task, pcmd->ret_port, res);
        if(res != NULL) free(res);
    }
}
Example #6
0
/*
 * True if there is more of the current diff listing to process.
 */
bool
another_hunk(void)
{
	long	line_beginning;			/* file pos of the current line */
	LINENUM	repl_beginning;			/* index of --- line */
	LINENUM	fillcnt;			/* #lines of missing ptrn or repl */
	LINENUM	fillsrc;			/* index of first line to copy */
	LINENUM	filldst;			/* index of first missing line */
	bool	ptrn_spaces_eaten;		/* ptrn was slightly misformed */
	bool	repl_could_be_missing;		/* no + or ! lines in this hunk */
	bool	repl_missing;			/* we are now backtracking */
	long	repl_backtrack_position;	/* file pos of first repl line */
	LINENUM	repl_patch_line;		/* input line number for same */
	LINENUM	ptrn_copiable;			/* # of copiable lines in ptrn */
	char	*s;
	size_t	len;
	int	context = 0;

	while (p_end >= 0) {
		if (p_end == p_efake)
			p_end = p_bfake;	/* don't free twice */
		else
			free(p_line[p_end]);
		p_end--;
	}
	p_efake = -1;

	p_max = hunkmax;	/* gets reduced when --- found */
	if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
		line_beginning = ftell(pfp);
		repl_beginning = 0;
		fillcnt = 0;
		fillsrc = 0;
		filldst = 0;
		ptrn_spaces_eaten = false;
		repl_could_be_missing = true;
		repl_missing = false;
		repl_backtrack_position = 0;
		repl_patch_line = 0;
		ptrn_copiable = 0;

		len = pgets(true);
		p_input_line++;
		if (len == 0 || strnNE(buf, "********", 8)) {
			next_intuit_at(line_beginning, p_input_line);
			return false;
		}
		p_context = 100;
		p_hunk_beg = p_input_line + 1;
		while (p_end < p_max) {
			line_beginning = ftell(pfp);
			len = pgets(true);
			p_input_line++;
			if (len == 0) {
				if (p_max - p_end < 4) {
					/* assume blank lines got chopped */
					strlcpy(buf, "  \n", buf_size);
				} else {
					if (repl_beginning && repl_could_be_missing) {
						repl_missing = true;
						goto hunk_done;
					}
					fatal("unexpected end of file in patch\n");
				}
			}
			p_end++;
			if (p_end >= hunkmax)
				fatal("Internal error: hunk larger than hunk "
				    "buffer size");
			p_char[p_end] = *buf;
			p_line[p_end] = NULL;
			switch (*buf) {
			case '*':
				if (strnEQ(buf, "********", 8)) {
					if (repl_beginning && repl_could_be_missing) {
						repl_missing = true;
						goto hunk_done;
					} else
						fatal("unexpected end of hunk "
						    "at line %ld\n",
						    p_input_line);
				}
				if (p_end != 0) {
					if (repl_beginning && repl_could_be_missing) {
						repl_missing = true;
						goto hunk_done;
					}
					fatal("unexpected *** at line %ld: %s",
					    p_input_line, buf);
				}
				context = 0;
				p_line[p_end] = savestr(buf);
				if (out_of_mem) {
					p_end--;
					return false;
				}
				for (s = buf; *s && !isdigit((unsigned char)*s); s++)
					;
				if (!*s)
					malformed();
				if (strnEQ(s, "0,0", 3))
					memmove(s, s + 2, strlen(s + 2) + 1);
				p_first = (LINENUM) atol(s);
				while (isdigit((unsigned char)*s))
					s++;
				if (*s == ',') {
					for (; *s && !isdigit((unsigned char)*s); s++)
						;
					if (!*s)
						malformed();
					p_ptrn_lines = ((LINENUM) atol(s)) - p_first + 1;
				} else if (p_first)
					p_ptrn_lines = 1;
				else {
					p_ptrn_lines = 0;
					p_first = 1;
				}

				/* we need this much at least */
				p_max = p_ptrn_lines + 6;
				while (p_max >= hunkmax)
					grow_hunkmax();
				p_max = hunkmax;
				break;
			case '-':
				if (buf[1] == '-') {
					if (repl_beginning ||
					    (p_end != p_ptrn_lines + 1 +
					    (p_char[p_end - 1] == '\n'))) {
						if (p_end == 1) {
							/*
							 * `old' lines were omitted;
							 * set up to fill them in
							 * from 'new' context lines.
							 */
							p_end = p_ptrn_lines + 1;
							fillsrc = p_end + 1;
							filldst = 1;
							fillcnt = p_ptrn_lines;
						} else {
							if (repl_beginning) {
								if (repl_could_be_missing) {
									repl_missing = true;
									goto hunk_done;
								}
								fatal("duplicate \"---\" at line %ld--check line numbers at line %ld\n",
								    p_input_line, p_hunk_beg + repl_beginning);
							} else {
								fatal("%s \"---\" at line %ld--check line numbers at line %ld\n",
								    (p_end <= p_ptrn_lines
								    ? "Premature"
								    : "Overdue"),
								    p_input_line, p_hunk_beg);
							}
						}
					}
					repl_beginning = p_end;
					repl_backtrack_position = ftell(pfp);
					repl_patch_line = p_input_line;
					p_line[p_end] = savestr(buf);
					if (out_of_mem) {
						p_end--;
						return false;
					}
					p_char[p_end] = '=';
					for (s = buf; *s && !isdigit((unsigned char)*s); s++)
						;
					if (!*s)
						malformed();
					p_newfirst = (LINENUM) atol(s);
					while (isdigit((unsigned char)*s))
						s++;
					if (*s == ',') {
						for (; *s && !isdigit((unsigned char)*s); s++)
							;
						if (!*s)
							malformed();
						p_repl_lines = ((LINENUM) atol(s)) -
						    p_newfirst + 1;
					} else if (p_newfirst)
						p_repl_lines = 1;
					else {
						p_repl_lines = 0;
						p_newfirst = 1;
					}
					p_max = p_repl_lines + p_end;
					if (p_max > MAXHUNKSIZE)
						fatal("hunk too large (%ld lines) at line %ld: %s",
						    p_max, p_input_line, buf);
					while (p_max >= hunkmax)
						grow_hunkmax();
					if (p_repl_lines != ptrn_copiable &&
					    (p_context != 0 || p_repl_lines != 1))
						repl_could_be_missing = false;
					break;
				}
				goto change_line;
			case '+':
			case '!':
				repl_could_be_missing = false;
		change_line:
				if (buf[1] == '\n' && canonicalize)
					strlcpy(buf + 1, " \n", buf_size - 1);
				if (!isspace((unsigned char)buf[1]) && buf[1] != '>' &&
				    buf[1] != '<' &&
				    repl_beginning && repl_could_be_missing) {
					repl_missing = true;
					goto hunk_done;
				}
				if (context >= 0) {
					if (context < p_context)
						p_context = context;
					context = -1000;
				}
				p_line[p_end] = savestr(buf + 2);
				if (out_of_mem) {
					p_end--;
					return false;
				}
				if (p_end == p_ptrn_lines) {
					if (remove_special_line()) {
						int	l;

						l = strlen(p_line[p_end]) - 1;
						(p_line[p_end])[l] = 0;
					}
				}
				break;
			case '\t':
			case '\n':	/* assume the 2 spaces got eaten */
				if (repl_beginning && repl_could_be_missing &&
				    (!ptrn_spaces_eaten ||
				    diff_type == NEW_CONTEXT_DIFF)) {
					repl_missing = true;
					goto hunk_done;
				}
				p_line[p_end] = savestr(buf);
				if (out_of_mem) {
					p_end--;
					return false;
				}
				if (p_end != p_ptrn_lines + 1) {
					ptrn_spaces_eaten |= (repl_beginning != 0);
					context++;
					if (!repl_beginning)
						ptrn_copiable++;
					p_char[p_end] = ' ';
				}
				break;
			case ' ':
				if (!isspace((unsigned char)buf[1]) &&
				    repl_beginning && repl_could_be_missing) {
					repl_missing = true;
					goto hunk_done;
				}
				context++;
				if (!repl_beginning)
					ptrn_copiable++;
				p_line[p_end] = savestr(buf + 2);
				if (out_of_mem) {
					p_end--;
					return false;
				}
				break;
			default:
				if (repl_beginning && repl_could_be_missing) {
					repl_missing = true;
					goto hunk_done;
				}
				malformed();
			}
			/* set up p_len for strncmp() so we don't have to */
			/* assume null termination */
			if (p_line[p_end])
				p_len[p_end] = strlen(p_line[p_end]);
			else
				p_len[p_end] = 0;
		}

hunk_done:
		if (p_end >= 0 && !repl_beginning)
			fatal("no --- found in patch at line %ld\n", pch_hunk_beg());

		if (repl_missing) {

			/* reset state back to just after --- */
			p_input_line = repl_patch_line;
			for (p_end--; p_end > repl_beginning; p_end--)
				free(p_line[p_end]);
			fseek(pfp, repl_backtrack_position, SEEK_SET);

			/* redundant 'new' context lines were omitted - set */
			/* up to fill them in from the old file context */
			if (!p_context && p_repl_lines == 1) {
				p_repl_lines = 0;
				p_max--;
			}
			fillsrc = 1;
			filldst = repl_beginning + 1;
			fillcnt = p_repl_lines;
			p_end = p_max;
		} else if (!p_context && fillcnt == 1) {
			/* the first hunk was a null hunk with no context */
			/* and we were expecting one line -- fix it up. */
			while (filldst < p_end) {
				p_line[filldst] = p_line[filldst + 1];
				p_char[filldst] = p_char[filldst + 1];
				p_len[filldst] = p_len[filldst + 1];
				filldst++;
			}
#if 0
			repl_beginning--;	/* this doesn't need to be fixed */
#endif
			p_end--;
			p_first++;	/* do append rather than insert */
			fillcnt = 0;
			p_ptrn_lines = 0;
		}
		if (diff_type == CONTEXT_DIFF &&
		    (fillcnt || (p_first > 1 && ptrn_copiable > 2 * p_context))) {
			if (verbose)
				say("%s\n%s\n%s\n",
				    "(Fascinating--this is really a new-style context diff but without",
				    "the telltale extra asterisks on the *** line that usually indicate",
				    "the new style...)");
			diff_type = NEW_CONTEXT_DIFF;
		}
		/* if there were omitted context lines, fill them in now */
		if (fillcnt) {
			p_bfake = filldst;	/* remember where not to free() */
			p_efake = filldst + fillcnt - 1;
			while (fillcnt-- > 0) {
				while (fillsrc <= p_end && p_char[fillsrc] != ' ')
					fillsrc++;
				if (fillsrc > p_end)
					fatal("replacement text or line numbers mangled in hunk at line %ld\n",
					    p_hunk_beg);
				p_line[filldst] = p_line[fillsrc];
				p_char[filldst] = p_char[fillsrc];
				p_len[filldst] = p_len[fillsrc];
				fillsrc++;
				filldst++;
			}
			while (fillsrc <= p_end && fillsrc != repl_beginning &&
			    p_char[fillsrc] != ' ')
				fillsrc++;
#ifdef DEBUGGING
			if (debug & 64)
				printf("fillsrc %ld, filldst %ld, rb %ld, e+1 %ld\n",
				fillsrc, filldst, repl_beginning, p_end + 1);
#endif
			if (fillsrc != p_end + 1 && fillsrc != repl_beginning)
				malformed();
			if (filldst != p_end + 1 && filldst != repl_beginning)
				malformed();
		}
		if (p_line[p_end] != NULL) {
			if (remove_special_line()) {
				p_len[p_end] -= 1;
				(p_line[p_end])[p_len[p_end]] = 0;
			}
		}
	} else if (diff_type == UNI_DIFF) {
		LINENUM	fillold;	/* index of old lines */
		LINENUM	fillnew;	/* index of new lines */
		char	ch;

		line_beginning = ftell(pfp); /* file pos of the current line */
		len = pgets(true);
		p_input_line++;
		if (len == 0 || strnNE(buf, "@@ -", 4)) {
			next_intuit_at(line_beginning, p_input_line);
			return false;
		}
		s = buf + 4;
		if (!*s)
			malformed();
		p_first = (LINENUM) atol(s);
		while (isdigit((unsigned char)*s))
			s++;
		if (*s == ',') {
			p_ptrn_lines = (LINENUM) atol(++s);
			while (isdigit((unsigned char)*s))
				s++;
		} else
			p_ptrn_lines = 1;
		if (*s == ' ')
			s++;
		if (*s != '+' || !*++s)
			malformed();
		p_newfirst = (LINENUM) atol(s);
		while (isdigit((unsigned char)*s))
			s++;
		if (*s == ',') {
			p_repl_lines = (LINENUM) atol(++s);
			while (isdigit((unsigned char)*s))
				s++;
		} else
			p_repl_lines = 1;
		if (*s == ' ')
			s++;
		if (*s != '@')
			malformed();
		if (!p_ptrn_lines)
			p_first++;	/* do append rather than insert */
		p_max = p_ptrn_lines + p_repl_lines + 1;
		while (p_max >= hunkmax)
			grow_hunkmax();
		fillold = 1;
		fillnew = fillold + p_ptrn_lines;
		p_end = fillnew + p_repl_lines;
		snprintf(buf, buf_size, "*** %ld,%ld ****\n", p_first,
		    p_first + p_ptrn_lines - 1);
		p_line[0] = savestr(buf);
		if (out_of_mem) {
			p_end = -1;
			return false;
		}
		p_char[0] = '*';
		snprintf(buf, buf_size, "--- %ld,%ld ----\n", p_newfirst,
		    p_newfirst + p_repl_lines - 1);
		p_line[fillnew] = savestr(buf);
		if (out_of_mem) {
			p_end = 0;
			return false;
		}
		p_char[fillnew++] = '=';
		p_context = 100;
		context = 0;
		p_hunk_beg = p_input_line + 1;
		while (fillold <= p_ptrn_lines || fillnew <= p_end) {
			line_beginning = ftell(pfp);
			len = pgets(true);
			p_input_line++;
			if (len == 0) {
				if (p_max - fillnew < 3) {
					/* assume blank lines got chopped */
					strlcpy(buf, " \n", buf_size);
				} else {
					fatal("unexpected end of file in patch\n");
				}
			}
			if (*buf == '\t' || *buf == '\n') {
				ch = ' ';	/* assume the space got eaten */
				s = savestr(buf);
			} else {
				ch = *buf;
				s = savestr(buf + 1);
			}
			if (out_of_mem) {
				while (--fillnew > p_ptrn_lines)
					free(p_line[fillnew]);
				p_end = fillold - 1;
				return false;
			}
			switch (ch) {
			case '-':
				if (fillold > p_ptrn_lines) {
					free(s);
					p_end = fillnew - 1;
					malformed();
				}
				p_char[fillold] = ch;
				p_line[fillold] = s;
				p_len[fillold++] = strlen(s);
				if (fillold > p_ptrn_lines) {
					if (remove_special_line()) {
						p_len[fillold - 1] -= 1;
						s[p_len[fillold - 1]] = 0;
					}
				}
				break;
			case '=':
				ch = ' ';
				/* FALL THROUGH */
			case ' ':
				if (fillold > p_ptrn_lines) {
					free(s);
					while (--fillnew > p_ptrn_lines)
						free(p_line[fillnew]);
					p_end = fillold - 1;
					malformed();
				}
				context++;
				p_char[fillold] = ch;
				p_line[fillold] = s;
				p_len[fillold++] = strlen(s);
				s = savestr(s);
				if (out_of_mem) {
					while (--fillnew > p_ptrn_lines)
						free(p_line[fillnew]);
					p_end = fillold - 1;
					return false;
				}
				if (fillold > p_ptrn_lines) {
					if (remove_special_line()) {
						p_len[fillold - 1] -= 1;
						s[p_len[fillold - 1]] = 0;
					}
				}
				/* FALL THROUGH */
			case '+':
				if (fillnew > p_end) {
					free(s);
					while (--fillnew > p_ptrn_lines)
						free(p_line[fillnew]);
					p_end = fillold - 1;
					malformed();
				}
				p_char[fillnew] = ch;
				p_line[fillnew] = s;
				p_len[fillnew++] = strlen(s);
				if (fillold > p_ptrn_lines) {
					if (remove_special_line()) {
						p_len[fillnew - 1] -= 1;
						s[p_len[fillnew - 1]] = 0;
					}
				}
				break;
			default:
				p_end = fillnew;
				malformed();
			}
			if (ch != ' ' && context > 0) {
				if (context < p_context)
					p_context = context;
				context = -1000;
			}
		}		/* while */
	} else {		/* normal diff--fake it up */
		char	hunk_type;
		int	i;
		LINENUM	min, max;

		line_beginning = ftell(pfp);
		p_context = 0;
		len = pgets(true);
		p_input_line++;
		if (len == 0 || !isdigit((unsigned char)*buf)) {
			next_intuit_at(line_beginning, p_input_line);
			return false;
		}
		p_first = (LINENUM) atol(buf);
		for (s = buf; isdigit((unsigned char)*s); s++)
			;
		if (*s == ',') {
			p_ptrn_lines = (LINENUM) atol(++s) - p_first + 1;
			while (isdigit((unsigned char)*s))
				s++;
		} else
			p_ptrn_lines = (*s != 'a');
		hunk_type = *s;
		if (hunk_type == 'a')
			p_first++;	/* do append rather than insert */
		min = (LINENUM) atol(++s);
		for (; isdigit((unsigned char)*s); s++)
			;
		if (*s == ',')
			max = (LINENUM) atol(++s);
		else
			max = min;
		if (hunk_type == 'd')
			min++;
		p_end = p_ptrn_lines + 1 + max - min + 1;
		if (p_end > MAXHUNKSIZE)
			fatal("hunk too large (%ld lines) at line %ld: %s",
			    p_end, p_input_line, buf);
		while (p_end >= hunkmax)
			grow_hunkmax();
		p_newfirst = min;
		p_repl_lines = max - min + 1;
		snprintf(buf, buf_size, "*** %ld,%ld\n", p_first,
		    p_first + p_ptrn_lines - 1);
		p_line[0] = savestr(buf);
		if (out_of_mem) {
			p_end = -1;
			return false;
		}
		p_char[0] = '*';
		for (i = 1; i <= p_ptrn_lines; i++) {
			len = pgets(true);
			p_input_line++;
			if (len == 0)
				fatal("unexpected end of file in patch at line %ld\n",
				    p_input_line);
			if (*buf != '<')
				fatal("< expected at line %ld of patch\n",
				    p_input_line);
			p_line[i] = savestr(buf + 2);
			if (out_of_mem) {
				p_end = i - 1;
				return false;
			}
			p_len[i] = strlen(p_line[i]);
			p_char[i] = '-';
		}

		if (remove_special_line()) {
			p_len[i - 1] -= 1;
			(p_line[i - 1])[p_len[i - 1]] = 0;
		}
		if (hunk_type == 'c') {
			len = pgets(true);
			p_input_line++;
			if (len == 0)
				fatal("unexpected end of file in patch at line %ld\n",
				    p_input_line);
			if (*buf != '-')
				fatal("--- expected at line %ld of patch\n",
				    p_input_line);
		}
		snprintf(buf, buf_size, "--- %ld,%ld\n", min, max);
		p_line[i] = savestr(buf);
		if (out_of_mem) {
			p_end = i - 1;
			return false;
		}
		p_char[i] = '=';
		for (i++; i <= p_end; i++) {
			len = pgets(true);
			p_input_line++;
			if (len == 0)
				fatal("unexpected end of file in patch at line %ld\n",
				    p_input_line);
			if (*buf != '>')
				fatal("> expected at line %ld of patch\n",
				    p_input_line);
			p_line[i] = savestr(buf + 2);
			if (out_of_mem) {
				p_end = i - 1;
				return false;
			}
			p_len[i] = strlen(p_line[i]);
			p_char[i] = '+';
		}

		if (remove_special_line()) {
			p_len[i - 1] -= 1;
			(p_line[i - 1])[p_len[i - 1]] = 0;
		}
	}
	if (reverse)		/* backwards patch? */
		if (!pch_swap())
			say("Not enough memory to swap next hunk!\n");
#ifdef DEBUGGING
	if (debug & 2) {
		int	i;
		char	special;

		for (i = 0; i <= p_end; i++) {
			if (i == p_ptrn_lines)
				special = '^';
			else
				special = ' ';
			fprintf(stderr, "%3d %c %c %s", i, p_char[i],
			    special, p_line[i]);
			fflush(stderr);
		}
	}
#endif
	if (p_end + 1 < hunkmax)/* paranoia reigns supreme... */
		p_char[p_end + 1] = '^';	/* add a stopper for apply_hunk */
	return true;
}
Example #7
0
static int
intuit_diff_type(void)
{
	long	this_line = 0, previous_line;
	long	first_command_line = -1;
	LINENUM	fcl_line = -1;
	bool	last_line_was_command = false, this_is_a_command = false;
	bool	stars_last_line = false, stars_this_line = false;
	char	*s, *t;
	int	indent, retval;
	struct file_name names[MAX_FILE];

	memset(names, 0, sizeof(names));
	ok_to_create_file = false;
	fseek(pfp, p_base, SEEK_SET);
	p_input_line = p_bline - 1;
	for (;;) {
		previous_line = this_line;
		last_line_was_command = this_is_a_command;
		stars_last_line = stars_this_line;
		this_line = ftell(pfp);
		indent = 0;
		p_input_line++;
		if (pgets(false) == 0) {
			if (first_command_line >= 0L) {
				/* nothing but deletes!? */
				p_start = first_command_line;
				p_sline = fcl_line;
				retval = ED_DIFF;
				goto scan_exit;
			} else {
				p_start = this_line;
				p_sline = p_input_line;
				retval = 0;
				goto scan_exit;
			}
		}
		for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) {
			if (*s == '\t')
				indent += 8 - (indent % 8);
			else
				indent++;
		}
		for (t = s; isdigit((unsigned char)*t) || *t == ','; t++)
			;
		this_is_a_command = (isdigit((unsigned char)*s) &&
		    (*t == 'd' || *t == 'c' || *t == 'a'));
		if (first_command_line < 0L && this_is_a_command) {
			first_command_line = this_line;
			fcl_line = p_input_line;
			p_indent = indent;	/* assume this for now */
		}
		if (!stars_last_line && strnEQ(s, "*** ", 4))
			names[OLD_FILE].path = fetchname(s + 4,
			    &names[OLD_FILE].exists, strippath);
		else if (strnEQ(s, "--- ", 4))
			names[NEW_FILE].path = fetchname(s + 4,
			    &names[NEW_FILE].exists, strippath);
		else if (strnEQ(s, "+++ ", 4))
			/* pretend it is the old name */
			names[OLD_FILE].path = fetchname(s + 4,
			    &names[OLD_FILE].exists, strippath);
		else if (strnEQ(s, "Index:", 6))
			names[INDEX_FILE].path = fetchname(s + 6,
			    &names[INDEX_FILE].exists, strippath);
		else if (strnEQ(s, "Prereq:", 7)) {
			for (t = s + 7; isspace((unsigned char)*t); t++)
				;
			revision = savestr(t);
			for (t = revision; *t && !isspace((unsigned char)*t); t++)
				;
			*t = '\0';
			if (*revision == '\0') {
				free(revision);
				revision = NULL;
			}
		} else if (strnEQ(s, "==== ", 5)) {
			/* Perforce-style diffs. */
			if ((t = strstr(s + 5, " - ")) != NULL)
				p4_fetchname(&names[NEW_FILE], t + 3);
			p4_fetchname(&names[OLD_FILE], s + 5);
		}
		if ((!diff_type || diff_type == ED_DIFF) &&
		    first_command_line >= 0L &&
		    strEQ(s, ".\n")) {
			p_indent = indent;
			p_start = first_command_line;
			p_sline = fcl_line;
			retval = ED_DIFF;
			goto scan_exit;
		}
		if ((!diff_type || diff_type == UNI_DIFF) && strnEQ(s, "@@ -", 4)) {
			if (strnEQ(s + 4, "0,0", 3))
				ok_to_create_file = true;
			p_indent = indent;
			p_start = this_line;
			p_sline = p_input_line;
			retval = UNI_DIFF;
			goto scan_exit;
		}
		stars_this_line = strnEQ(s, "********", 8);
		if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line &&
		    strnEQ(s, "*** ", 4)) {
			if (atol(s + 4) == 0)
				ok_to_create_file = true;
			/*
			 * If this is a new context diff the character just
			 * before the newline is a '*'.
			 */
			while (*s != '\n')
				s++;
			p_indent = indent;
			p_start = previous_line;
			p_sline = p_input_line - 1;
			retval = (*(s - 1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF);
			goto scan_exit;
		}
		if ((!diff_type || diff_type == NORMAL_DIFF) &&
		    last_line_was_command &&
		    (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2))) {
			p_start = previous_line;
			p_sline = p_input_line - 1;
			p_indent = indent;
			retval = NORMAL_DIFF;
			goto scan_exit;
		}
	}
scan_exit:
	if (retval == UNI_DIFF) {
		/* unswap old and new */
		struct file_name tmp = names[OLD_FILE];
		names[OLD_FILE] = names[NEW_FILE];
		names[NEW_FILE] = tmp;
	}
	if (filearg[0] == NULL) {
		if (posix)
			filearg[0] = posix_name(names, ok_to_create_file);
		else {
			/* Ignore the Index: name for context diffs, like GNU */
			if (names[OLD_FILE].path != NULL ||
			    names[NEW_FILE].path != NULL) {
				free(names[INDEX_FILE].path);
				names[INDEX_FILE].path = NULL;
			}
			filearg[0] = best_name(names, ok_to_create_file);
		}
	}

	free(bestguess);
	bestguess = NULL;
	if (filearg[0] != NULL)
		bestguess = savestr(filearg[0]);
	else if (!ok_to_create_file) {
		/*
		 * We don't want to create a new file but we need a
		 * filename to set bestguess.  Avoid setting filearg[0]
		 * so the file is not created automatically.
		 */
		if (posix)
			bestguess = posix_name(names, true);
		else
			bestguess = best_name(names, true);
	}
	free(names[OLD_FILE].path);
	free(names[NEW_FILE].path);
	free(names[INDEX_FILE].path);
	return retval;
}
/* ................................ MAIN ............................. */
int      main         (void)
{
FILE     *Fptr[2];
int      iprint, printint, iloop;
double   T, TINITIAL,TFINAL,INTEGSTP,abserr,relerr,_printint;
double   VAR[2];

/* Open input and output files */
for(iloop=0;  iloop<=1;  iloop++)
  {
  char fileName[256];
  if( !iloop ) strcpy(fileName, "PendulumDynamics.in");
  else sprintf(fileName, "PendulumDynamics.%d", iloop);
  if( (Fptr[iloop] = fopen(fileName, iloop ? "w" : "r")) == NULL)
    {printf("Error: unable to open file %s\n", fileName);  exit(0);}
  }
 
/* Read top of input file */
for(iloop=0;  iloop<6;  iloop++) pgets(Fptr[0],NULL);

/* Read values of constants from input file */
readf(Fptr[0],&g,&i,&l,&m,NULL);

/* Read the initial value of each variable from input file */
readf(Fptr[0],&omega,&theta,NULL);

/* Read integration parameters from input file */
readf(Fptr[0],&TINITIAL,&TFINAL,&INTEGSTP,&_printint,&abserr,&relerr,NULL);
printint = (int)_printint;

/* Write heading(s) to output file(s) */
fprintf(stdout,  "%% FILE: PendulumDynamics.1\n%%\n");
fprintf(stdout,  "%%     omega          theta            k              p         longoutput\n"
                 "%% (radian/sec)     (radian)       (joules)       (joules)        (UNITS)\n\n" );
fprintf(Fptr[1], "%% FILE: PendulumDynamics.1\n%%\n");
fprintf(Fptr[1], "%%     omega          theta            k              p         longoutput\n"
                 "%% (radian/sec)     (radian)       (joules)       (joules)        (UNITS)\n\n" );

/* Unit conversions */
  Pi       = 3.141592653589793;
  DEGtoRAD = Pi/180.0;
  RADtoDEG = 180.0/Pi;

/* Evaluate constants */
  z[8] = g*m;
  z[15] = g*l*m;

/* Initialize time, print counter, variables array for integrator */
  T      = TINITIAL;
  iprint = 0;
  VAR[0] = omega;
  VAR[1] = theta;

/* Initalize numerical integrator, with call to eqns1 at T=TINITIAL */
kutta(eqns1, 2, VAR, &T, INTEGSTP, abserr, relerr, 0);

/* Numerically integrate; print results */
while(1)
  {
  if( TFINAL>=TINITIAL && T+.01*INTEGSTP>=TFINAL) iprint=-7;
  if( TFINAL<=TINITIAL && T+.01*INTEGSTP<=TFINAL) iprint=-7;
  if( iprint <= 0 )
    {
    output(Fptr, T);
    if( iprint == -7 ) break;
    iprint = printint;
    }
  if( !kutta(eqns1, 2, VAR, &T, INTEGSTP, abserr, relerr, 2) )
    {
    output(Fptr, T);
    for(iloop=0;  iloop<=1;  iloop++)
      fputs( "\n\tError: Numerical integration failed to converge\n",
              iloop ? Fptr[iloop]:stdout);
    break;
    }
  iprint--;
  }

/* Inform user of input and output filename(s) */
puts( "\n Input is in the file PendulumDynamics.in" );
puts( "\n Output is in the file PendulumDynamics.1" );
puts( "\n The output quantities and associated files are listed in file "
      "PendulumDynamics.dir\n" );
return 0;
}
Example #9
0
void
copy(int prompt, FILE *fin)
{
	FILE *fout, *f;
	char s[200], t[200], s1[200], *r, *tod;
	char nm[100];
	int *p;
	time_t tval;
	int nmatch = 0;

	if (subdir[0] == 0)
		snprintf(subdir, sizeof subdir, "%s/%s", _PATH_LLIB, sname);
	for (;;) {
		if (pgets(s, sizeof s, prompt, fin) == 0) {
			if (fin == stdin) {
				/* fprintf(stderr, "Don't type control-D\n"); */
				/* this didn't work out very well */
				wrapup(1);	/* ian */
				continue;
			} else
				break;
		}
		trim(s);
		/* change the sequence %s to lesson directory */
		/* if needed */
		for (r = s; *r; r++)
			if (*r == '%') {
				snprintf(s1, sizeof s1, s,
				    subdir, subdir, subdir);
				strlcpy(s, s1, sizeof s);
				break;
			}
		r = wordb(s, t);
		p = action(t);
		/* some actions done only once per script */
		if (p && *p == ONCE) {
			if (wrong) {	/* we are on 2nd time */
				scopy(fin, NULL);
				continue;
			}
			strlcpy(s, r, sizeof s);
			r = wordb(s, t);
			p = action(t);
		}
		if (p == 0) {
			if (comfile >= 0) {
				write(comfile, s, strlen(s));
				write(comfile, "\n", 1);
			}
			else {
				signal(SIGINT, SIG_IGN);
				status = mysys(s);
				signal(SIGINT, signal_intrpt);
			}
			if (incopy) {
				fprintf(incopy, "%s\n", s);
				strlcpy(last, s, sizeof last);
			}
			continue;
		}
		switch (*p) {
		case READY:
			if (incopy && r) {
				fprintf(incopy, "%s\n", r);
				strlcpy(last, r, sizeof last);
			}
			return;
		case PRINT:
			if (wrong)
				scopy(fin, NULL);	/* don't repeat msg */
			else if (r)
				list(r);
			else
				scopy(fin, stdout);
			break;
		case NOP:
			break;
		case MATCH:
			if (nmatch > 0)	/* we have already passed */
				scopy(fin, NULL);
			/* did we pass this time? */
			else if ((status = strcmp(r, last)) == 0) {
				nmatch++;
				scopy(fin, stdout);
			} else
				scopy(fin, NULL);
			break;
		case BAD:
			if (strcmp(r, last) == 0)
				scopy(fin, stdout);
			else
				scopy(fin, NULL);
			break;
		case SUCCEED:
			scopy(fin, (status == 0) ? stdout : NULL);
			break;
		case FAIL:
			scopy(fin, (status != 0) ? stdout : NULL);
			break;
		case CREATE:
			fout = fopen(r, "w");
			scopy(fin, fout);
			fclose(fout);
			break;
		case CMP:
			status = cmp(r);	/* contains two file names */
			break;
		case MV:
			snprintf(nm, sizeof nm, "%s/L%s.%s", subdir, todo, r);
			fcopy(r, nm);
			break;
		case USER:
		case NEXT:
			more = 1;
			return;
		case COPYIN:
			incopy = fopen(".copy", "w");
			break;
		case UNCOPIN:
			fclose(incopy);
			incopy = NULL;
			break;
		case COPYOUT:
			maktee();
			break;
		case UNCOPOUT:
			untee();
			break;
		case PIPE:
			comfile = makpipe();
			break;
		case UNPIPE:
			close(comfile);
			wait(0);
			comfile = -1;
			break;
		case YES:
		case NO:
			if (incopy) {
				fprintf(incopy, "%s\n", s);
				strlcpy(last, s, sizeof last);
			}
			return;
		case WHERE:
			printf("You are in lesson %s\n", todo);
			fflush(stdout);
			break;
		case BYE:
			more = 0;
			return;
		case CHDIR:
			printf("cd not allowed\n");
			fflush(stdout);
			break;
		case LEARN:
			printf("You are already in learn.\n");
			fflush(stdout);
			break;
		case LOG:
			if (!logging)
				break;
			if (logfile[0] == 0) {
				snprintf(logfile, sizeof logfile,
				    "%s/log/%s", direct, sname);
			}
			f = fopen((r ? r : logfile), "a");
			if (f == NULL)
				break;
			time(&tval);
			tod = ctime(&tval);
			tod[24] = 0;
			fprintf(f, "%s L%-6s %s %2d %s\n", tod,
			    todo, status? "fail" : "pass", speed, pwline);
			fclose(f);
			break;
		}
	}
	return;
}