Beispiel #1
0
/* exec_global: apply command list in the command buffer to the active
   lines in a range; return command status */
int
exec_global(int interact, int gflag)
{
	static char *ocmd = NULL;
	static int ocmdsz = 0;

	line_t *lp = NULL;
	int status;
	int n;
	char *cmd = NULL;

	if (!interact) {
		if (!strcmp(ibufp, "\n"))
			cmd = "p\n";		/* null cmd-list == `p' */
		else if ((cmd = get_extended_line(&n, 0)) == NULL)
			return ERR;
	}
	clear_undo_stack();
	while ((lp = next_active_node()) != NULL) {
		if ((current_addr = get_line_node_addr(lp)) < 0)
			return ERR;
		if (interact) {
			/* print current_addr; get a command in global syntax */
			if (display_lines(current_addr, current_addr, gflag) < 0)
				return ERR;
			while ((n = get_tty_line()) > 0 &&
			    ibuf[n - 1] != '\n')
				clearerr(stdin);
			if (n < 0)
				return ERR;
			else if (n == 0) {
				seterrmsg("unexpected end-of-file");
				return ERR;
			} else if (n == 1 && !strcmp(ibuf, "\n"))
				continue;
			else if (n == 2 && !strcmp(ibuf, "&\n")) {
				if (cmd == NULL) {
					seterrmsg("no previous command");
					return ERR;
				} else cmd = ocmd;
			} else if ((cmd = get_extended_line(&n, 0)) == NULL)
				return ERR;
			else {
				REALLOC(ocmd, ocmdsz, n + 1, ERR);
				memcpy(ocmd, cmd, n + 1);
				cmd = ocmd;
			}

		}
		ibufp = cmd;
		for (; *ibufp;)
			if ((status = extract_addr_range()) < 0 ||
			    (status = exec_command()) < 0 ||
			    (status > 0 && (status = display_lines(
			    current_addr, current_addr, status)) < 0))
				return status;
	}
	return 0;
}
Beispiel #2
0
static bool command_s( const char ** const ibufpp, int * const gflagsp,
                       const int addr_cnt, const bool isglobal )
  {
  static int gflags = 0;
  static int snum = 0;
  enum Sflags {
    SGG = 0x01,		/* complement previous global substitute suffix */
    SGP = 0x02,		/* complement previous print suffix */
    SGR = 0x04,		/* use last regex instead of last pat */
    SGF = 0x08		/* repeat last substitution */
    } sflags = 0;

  do {
    if( isdigit( (unsigned char)**ibufpp ) )
      {
      if( !parse_int( &snum, *ibufpp, ibufpp ) ) return false;
      sflags |= SGF; gflags &= ~GSG;		/* override GSG */
      }
    else switch( **ibufpp )
      {
      case '\n':sflags |= SGF; break;
      case 'g': sflags |= SGG; ++*ibufpp; break;
      case 'p': sflags |= SGP; ++*ibufpp; break;
      case 'r': sflags |= SGR; ++*ibufpp; break;
      default : if( sflags )
                  { set_error_msg( "Invalid command suffix" ); return false; }
      }
    }
  while( sflags && **ibufpp != '\n' );
  if( sflags && !prev_pattern() )
    { set_error_msg( "No previous substitution" ); return false; }
  if( sflags & SGG ) snum = 0;			/* override numeric arg */
  if( **ibufpp != '\n' && (*ibufpp)[1] == '\n' )
    { set_error_msg( "Invalid pattern delimiter" ); return false; }
  if( ( !sflags || ( sflags & SGR ) ) && !new_compiled_pattern( ibufpp ) )
    return false;
  if( !sflags && !extract_subst_tail( ibufpp, &gflags, &snum, isglobal ) )
    return false;
  if( isglobal ) gflags |= GLB;
  else gflags &= ~GLB;
  if( sflags & SGG ) gflags ^= GSG;
  if( sflags & SGP ) { gflags ^= GPR; gflags &= ~( GLS | GNP ); }
  switch( **ibufpp )
    {
    case 'l': gflags |= GLS; ++*ibufpp; break;
    case 'n': gflags |= GNP; ++*ibufpp; break;
    case 'p': gflags |= GPR; ++*ibufpp; break;
    }
  if( !check_current_addr( addr_cnt ) ||
      !get_command_suffix( ibufpp, gflagsp ) ) return false;
  if( !isglobal ) clear_undo_stack();
  if( !search_and_replace( first_addr, second_addr, gflags, snum, isglobal ) )
    return false;
  if( ( gflags & ( GPR | GLS | GNP ) ) &&
      !display_lines( current_addr(), current_addr(), gflags ) )
    return false;
  return true;
  }
