コード例 #1
0
ファイル: copy_lines.c プロジェクト: Harsh-Vardhan/copy-lines
int main(void)
{
	/* Local Declarations */
	int	count_lines_copied;
	char	usr_ch;

	/* Program Intro */
	LINEBREAK;
	printf("This program copies lines beginning with the user specified character");

	/* Read user specified character */
	LINEBREAK;
	printf("Please type in a character (a-z): ");
	while(scanf("%c", &usr_ch) != 1 )
		printf("ERROR: Invalid input, try again: ");

	/* Call function to copy lines matching the user specified character */
	LINEBREAK;
	printf("Copying lines...");
	count_lines_copied = copy_lines(usr_ch);
	LINEBREAK;
	printf("Done... a total of %d lines were copied", count_lines_copied);

	/* Exit Program */
	LINEBREAK; LINEBREAK;
	return 0;
}
コード例 #2
0
void
cmd_insert()
{
  int m;
  size_t text_len;
  get_int_opt(&m);
  if (m < ln) notif_error("Invalid line number");
  next_arg();
  copy_lines(m);
  write_text();
  ln = m + 1;
}
コード例 #3
0
void
cmd_delete()
{
  int m, n;
  get_int_opt(&m);
  next_arg();
  get_int_opt(&n);
  if (m > n) notif_error("First argument cannot be greater than the second");
  copy_lines(m - 1);
  if (m < ln) notif_error("Invalid line number");
  goto_line(n + 1);
}
コード例 #4
0
void
cmd_replace()
{
  int m, n;
  get_int_opt(&m);
  next_arg();
  get_int_opt(&n);
  if (m > n) notif_error("First argument cannot be greater than the second");
  next_arg();
  copy_lines(m - 1);
  if (m < ln) return;
  goto_line(n + 1);
  write_text();
}
コード例 #5
0
ファイル: RecordList.cpp プロジェクト: szte-wsn/szte-wsn
void RecordList::read_all() {

    matching_header->clear(); // TODO Check what is good for the GUI
    matching_records->clear();
    matching_timesync_data->clear();

    scout->read_all_existing();

    //scout->dump_all();

    qDebug() << "Number of records: " << scout->record_info().size();

    copy_headers();
    copy_lines();
}
コード例 #6
0
int interpret_instruction(char *buf, int fd_in, int cur_line, int fd_out) {

    if(buf[0] == 'E') {
        return -1;
    }
    
    struct parameters_t parameters;
    int res = get_parameters(buf, &parameters);
    printf("%d;%c\n",res,parameters.cmd);
    if(res > 0) {

        switch(parameters.cmd) {
            case 'I':
            printf("I\n");
            if(copy_lines(cur_line, parameters.m, fd_in, fd_out)<0)
                return -2;
            write(fd_out, parameters.text, SIZE-4);
            cur_line = parameters.m + 1;
            break;

            case 'R':
            printf("R\n");
            write(fd_out, parameters.text, SIZE-6);
            case 'D':
            printf("D ou R\n");
            if(jump_to_line(fd_in, cur_line, parameters.n) < 0)
                return -2;
            cur_line = parameters.n;
            break;    
        }

        return cur_line;
    }
    printf("ERROR GET\n");
    return -2;
}
コード例 #7
0
ファイル: patch.c プロジェクト: acassis/emlinux-ssd1935
int patch_main(int argc, char **argv)
{
	int patch_level = -1;
	char *patch_line;
	int ret;
	FILE *patch_file = NULL;

	{
		char *p, *i;
		ret = getopt32(argv, "p:i:", &p, &i);
		if (ret & 1)
			patch_level = xatol_range(p, -1, USHRT_MAX);
		if (ret & 2) {
			patch_file = xfopen(i, "r");
		} else {
			patch_file = stdin;
		}
		ret = 0;
	}

	patch_line = xmalloc_getline(patch_file);
	while (patch_line) {
		FILE *src_stream;
		FILE *dst_stream;
		char *original_filename;
		char *new_filename;
		char *backup_filename;
		unsigned int src_cur_line = 1;
		unsigned int dest_cur_line = 0;
		unsigned int dest_beg_line;
		unsigned int bad_hunk_count = 0;
		unsigned int hunk_count = 0;
		char copy_trailing_lines_flag = 0;

		/* Skip everything upto the "---" marker
		 * No need to parse the lines "Only in <dir>", and "diff <args>"
		 */
		while (patch_line && strncmp(patch_line, "--- ", 4) != 0) {
			free(patch_line);
			patch_line = xmalloc_getline(patch_file);
		}
		/* FIXME: patch_line NULL check?? */

		/* Extract the filename used before the patch was generated */
		original_filename = extract_filename(patch_line, patch_level);
		free(patch_line);

		patch_line = xmalloc_getline(patch_file);
		/* FIXME: NULL check?? */
		if (strncmp(patch_line, "+++ ", 4) != 0) {
			ret = 2;
			bb_error_msg("invalid patch");
			continue;
		}
		new_filename = extract_filename(patch_line, patch_level);
		free(patch_line);

		if (file_doesnt_exist(new_filename)) {
			char *line_ptr;
			/* Create leading directories */
			line_ptr = strrchr(new_filename, '/');
			if (line_ptr) {
				*line_ptr = '\0';
				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
				*line_ptr = '/';
			}
			dst_stream = xfopen(new_filename, "w+");
			backup_filename = NULL;
		} else {
			backup_filename = xmalloc(strlen(new_filename) + 6);
			strcpy(backup_filename, new_filename);
			strcat(backup_filename, ".orig");
			if (rename(new_filename, backup_filename) == -1) {
				bb_perror_msg_and_die("cannot create file %s",
						backup_filename);
			}
			dst_stream = xfopen(new_filename, "w");
		}

		if ((backup_filename == NULL) || file_doesnt_exist(original_filename)) {
			src_stream = NULL;
		} else {
			if (strcmp(original_filename, new_filename) == 0) {
				src_stream = xfopen(backup_filename, "r");
			} else {
				src_stream = xfopen(original_filename, "r");
			}
		}

		printf("patching file %s\n", new_filename);

		/* Handle each hunk */
		patch_line = xmalloc_fgets(patch_file);
		while (patch_line) {
			unsigned int count;
			unsigned int src_beg_line;
			unsigned int unused;
			unsigned int hunk_offset_start = 0;
			int hunk_error = 0;

			/* This bit should be improved */
			if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, &unused, &dest_beg_line, &unused) != 4) &&
				(sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, &unused, &dest_beg_line) != 3) &&
				(sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line, &dest_beg_line, &unused) != 3)) {
				/* No more hunks for this file */
				break;
			}
			free(patch_line);
			hunk_count++;

			if (src_beg_line && dest_beg_line) {
				/* Copy unmodified lines upto start of hunk */
				/* src_beg_line will be 0 if its a new file */
				count = src_beg_line - src_cur_line;
				if (copy_lines(src_stream, dst_stream, count) != count) {
					bb_error_msg_and_die("bad src file");
				}
				src_cur_line += count;
				dest_cur_line += count;
				copy_trailing_lines_flag = 1;
			}
			hunk_offset_start = src_cur_line;

			while ((patch_line = xmalloc_fgets(patch_file)) != NULL) {
				if ((*patch_line == '-') || (*patch_line == ' ')) {
					char *src_line = NULL;
					if (src_stream) {
						src_line = xmalloc_fgets(src_stream);
						if (!src_line) {
							hunk_error++;
							break;
						} else {
							src_cur_line++;
						}
						if (strcmp(src_line, patch_line + 1) != 0) {
							bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start);
							hunk_error++;
							free(patch_line);
							/* Probably need to find next hunk, etc... */
							/* but for now we just bail out */
							patch_line = NULL;
							break;
						}
						free(src_line);
					}
					if (*patch_line == ' ') {
						fputs(patch_line + 1, dst_stream);
						dest_cur_line++;
					}
				} else if (*patch_line == '+') {
					fputs(patch_line + 1, dst_stream);
					dest_cur_line++;
				} else {
					break;
				}
				free(patch_line);
			}
			if (hunk_error) {
				bad_hunk_count++;
			}
		}

		/* Cleanup last patched file */
		if (copy_trailing_lines_flag) {
			copy_lines(src_stream, dst_stream, -1);
		}
		if (src_stream) {
			fclose(src_stream);
		}
		if (dst_stream) {
			fclose(dst_stream);
		}
		if (bad_hunk_count) {
			if (!ret) {
				ret = 1;
			}
			bb_error_msg("%d out of %d hunk FAILED", bad_hunk_count, hunk_count);
		} else {
			/* It worked, we can remove the backup */
			if (backup_filename) {
				unlink(backup_filename);
			}
			if ((dest_cur_line == 0) || (dest_beg_line == 0)) {
				/* The new patched file is empty, remove it */
				xunlink(new_filename);
				if (strcmp(new_filename, original_filename) != 0)
					xunlink(original_filename);
			}
		}
	}

	/* 0 = SUCCESS
	 * 1 = Some hunks failed
	 * 2 = More serious problems
	 */
	return ret;
}
コード例 #8
0
ファイル: patch_bbox.c プロジェクト: ThinkIntegrate/busybox
int patch_main(int argc UNUSED_PARAM, char **argv)
{
	struct stat saved_stat;
	char *patch_line;
	FILE *patch_file;
	int patch_level;
	int ret = 0;
	char plus = '+';
	unsigned opt;
	enum {
		OPT_R = (1 << 2),
		OPT_N = (1 << 3),
		/*OPT_f = (1 << 4), ignored */
		/*OPT_E = (1 << 5), ignored, this is the default */
		/*OPT_g = (1 << 6), ignored */
		OPT_dry_run = (1 << 7) * ENABLE_LONG_OPTS,
	};

	xfunc_error_retval = 2;
	{
		const char *p = "-1";
		const char *i = "-"; /* compat */
#if ENABLE_LONG_OPTS
		static const char patch_longopts[] ALIGN1 =
			"strip\0"                 Required_argument "p"
			"input\0"                 Required_argument "i"
			"reverse\0"               No_argument       "R"
			"forward\0"               No_argument       "N"
		/* "Assume user knows what [s]he is doing, do not ask any questions": */
			"force\0"                 No_argument       "f" /*ignored*/
# if ENABLE_DESKTOP
			"remove-empty-files\0"    No_argument       "E" /*ignored*/
		/* "Controls actions when a file is under RCS or SCCS control,
		 * and does not exist or is read-only and matches the default version,
		 * or when a file is under ClearCase control and does not exist..."
		 * IOW: rather obscure option.
		 * But Gentoo's portage does use -g0 */
			"get\0"                   Required_argument "g" /*ignored*/
# endif
			"dry-run\0"               No_argument       "\xfd"
# if ENABLE_DESKTOP
			"backup-if-mismatch\0"    No_argument       "\xfe" /*ignored*/
			"no-backup-if-mismatch\0" No_argument       "\xff" /*ignored*/
# endif
			;
		applet_long_options = patch_longopts;
#endif
		/* -f,-E,-g are ignored */
		opt = getopt32(argv, "p:i:RN""fEg:", &p, &i, NULL);
		if (opt & OPT_R)
			plus = '-';
		patch_level = xatoi(p); /* can be negative! */
		patch_file = xfopen_stdin(i);
	}

	patch_line = xmalloc_fgetline(patch_file);
	while (patch_line) {
		FILE *src_stream;
		FILE *dst_stream;
		//char *old_filename;
		char *new_filename;
		char *backup_filename = NULL;
		unsigned src_cur_line = 1;
		unsigned dst_cur_line = 0;
		unsigned dst_beg_line;
		unsigned bad_hunk_count = 0;
		unsigned hunk_count = 0;
		smallint copy_trailing_lines_flag = 0;

		/* Skip everything upto the "---" marker
		 * No need to parse the lines "Only in <dir>", and "diff <args>"
		 */
		do {
			/* Extract the filename ugsed before the patch was generated */
			new_filename = extract_filename(patch_line, patch_level, "--- ");
			// was old_filename above
			patch_line = xmalloc_fgetline(patch_file);
			if (!patch_line) goto quit;
		} while (!new_filename);
		free(new_filename); // "source" filename is irrelevant

		new_filename = extract_filename(patch_line, patch_level, "+++ ");
		if (!new_filename) {
			bb_error_msg_and_die("invalid patch");
		}

		/* Get access rights from the file to be patched */
		if (stat(new_filename, &saved_stat) != 0) {
			char *slash = strrchr(new_filename, '/');
			if (slash) {
				/* Create leading directories */
				*slash = '\0';
				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
				*slash = '/';
			}
			src_stream = NULL;
			saved_stat.st_mode = 0644;
		} else if (!(opt & OPT_dry_run)) {
			backup_filename = xasprintf("%s.orig", new_filename);
			xrename(new_filename, backup_filename);
			src_stream = xfopen_for_read(backup_filename);
		} else
			src_stream = xfopen_for_read(new_filename);

		if (opt & OPT_dry_run) {
			dst_stream = xfopen_for_write("/dev/null");
		} else {
			dst_stream = xfopen_for_write(new_filename);
			fchmod(fileno(dst_stream), saved_stat.st_mode);
		}

		printf("patching file %s\n", new_filename);

		/* Handle all hunks for this file */
		patch_line = xmalloc_fgets(patch_file);
		while (patch_line) {
			unsigned count;
			unsigned src_beg_line;
			unsigned hunk_offset_start;
			unsigned src_last_line = 1;
			unsigned dst_last_line = 1;

			if ((sscanf(patch_line, "@@ -%u,%u +%u,%u", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3)
			 && (sscanf(patch_line, "@@ -%u +%u,%u", &src_beg_line, &dst_beg_line, &dst_last_line) < 2)
			) {
				/* No more hunks for this file */
				break;
			}
			if (plus != '+') {
				/* reverse patch */
				unsigned tmp = src_last_line;
				src_last_line = dst_last_line;
				dst_last_line = tmp;
				tmp = src_beg_line;
				src_beg_line = dst_beg_line;
				dst_beg_line = tmp;
			}
			hunk_count++;

			if (src_beg_line && dst_beg_line) {
				/* Copy unmodified lines upto start of hunk */
				/* src_beg_line will be 0 if it's a new file */
				count = src_beg_line - src_cur_line;
				if (copy_lines(src_stream, dst_stream, count)) {
					bb_error_msg_and_die("bad src file");
				}
				src_cur_line += count;
				dst_cur_line += count;
				copy_trailing_lines_flag = 1;
			}
			src_last_line += hunk_offset_start = src_cur_line;
			dst_last_line += dst_cur_line;

			while (1) {
				free(patch_line);
				patch_line = xmalloc_fgets(patch_file);
				if (patch_line == NULL)
					break; /* EOF */
				if (!*patch_line) {
					/* whitespace-damaged patch with "" lines */
					free(patch_line);
					patch_line = xstrdup(" ");
				}
				if ((*patch_line != '-') && (*patch_line != '+')
				 && (*patch_line != ' ')
				) {
					break; /* End of hunk */
				}
				if (*patch_line != plus) { /* '-' or ' ' */
					char *src_line = NULL;
					if (src_cur_line == src_last_line)
						break;
					if (src_stream) {
						src_line = xmalloc_fgets(src_stream);
						if (src_line) {
							int diff = strcmp(src_line, patch_line + 1);
							src_cur_line++;
							free(src_line);
							if (diff)
								src_line = NULL;
						}
					}
					/* Do not patch an already patched hunk with -N */
					if (src_line == 0 && (opt & OPT_N)) {
						continue;
					}
					if (!src_line) {
						bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start);
						bad_hunk_count++;
						break;
					}
					if (*patch_line != ' ') { /* '-' */
						continue;
					}
				}
				if (dst_cur_line == dst_last_line)
					break;
				fputs(patch_line + 1, dst_stream);
				dst_cur_line++;
			} /* end of while loop handling one hunk */
		} /* end of while loop handling one file */

		/* Cleanup last patched file */
		if (copy_trailing_lines_flag) {
			copy_lines(src_stream, dst_stream, (unsigned)(-1));
		}
		if (src_stream) {
			fclose(src_stream);
		}
		fclose(dst_stream);
		if (bad_hunk_count) {
			ret = 1;
			bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count);
		} else {
			/* It worked, we can remove the backup */
			if (backup_filename) {
				unlink(backup_filename);
			}
			if (!(opt & OPT_dry_run)
			 && ((dst_cur_line == 0) || (dst_beg_line == 0))
			) {
				/* The new patched file is empty, remove it */
				xunlink(new_filename);
				// /* old_filename and new_filename may be the same file */
				// unlink(old_filename);
			}
		}
		free(backup_filename);
		//free(old_filename);
		free(new_filename);
	} /* end of "while there are patch lines" */
 quit:
	/* 0 = SUCCESS
	 * 1 = Some hunks failed
	 * 2 = More serious problems (exited earlier)
	 */
	return ret;
}
コード例 #9
0
ファイル: patch.c プロジェクト: Jeanlst/Onlive-Source-Backup
int patch_main(int argc UNUSED_PARAM, char **argv)
{
	struct stat saved_stat;
	char *patch_line;
	FILE *patch_file;
	int patch_level;
	int ret = 0;
	char plus = '+';

	xfunc_error_retval = 2;
	{
		const char *p = "-1";
		const char *i = "-"; /* compat */
		if (getopt32(argv, "p:i:R", &p, &i) & 4)
			plus = '-';
		patch_level = xatoi(p); /* can be negative! */
		patch_file = xfopen_stdin(i);
	}

	patch_line = xmalloc_fgetline(patch_file);
	while (patch_line) {
		FILE *src_stream;
		FILE *dst_stream;
		//char *old_filename;
		char *new_filename;
		char *backup_filename;
		unsigned src_cur_line = 1;
		unsigned dst_cur_line = 0;
		unsigned dst_beg_line;
		unsigned bad_hunk_count = 0;
		unsigned hunk_count = 0;
		smallint copy_trailing_lines_flag = 0;

		/* Skip everything upto the "---" marker
		 * No need to parse the lines "Only in <dir>", and "diff <args>"
		 */
		do {
			/* Extract the filename used before the patch was generated */
			new_filename = extract_filename(patch_line, patch_level, "--- ");
			// was old_filename above
			patch_line = xmalloc_fgetline(patch_file);
			if (!patch_line) goto quit;
		} while (!new_filename);
		free(new_filename); // "source" filename is irrelevant

		new_filename = extract_filename(patch_line, patch_level, "+++ ");
		if (!new_filename) {
			bb_error_msg_and_die("invalid patch");
		}

		/* Get access rights from the file to be patched */
		if (stat(new_filename, &saved_stat) != 0) {
			char *slash = strrchr(new_filename, '/');
			if (slash) {
				/* Create leading directories */
				*slash = '\0';
				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
				*slash = '/';
			}
			backup_filename = NULL;
			src_stream = NULL;
			saved_stat.st_mode = 0644;
		} else {
			backup_filename = xasprintf("%s.orig", new_filename);
			xrename(new_filename, backup_filename);
			src_stream = xfopen_for_read(backup_filename);
		}
		dst_stream = xfopen_for_write(new_filename);
		fchmod(fileno(dst_stream), saved_stat.st_mode);

		printf("patching file %s\n", new_filename);

		/* Handle all hunks for this file */
		patch_line = xmalloc_fgets(patch_file);
		while (patch_line) {
			unsigned count;
			unsigned src_beg_line;
			unsigned hunk_offset_start;
			unsigned src_last_line = 1;
			unsigned dst_last_line = 1;

			if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3)
			 && (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dst_beg_line, &dst_last_line) < 2)
			) {
				/* No more hunks for this file */
				break;
			}
			if (plus != '+') {
				/* reverse patch */
				unsigned tmp = src_last_line;
				src_last_line = dst_last_line;
				dst_last_line = tmp;
				tmp = src_beg_line;
				src_beg_line = dst_beg_line;
				dst_beg_line = tmp;
			}
			hunk_count++;

			if (src_beg_line && dst_beg_line) {
				/* Copy unmodified lines upto start of hunk */
				/* src_beg_line will be 0 if it's a new file */
				count = src_beg_line - src_cur_line;
				if (copy_lines(src_stream, dst_stream, count)) {
					bb_error_msg_and_die("bad src file");
				}
				src_cur_line += count;
				dst_cur_line += count;
				copy_trailing_lines_flag = 1;
			}
			src_last_line += hunk_offset_start = src_cur_line;
			dst_last_line += dst_cur_line;

			while (1) {
				free(patch_line);
				patch_line = xmalloc_fgets(patch_file);
				if (patch_line == NULL)
					break; /* EOF */
				if ((*patch_line != '-') && (*patch_line != '+')
				 && (*patch_line != ' ')
				) {
					break; /* End of hunk */
				}
				if (*patch_line != plus) { /* '-' or ' ' */
					char *src_line = NULL;
					if (src_cur_line == src_last_line)
						break;
					if (src_stream) {
						src_line = xmalloc_fgets(src_stream);
						if (src_line) {
							int diff = strcmp(src_line, patch_line + 1);
							src_cur_line++;
							free(src_line);
							if (diff)
								src_line = NULL;
						}
					}
					if (!src_line) {
						bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start);
						bad_hunk_count++;
						break;
					}
					if (*patch_line != ' ') { /* '-' */
						continue;
					}
				}
				if (dst_cur_line == dst_last_line)
					break;
				fputs(patch_line + 1, dst_stream);
				dst_cur_line++;
			} /* end of while loop handling one hunk */
		} /* end of while loop handling one file */

		/* Cleanup last patched file */
		if (copy_trailing_lines_flag) {
			copy_lines(src_stream, dst_stream, (unsigned)(-1));
		}
		if (src_stream) {
			fclose(src_stream);
		}
		fclose(dst_stream);
		if (bad_hunk_count) {
			ret = 1;
			bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count);
		} else {
			/* It worked, we can remove the backup */
			if (backup_filename) {
				unlink(backup_filename);
			}
			if ((dst_cur_line == 0) || (dst_beg_line == 0)) {
				/* The new patched file is empty, remove it */
				xunlink(new_filename);
				// /* old_filename and new_filename may be the same file */
				// unlink(old_filename);
			}
		}
		free(backup_filename);
		//free(old_filename);
		free(new_filename);
	} /* end of "while there are patch lines" */
 quit:
	/* 0 = SUCCESS
	 * 1 = Some hunks failed
	 * 2 = More serious problems (exited earlier)
	 */
	return ret;
}
コード例 #10
0
ファイル: main_loop.c プロジェクト: SvenDowideit/clearlinux
/* execute the next command in command buffer; return error status */
static int exec_command( const char ** const ibufpp, const int prev_status,
                         const bool isglobal )
  {
  const char * fnp;
  int gflags = 0;
  int addr, c, n;
  const int addr_cnt = extract_addr_range( ibufpp );

  if( addr_cnt < 0 ) return ERR;
  *ibufpp = skip_blanks( *ibufpp );
  c = *(*ibufpp)++;
  switch( c )
    {
    case 'a': if( !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !append_lines( ibufpp, second_addr, isglobal ) ) return ERR;
              break;
    case 'c': if( first_addr == 0 ) first_addr = 1;
              if( second_addr == 0 ) second_addr = 1;
              if( !check_current_addr( addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !delete_lines( first_addr, second_addr, isglobal ) ||
                  !append_lines( ibufpp, current_addr(), isglobal ) ) return ERR;
              break;
    case 'd': if( !check_current_addr( addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !delete_lines( first_addr, second_addr, isglobal ) ) return ERR;
              inc_current_addr();
              break;
    case 'e': if( modified() && !scripted() && prev_status != EMOD )
                return EMOD;				/* fall through */
    case 'E': if( unexpected_address( addr_cnt ) ||
                  unexpected_command_suffix( **ibufpp ) ) return ERR;
              fnp = get_filename( ibufpp );
              if( !fnp || !delete_lines( 1, last_addr(), isglobal ) ||
                  !close_sbuf() ) return ERR;
              if( !open_sbuf() ) return FATAL;
              if( fnp[0] && fnp[0] != '!' ) set_def_filename( fnp );
              if( traditional() && !fnp[0] && !def_filename[0] )
                { set_error_msg( "No current filename" ); return ERR; }
              if( read_file( fnp[0] ? fnp : def_filename, 0 ) < 0 )
                return ERR;
              reset_undo_state(); set_modified( false );
              break;
    case 'f': if( unexpected_address( addr_cnt ) ||
                  unexpected_command_suffix( **ibufpp ) ) return ERR;
              fnp = get_filename( ibufpp );
              if( !fnp ) return ERR;
              if( fnp[0] == '!' )
                { set_error_msg( "Invalid redirection" ); return ERR; }
              if( fnp[0] ) set_def_filename( fnp );
              printf( "%s\n", strip_escapes( def_filename ) );
              break;
    case 'g':
    case 'v':
    case 'G':
    case 'V': if( isglobal )
                { set_error_msg( "Cannot nest global commands" ); return ERR; }
              n = ( c == 'g' || c == 'G' );	/* mark matching lines */
              if( !check_addr_range( 1, last_addr(), addr_cnt ) ||
                  !build_active_list( ibufpp, first_addr, second_addr, n ) )
                return ERR;
              n = ( c == 'G' || c == 'V' );		/* interactive */
              if( ( n && !get_command_suffix( ibufpp, &gflags ) ) ||
                  !exec_global( ibufpp, gflags, n ) )
                return ERR;
              break;
    case 'h':
    case 'H': if( unexpected_address( addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( c == 'H' ) verbose = !verbose;
              if( ( c == 'h' || verbose ) && errmsg[0] )
                fprintf( stderr, "%s\n", errmsg );
              break;
    case 'i': if( second_addr == 0 ) second_addr = 1;
              if( !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !append_lines( ibufpp, second_addr - 1, isglobal ) )
                return ERR;
              break;
    case 'j': if( !check_addr_range( current_addr(), current_addr() + 1, addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( first_addr != second_addr &&
                  !join_lines( first_addr, second_addr, isglobal ) ) return ERR;
              break;
    case 'k': n = *(*ibufpp)++;
              if( second_addr == 0 ) { invalid_address(); return ERR; }
              if( !get_command_suffix( ibufpp, &gflags ) ||
                  !mark_line_node( search_line_node( second_addr ), n ) )
                return ERR;
              break;
    case 'l':
    case 'n':
    case 'p': if( c == 'l' ) n = GLS; else if( c == 'n' ) n = GNP; else n = GPR;
              if( !check_current_addr( addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ||
                  !display_lines( first_addr, second_addr, gflags | n ) )
                return ERR;
              gflags = 0;
              break;
    case 'm': if( !check_current_addr( addr_cnt ) ||
                  !get_third_addr( ibufpp, &addr ) ) return ERR;
              if( addr >= first_addr && addr < second_addr )
                { set_error_msg( "Invalid destination" ); return ERR; }
              if( !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !move_lines( first_addr, second_addr, addr, isglobal ) )
                return ERR;
              break;
    case 'P':
    case 'q':
    case 'Q': if( unexpected_address( addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( c == 'P' ) prompt_on = !prompt_on;
              else if( modified() && !scripted() && c == 'q' &&
                       prev_status != EMOD ) return EMOD;
              else return QUIT;
              break;
    case 'r': if( unexpected_command_suffix( **ibufpp ) ) return ERR;
              if( addr_cnt == 0 ) second_addr = last_addr();
              fnp = get_filename( ibufpp );
              if( !fnp ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !def_filename[0] && fnp[0] != '!' ) set_def_filename( fnp );
              if( traditional() && !fnp[0] && !def_filename[0] )
                { set_error_msg( "No current filename" ); return ERR; }
              addr = read_file( fnp[0] ? fnp : def_filename, second_addr );
              if( addr < 0 ) return ERR;
              if( addr ) set_modified( true );
              break;
    case 's': if( !command_s( ibufpp, &gflags, addr_cnt, isglobal ) )
                return ERR;
              break;
    case 't': if( !check_current_addr( addr_cnt ) ||
                  !get_third_addr( ibufpp, &addr ) ||
                  !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !copy_lines( first_addr, second_addr, addr ) ) return ERR;
              break;
    case 'u': if( unexpected_address( addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ||
                  !undo( isglobal ) ) return ERR;
              break;
    case 'w':
    case 'W': n = **ibufpp;
              if( n == 'q' || n == 'Q' ) ++*ibufpp;
              if( unexpected_command_suffix( **ibufpp ) ) return ERR;
              fnp = get_filename( ibufpp );
              if( !fnp ) return ERR;
              if( addr_cnt == 0 && last_addr() == 0 )
                first_addr = second_addr = 0;
              else if( !check_addr_range( 1, last_addr(), addr_cnt ) )
                return ERR;
              if( !def_filename[0] && fnp[0] != '!' ) set_def_filename( fnp );
              if( traditional() && !fnp[0] && !def_filename[0] )
                { set_error_msg( "No current filename" ); return ERR; }
              addr = write_file( fnp[0] ? fnp : def_filename,
                     ( c == 'W' ) ? "a" : "w", first_addr, second_addr );
              if( addr < 0 ) return ERR;
              if( addr == last_addr() ) set_modified( false );
              else if( modified() && !scripted() && n == 'q' &&
                       prev_status != EMOD ) return EMOD;
              if( n == 'q' || n == 'Q' ) return QUIT;
              break;
    case 'x': if( second_addr < 0 || last_addr() < second_addr )
                { invalid_address(); return ERR; }
              if( !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              if( !isglobal ) clear_undo_stack();
              if( !put_lines( second_addr ) ) return ERR;
              break;
    case 'y': if( !check_current_addr( addr_cnt ) ||
                  !get_command_suffix( ibufpp, &gflags ) ||
                  !yank_lines( first_addr, second_addr ) ) return ERR;
              break;
    case 'z': first_addr = 1;
              if( !check_addr_range( first_addr, current_addr() +
                                     ( traditional() || !isglobal ), addr_cnt ) )
                return ERR;
              if( **ibufpp > '0' && **ibufpp <= '9' )
                { if( parse_int( &n, *ibufpp, ibufpp ) ) set_window_lines( n );
                  else return ERR; }
              if( !get_command_suffix( ibufpp, &gflags ) ||
                  !display_lines( second_addr, min( last_addr(), second_addr + window_lines() ),
                                  gflags ) )
                return ERR;
              gflags = 0;
              break;
    case '=': if( !get_command_suffix( ibufpp, &gflags ) ) return ERR;
              printf( "%d\n", addr_cnt ? second_addr : last_addr() );
              break;
    case '!': if( unexpected_address( addr_cnt ) ) return ERR;
              fnp = get_shell_command( ibufpp );
              if( !fnp ) return ERR;
              if( system( fnp + 1 ) < 0 )
                { set_error_msg( "Can't create shell process" ); return ERR; }
              if( !scripted() ) printf( "!\n" );
              break;
    case '\n': first_addr = 1;
              if( !check_addr_range( first_addr, current_addr() +
                                     ( traditional() || !isglobal ), addr_cnt ) ||
                  !display_lines( second_addr, second_addr, 0 ) )
                return ERR;
              break;
    case '#': while( *(*ibufpp)++ != '\n' ) ;
              break;
    default : set_error_msg( "Unknown command" ); return ERR;
    }
  if( gflags && !display_lines( current_addr(), current_addr(), gflags ) )
    return ERR;
  return 0;
  }