/* 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; }
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; }
/* 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; }
/* 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; }
/* ** 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); }
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 */
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; }
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; }
/* * 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; }
/* 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; }
/* * 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); }