Beispiel #3
0
/* apply command list in the command buffer to the active lines in a
   range; return false if error */
static bool exec_global( const char ** const ibufpp, const int gflags,
                         const bool interactive )
  {
  static char * buf = 0;
  static int bufsz = 0;
  const char * cmd = 0;

  if( !interactive )
    {
    if( traditional() && !strcmp( *ibufpp, "\n" ) )
      cmd = "p\n";			/* null cmd_list == 'p' */
    else
      {
      if( !get_extended_line( ibufpp, 0, false ) ) return false;
      cmd = *ibufpp;
      }
    }
  clear_undo_stack();
  while( true )
    {
    const line_t * const lp = next_active_node();
    if( !lp ) break;
    set_current_addr( get_line_node_addr( lp ) );
    if( current_addr() < 0 ) return false;
    if( interactive )
      {
      /* print current_addr; get a command in global syntax */
      int len;
      if( !display_lines( current_addr(), current_addr(), gflags ) )
        return false;
      do { *ibufpp = get_tty_line( &len ); }
      while( *ibufpp && len > 0 && (*ibufpp)[len-1] != '\n' );
      if( !*ibufpp ) return false;
      if( len == 0 )
        { set_error_msg( "Unexpected end-of-file" ); return false; }
      if( len == 1 && !strcmp( *ibufpp, "\n" ) ) continue;
      if( len == 2 && !strcmp( *ibufpp, "&\n" ) )
        { if( !cmd ) { set_error_msg( "No previous command" ); return false; } }
      else
        {
        if( !get_extended_line( ibufpp, &len, false ) ||
            !resize_buffer( &buf, &bufsz, len + 1 ) ) return false;
        memcpy( buf, *ibufpp, len + 1 );
        cmd = buf;
        }
      }
    *ibufpp = cmd;
    while( **ibufpp ) if( exec_command( ibufpp, 0, true ) < 0 ) return false;
    }
  return true;
  }
Beispiel #4
0
/* search_and_replace: for each line in a range, change text matching a pattern
   according to a substitution template; return status  */
int
search_and_replace(pattern_t *pat, int gflag, int kth)
{
	undo_t *up;
	const char *txt;
	const char *eot;
	long lc;
	long xa = current_addr;
	int nsubs = 0;
	line_t *lp;
	int len;

	current_addr = first_addr - 1;
	for (lc = 0; lc <= second_addr - first_addr; lc++) {
		lp = get_addressed_line_node(++current_addr);
		if ((len = substitute_matching_text(pat, lp, gflag, kth)) < 0)
			return ERR;
		else if (len) {
			up = NULL;
			if (delete_lines(current_addr, current_addr) < 0)
				return ERR;
			txt = rbuf;
			eot = rbuf + len;
			SPL1();
			do {
				if ((txt = put_sbuf_line(txt)) == NULL) {
					SPL0();
					return ERR;
				} else if (up)
					up->t = get_addressed_line_node(current_addr);
				else if ((up = push_undo_stack(UADD,
				    current_addr, current_addr)) == NULL) {
					SPL0();
					return ERR;
				}
			} while (txt != eot);
			SPL0();
			nsubs++;
			xa = current_addr;
		}
	}
	current_addr = xa;
	if  (nsubs == 0 && !(gflag & GLB)) {
		errmsg = "no match";
		return ERR;
	} else if ((gflag & (GPR | GLS | GNP)) &&
	    display_lines(current_addr, current_addr, gflag) < 0)
		return ERR;
	return 0;
}
Beispiel #5
0
/*
**	page_up
*/
STATUS
page_up()
{
    STATUS                 ret_val = OK ;
    char                   junk ;

    if (myPages == NULL || myPages->previous == NULL)
	disp_prompt(ERx("TOF reached"),&junk,NULL);
    else
    {
	myPages = myPages->previous;
	SIfseek(diffPtr, myPages->file_pos, SI_P_START);
	display_lines();
    }

    return (ret_val);
}
Beispiel #6
0
STATUS
page_down(i4 update)
{
    struct page_chain     *newpage = NULL ;
    char                   junk ;

    if ( (myPages) && (myPages->final_page) )
    {
	disp_prompt(ERx("EOF reached"),&junk,NULL);
	return(OK);
    }
    if ( (myPages == NULL) || (myPages->next == NULL) )
    {
	newpage = (struct page_chain *)
		   SEP_MEalloc(SEP_ME_TAG_PAGES, sizeof(struct page_chain),
			       TRUE, (STATUS *) NULL);

	newpage->file_pos = SIftell(diffPtr );
	newpage->final_page = FALSE;
	newpage->next = NULL;
	if (myPages)
        {
	    newpage->previous = myPages;
	    myPages->next = newpage;
	}
	else
	    newpage->previous = NULL;

	myPages = newpage;
    }
    else
	myPages = myPages->next;

    TDerase(diffW);
    return(display_lines());
} /* page_down */
Beispiel #7
0
int main(int argc, char** argv) {
    analyseArgs(argc, argv);
    read_file(opt_path_v[0]);
    display_lines(opt_path_v[0], nb_lines_wanted);
    return 0;
}
Beispiel #8
0
int display_shape(struct Map_info *Map, int type, struct cat_list *Clist, const struct Cell_head *window, 
		  const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat,
		  const char *icon, double size, const char *size_column, int sqrt_flag, const char *rot_column, /* lines only */
		  int id_flag, int cats_colors_flag, char *rgb_column,
		  int default_width, char *width_column, double width_scale,
		  char *z_style)
{
    int open_db, field, i, stat;
    dbCatValArray cvarr_rgb, cvarr_width, cvarr_size, cvarr_rot;
    struct field_info *fi;
    dbDriver *driver;
    int nrec_rgb, nrec_width, nrec_size, nrec_rot, have_colors;
    struct Colors colors, zcolors;
    struct bound_box box;
    
    stat = 0;
    nrec_rgb = nrec_width = nrec_size = nrec_rot = 0;
    
    open_db = rgb_column || width_column || size_column || rot_column;
    if (open_db) {
	field = Clist->field > 0 ? Clist->field : 1;
	fi = Vect_get_field(Map, field);
	if (!fi) {
	    G_fatal_error(_("Database connection not defined for layer %d"),
			  field);
	}
	
	driver = db_start_driver_open_database(fi->driver, fi->database);
	if (!driver)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  fi->database, fi->driver);
        db_set_error_handler_driver(driver);
    }
    
    /* fisrt search for color table */
    have_colors = Vect_read_colors(Vect_get_name(Map), Vect_get_mapset(Map),
				   &colors);
    if (have_colors && rgb_column) {
        G_warning(_("Both color table and <%s> option detected. "
                    "Color table will ignored."), "rgb_column");
        have_colors = FALSE;
    }

    if (rgb_column) {
	/* read RRR:GGG:BBB color strings from table */
	db_CatValArray_init(&cvarr_rgb);
	
	nrec_rgb = db_select_CatValArray(driver, fi->table, fi->key,
					 rgb_column, NULL, &cvarr_rgb);
	
	G_debug(3, "nrec_rgb (%s) = %d", rgb_column, nrec_rgb);
	    
	if (cvarr_rgb.ctype != DB_C_TYPE_STRING) {
	    G_warning(_("Color definition column ('%s') not a string. "
			"Column must be of form 'RRR:GGG:BBB' where RGB values range 0-255. "
			"You can use '%s' module to define color rules. "
			"Unable to colorize features."),
		      rgb_column, "v.colors");
            rgb_column = NULL;
        }
	else {
	    if (nrec_rgb < 0)
		G_fatal_error(_("Unable to select data ('%s') from table"),
			      rgb_column);
	    
	    G_debug(2, "\n%d records selected from table", nrec_rgb);
	}
    }
    if (width_column) {
	if (*width_column == '\0')
	    G_fatal_error(_("Line width column not specified"));

	db_CatValArray_init(&cvarr_width);

	nrec_width = db_select_CatValArray(driver, fi->table, fi->key,
					   width_column, NULL, &cvarr_width);

	G_debug(3, "nrec_width (%s) = %d", width_column, nrec_width);

	if (cvarr_width.ctype != DB_C_TYPE_INT &&
	    cvarr_width.ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Line width column ('%s') not a number"),
			  width_column);

	if (nrec_width < 0)
	    G_fatal_error(_("Unable to select data ('%s') from table"),
			  width_column);

	G_debug(2, "\n%d records selected from table", nrec_width);

	for (i = 0; i < cvarr_width.n_values; i++) {
	    G_debug(4, "cat = %d  %s = %d", cvarr_width.value[i].cat,
		    width_column,
		    (cvarr_width.ctype ==
		     DB_C_TYPE_INT ? cvarr_width.value[i].val.
		     i : (int)cvarr_width.value[i].val.d));
	}
    }

    if (size_column) {
	if (*size_column == '\0')
	    G_fatal_error(_("Symbol size column not specified"));
	
	db_CatValArray_init(&cvarr_size);

	nrec_size = db_select_CatValArray(driver, fi->table, fi->key,
					  size_column, NULL, &cvarr_size);
	
	G_debug(3, "nrec_size (%s) = %d", size_column, nrec_size);

	if (cvarr_size.ctype != DB_C_TYPE_INT &&
	    cvarr_size.ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Symbol size column ('%s') is not numeric"),
			  size_column);

	if (nrec_size < 0)
	    G_fatal_error(_("Unable to select data ('%s') from table"),
			  size_column);

	G_debug(2, " %d records selected from table", nrec_size);

	for (i = 0; i < cvarr_size.n_values; i++) {
	    G_debug(4, "(size) cat = %d  %s = %.2f", cvarr_size.value[i].cat,
		    size_column,
		    (cvarr_size.ctype ==
		     DB_C_TYPE_INT ? (double)cvarr_size.value[i].val.i
		     : cvarr_size.value[i].val.d));
	}
    }

    if (rot_column) {
	if (*rot_column == '\0')
	    G_fatal_error(_("Symbol rotation column not specified"));

	db_CatValArray_init(&cvarr_rot);

	nrec_rot = db_select_CatValArray(driver, fi->table, fi->key,
					 rot_column, NULL, &cvarr_rot);

	G_debug(3, "nrec_rot (%s) = %d", rot_column, nrec_rot);

	if (cvarr_rot.ctype != DB_C_TYPE_INT &&
	    cvarr_rot.ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Symbol rotation column ('%s') is not numeric"),
			  rot_column);

	if (nrec_rot < 0)
	    G_fatal_error(_("Unable to select data ('%s') from table"),
			  rot_column);

	G_debug(2, " %d records selected from table", nrec_rot);

	for (i = 0; i < cvarr_rot.n_values; i++) {
	    G_debug(4, "(rot) cat = %d  %s = %.2f", cvarr_rot.value[i].cat,
		    rot_column,
		    (cvarr_rot.ctype ==
		     DB_C_TYPE_INT ? (double)cvarr_rot.value[i].val.i
		     : cvarr_rot.value[i].val.d));
	}
    }

    if (open_db) {
	db_close_database_shutdown_driver(driver);
    }

    if (z_style) {
	if (!Vect_is_3d(Map)) {
	    G_warning(_("Vector map is not 3D. Unable to colorize features based on z-coordinates."));
	    z_style = NULL;
	}
        else if (rgb_column) {
            G_warning(_("%s= and %s= are mutually exclusive. "
                        "%s= will be ignored."), "zcolor", "rgb_column", "zcolor");
	    z_style = NULL;
        }
	else {
	    Vect_get_map_box(Map, &box);
	    Rast_make_fp_colors(&zcolors, z_style, box.B, box.T);
	}
    }

    stat = 0;
    if (type & GV_AREA && Vect_get_num_primitives(Map, GV_CENTROID | GV_BOUNDARY) > 0)
	stat += display_area(Map, Clist, window, 
			     bcolor, fcolor, chcat,
			     id_flag, cats_colors_flag,
			     default_width, width_scale,
			     z_style ? &zcolors : NULL,
			     rgb_column ? &cvarr_rgb : NULL,
			     have_colors ? &colors : NULL,
			     &cvarr_width, nrec_width);
    
    stat += display_lines(Map, type, Clist,
			  bcolor, fcolor, chcat,
			  icon, size, sqrt_flag,
			  id_flag, cats_colors_flag,
			  default_width, width_scale,
			  z_style ? &zcolors : NULL,
			  rgb_column ? &cvarr_rgb : NULL,
			  have_colors ? &colors : NULL,
			  &cvarr_width, nrec_width,
			  &cvarr_size, nrec_size,
			  &cvarr_rot, nrec_rot);
    
    return stat;
}
Beispiel #9
0
Datei: glbl.c Projekt: slewsys/ed
/*
 * exec_global: Apply command list to lines in a range in global
 *   queue. Return command status.
 */
int
exec_global (ed_buffer_t *ed)
{
  static char *gcb = NULL;      /* global command buffer */
  static size_t gcb_size = 0;   /* buffer size */

  ed_line_node_t *lp = NULL;
  size_t len;
  int first_time = 1;
  int interactive = ed->exec->global & GLBI;
  int saved_io_f = ed->display->io_f;
  int status;

  reset_undo_queue (ed);

  /*
   * If non-interactive, read command before entering loop in the
   * event of empty global queue.
   */
  if (!interactive && !(ed->input = get_extended_line (&len, 0, 1, ed)))
    {
      status = ERR;
      clearerr (stdin);
      return status;
    }

  /* Empty command list equivalent to `p' command per SUSv4. */
  if (strlen (ed->input) == 1 && *ed->input == '\n')
    ed->input = "p\n";

  for (ed->exec->first_pass = 1; (lp = next_global_node (ed));
       ed->input = gcb, ed->exec->first_pass = 0)
    {
      if ((status = get_line_node_address (lp, &ed->state->dot, ed)) < 0)
        return status;

      else if (interactive)
        {
          ed->display->io_f = PRNT;
          if ((status = display_lines (ed->state->dot,
                                       ed->state->dot, ed)) < 0)
            return status;
          else if (!(ed->input = get_stdin_line (&len, ed))
                   || !(ed->input = get_extended_line (&len, 0, 1, ed)))
            {
              /* For an interactive global command, permit EOF to cancel. */
              status = feof (stdin) ? 0 : ERR;
              clearerr (stdin);
              return status;
            }
        }

      /* Global non-interactive command already set. */
      if (ed->input == gcb)
        ;

      /* Skip to next line */
      else if (len == 1 && interactive)
        continue;

      /* Repeat previous command. */
      else if (len == 2 && *ed->input == '&' && interactive)
        {
          if (first_time)
            {
              ed->exec->err = _("No previous command");
              return ERR;
            }
        }
      else
        {
          /* get_extended_line () isn't reentrant, so save ed->input. */
          REALLOC_THROW (gcb, gcb_size, len + 1, ERR, ed);

          /* Assert: ed->input is NUL-terminated! */
          strcpy (gcb, ed->input);
          first_time = 0;
        }
      for (ed->input = gcb; *ed->input;)
        if ((status = address_range (ed)) < 0
            || (status = exec_command (ed)) < 0
            || ((ed->display->io_f = status) > 0
                && (status = display_lines (ed->state->dot,
                                            ed->state->dot, ed)) < 0))
          return status;
    }
  return saved_io_f;
}
Beispiel #10
0
/* 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;
  }
Beispiel #11
0
/*
 * forward -- display the file, from an offset, forward.
 *
 * There are eight separate cases for this -- regular and non-regular
 * files, by bytes or lines and from the beginning or end of the file.
 *
 * FBYTES	byte offset from the beginning of the file
 *	REG	seek
 *	NOREG	read, counting bytes
 *
 * FLINES	line offset from the beginning of the file
 *	REG	read, counting lines
 *	NOREG	read, counting lines
 *
 * RBYTES	byte offset from the end of the file
 *	REG	seek
 *	NOREG	cyclically read characters into a wrap-around buffer
 *
 * RLINES
 *	REG	mmap the file and step back until reach the correct offset.
 *	NOREG	cyclically read lines into a wrap-around array of buffers
 */
void
forward(FILE *fp, enum STYLE style, off_t off, struct stat *sbp)
{
	int ch;

	switch(style) {
	case FBYTES:
		if (off == 0)
			break;
		if (S_ISREG(sbp->st_mode)) {
			if (sbp->st_size < off)
				off = sbp->st_size;
			if (fseeko(fp, off, SEEK_SET) == -1) {
				ierr();
				return;
			}
		} else while (off--)
			if ((ch = getc(fp)) == EOF) {
				if (ferror(fp)) {
					ierr();
					return;
				}
				break;
			}
		break;
	case FLINES:
		if (off == 0)
			break;
		for (;;) {
			if ((ch = getc(fp)) == EOF) {
				if (ferror(fp)) {
					ierr();
					return;
				}
				break;
			}
			if (ch == '\n' && !--off)
				break;
		}
		break;
	case RBYTES:
		if (S_ISREG(sbp->st_mode)) {
			if (sbp->st_size >= off &&
			    fseeko(fp, -off, SEEK_END) == -1) {
				ierr();
				return;
			}
		} else if (off == 0) {
			while (getc(fp) != EOF);
			if (ferror(fp)) {
				ierr();
				return;
			}
		} else
			if (display_bytes(fp, off))
				return;
		break;
	case RLINES:
		if (S_ISREG(sbp->st_mode))
			if (!off) {
				if (fseeko(fp, (off_t)0, SEEK_END) == -1) {
					ierr();
					return;
				}
			} else
				rlines(fp, off, sbp);
		else if (off == 0) {
			while (getc(fp) != EOF);
			if (ferror(fp)) {
				ierr();
				return;
			}
		} else
			if (display_lines(fp, off))
				return;
		break;
	case REVERSE:
		errx(1, "internal error: forward style cannot be REVERSE");
		/* NOTREACHED */
	}

	while ((ch = getc(fp)) != EOF) {
		if (putchar(ch) == EOF)
			oerr();
	}
	if (ferror(fp)) {
		ierr();
		return;
	}
	fflush(stdout);
}