Пример #1
0
Файл: blob.c Проект: gvx/deja
Error setbyte_blob_(Stack *S, Stack *scope_arr)
{
	require(3);
	V blob = popS();
	V index = popS();
	V value = popS();
	Error e = Nothing;
	if (getType(blob) != T_BLOB || getType(index) != T_NUM || getType(value) != T_NUM)
	{
		e = TypeError;
		goto cleanup;
	}
	int num = toNumber(value);
	if (num < 0 || num > 255)
	{
		set_error_msg("Value not in range [0,255]");
		e = ValueError;
		goto cleanup;
	}
	int byte = setbyte_blob(blob, toNumber(index), num);
	if (byte < 0)
	{
		set_error_msg("Index out of range");
		e = ValueError;
		goto cleanup;
	}
	cleanup:
	clear_ref(blob);
	clear_ref(index);
	clear_ref(value);
	return e;
}
Пример #2
0
/* copy a pattern string from the command buffer; return pointer to the copy */
static char *extract_pattern( const char **ibufpp, const int delimiter )
  {
  static char *buf = 0;
  static int bufsz = 0;
  const char *nd = *ibufpp;
  int len;

  while( *nd != delimiter && *nd != '\n' )
    {
    if( *nd == '[' )
      {
      nd = parse_char_class( ++nd );
      if( !nd ) { set_error_msg( "Unbalanced brackets ([])" ); return 0; }
      }
    else if( *nd == '\\' && *++nd == '\n' )
      { set_error_msg( "Trailing backslash (\\)" ); return 0; }
    ++nd;
    }
  len = nd - *ibufpp;
  if( !resize_buffer( &buf, &bufsz, len + 1 ) ) return 0;
  memcpy( buf, *ibufpp, len );
  buf[len] = 0;
  *ibufpp = nd;
  if( isbinary() ) nul_to_newline( buf, len );
  return buf;
  }
Пример #3
0
/* get a line of text from the scratch file; return pointer to the text */
char * get_sbuf_line( const line_t * const lp )
  {
  static char * buf = 0;
  static int bufsz = 0;
  int len;

  if( lp == &buffer_head ) return 0;
  seek_write = true;			/* force seek on write */
  /* out of position */
  if( sfpos != lp->pos )
    {
    sfpos = lp->pos;
    if( fseek( sfp, sfpos, SEEK_SET ) != 0 )
      {
      show_strerror( 0, errno );
      set_error_msg( "Cannot seek temp file" );
      return 0;
      }
    }
  len = lp->len;
  if( !resize_buffer( &buf, &bufsz, len + 1 ) ) return 0;
  if( (int)fread( buf, 1, len, sfp ) != len )
    {
    show_strerror( 0, errno );
    set_error_msg( "Cannot read temp file" );
    return 0;
    }
  sfpos += len;		/* update file position */
  buf[len] = 0;
  return buf;
  }
Пример #4
0
/* return pointer to compiled pattern from command buffer */
static regex_t *get_compiled_pattern( const char **ibufpp )
  {
  static regex_t *exp = 0;
  char *exps;
  const char delimiter = **ibufpp;
  int n;

  if( delimiter == ' ' )
    { set_error_msg( "Invalid pattern delimiter" ); return 0; }
  if( delimiter == '\n' || *++(*ibufpp) == '\n' || **ibufpp == delimiter )
    {
    if( !exp ) set_error_msg( "No previous pattern" );
    return exp;
    }
  if( !( exps = extract_pattern( ibufpp, delimiter ) ) ) return 0;
  /* buffer alloc'd && not reserved */
  if( exp && !patlock ) regfree( exp );
  else if( !( exp = ( regex_t *) malloc( sizeof( regex_t ) ) ) )
    {
    show_strerror( 0, errno );
    set_error_msg( "Memory exhausted" );
    return 0;
    }
  patlock = 0;
  n = regcomp( exp, exps, 0 );
  if( n )
    {
    char buf[80];
    regerror( n, exp, buf, sizeof( buf ) );
    set_error_msg( buf );
    free( exp );
    exp = 0;
    }
  return exp;
  }
Пример #5
0
/* Return pointer to copy of filename in the command buffer */
static const char * get_filename( const char ** const ibufpp )
  {
  static char * buf = 0;
  static int bufsz = 0;
  const int pmax = path_max( 0 );
  int n;

  *ibufpp = skip_blanks( *ibufpp );
  if( **ibufpp != '\n' )
    {
    int size = 0;
    if( !get_extended_line( ibufpp, &size, true ) ) return 0;
    if( **ibufpp == '!' )
      {
      ++*ibufpp;
      return get_shell_command( ibufpp );
      }
    else if( size > pmax )
      { set_error_msg( "Filename too long" ); return 0; }
    }
  else if( !traditional() && !def_filename[0] )
    { set_error_msg( "No current filename" ); return 0; }
  if( !resize_buffer( &buf, &bufsz, pmax + 1 ) ) return 0;
  for( n = 0; **ibufpp != '\n'; ++n, ++*ibufpp ) buf[n] = **ibufpp;
  buf[n] = 0;
  while( **ibufpp == '\n' ) ++*ibufpp;			/* skip newline */
  return ( may_access_filename( buf ) ? buf : 0 );
  }
Пример #6
0
/* write a line of text to the scratch file and add a line node to the
   editor buffer; return a pointer to the end of the text */
const char * put_sbuf_line( const char * const buf, const int size,
                            const int addr )
  {
  line_t * const lp = dup_line_node( 0 );
  const char * const p = (const char *) memchr( buf, '\n', size );
  int len;

  if( !lp ) return 0;
  if( !p ) { set_error_msg( "Line too long" ); return 0; }
  len = p - buf;
  /* out of position */
  if( seek_write )
    {
    if( fseek( sfp, 0L, SEEK_END ) != 0 )
      {
      show_strerror( 0, errno );
      set_error_msg( "Cannot seek temp file" );
      return 0;
      }
    sfpos = ftell( sfp );
    seek_write = false;
    }
  if( (int)fwrite( buf, 1, len, sfp ) != len )	/* assert: interrupts disabled */
    {
    sfpos = -1;
    show_strerror( 0, errno );
    set_error_msg( "Cannot write temp file" );
    return 0;
    }
  lp->pos = sfpos; lp->len = len;
  add_line_node( lp, addr );
  ++current_addr_;
  sfpos += len;				/* update file position */
  return p + 1;
  }
Пример #7
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;
  }
Пример #8
0
/* Return pointer to copy of shell command in the command buffer */
static const char * get_shell_command( const char ** const ibufpp )
  {
  static char * buf = 0;
  static int bufsz = 0;
  static char * shcmd = 0;		/* shell command buffer */
  static int shcmdsz = 0;		/* shell command buffer size */
  static int shcmdlen = 0;		/* shell command length */
  const char * p;			/* substitution char pointer */
  int i = 0, len;

  if( restricted() ) { set_error_msg( "Shell access restricted" ); return 0; }
  if( !get_extended_line( ibufpp, &len, true ) ) return 0;
  p = *ibufpp;
  if( !resize_buffer( &buf, &bufsz, len + 1 ) ) return 0;
  buf[i++] = '!';			/* prefix command w/ bang */
  while( **ibufpp != '\n' )
    {
    if( **ibufpp == '!' )
      {
      if( p != *ibufpp )
        {
        if( !resize_buffer( &buf, &bufsz, i + 1 ) ) return 0;
        buf[i++] = *(*ibufpp)++;
        }
      else if( !shcmd || ( traditional() && !*( shcmd + 1 ) ) )
        { set_error_msg( "No previous command" ); return 0; }
      else
        {
        if( !resize_buffer( &buf, &bufsz, i + shcmdlen ) ) return 0;
        for( p = shcmd + 1; p < shcmd + shcmdlen; ) buf[i++] = *p++;
        p = (*ibufpp)++;
        }
      }
    else if( **ibufpp == '%' )
      {
      if( !def_filename[0] )
        { set_error_msg( "No current filename" ); return 0; }
      p = strip_escapes( def_filename );
      len = strlen( p );
      if( !resize_buffer( &buf, &bufsz, i + len ) ) return 0;
      while( len-- ) buf[i++] = *p++;
      p = (*ibufpp)++;
      }
    else
      {
      if( !resize_buffer( &buf, &bufsz, i + 2 ) ) return 0;
      buf[i++] = **ibufpp;
      if( *(*ibufpp)++ == '\\' ) buf[i++] = *(*ibufpp)++;
      }
    }
  while( **ibufpp == '\n' ) ++*ibufpp;			/* skip newline */
  if( !resize_buffer( &shcmd, &shcmdsz, i + 1 ) ) return 0;
  memcpy( shcmd, buf, i );
  shcmdlen = i; shcmd[i] = 0;
  if( *p == '!' || *p == '%' ) printf( "%s\n", shcmd + 1 );
  return shcmd;
  }
Пример #9
0
void abstract_interpreter::check_branch_target(Oop p) {
  if (! SmiLayout().hasMyTag(p)) {
    set_error_msg( "branch target must be smallInt");
  }
  else if (   0 <= SmiLayout().valueOf(p)
           &&      SmiLayout().valueOf(p) <= mi.length_codes ) { // == length_codes means return
  }
  else {
    set_error_msg( "bad branch target");
  }
}
Пример #10
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;
  }
Пример #11
0
/* for each line in a range, change text matching a pattern according to
   a substitution template; return false if error */
char search_and_replace( const int first_addr, const int second_addr,
                         const int gflags, const int snum, const char isglobal )
  {
  int lc;
  char match_found = 0;

  set_current_addr( first_addr - 1 );
  for( lc = 0; lc <= second_addr - first_addr; ++lc )
    {
    line_t *lp = search_line_node( inc_current_addr() );
    int len = replace_matching_text( lp, gflags, snum );
    if( len < 0 ) return 0;
    if( len )
      {
      const char *txt = rbuf;
      const char *eot = rbuf + len;
      undo_t *up = 0;
      disable_interrupts();
      if( !delete_lines( current_addr(), current_addr(), isglobal ) ) return 0;
      do {
        txt = put_sbuf_line( txt, current_addr() );
        if( !txt ) { enable_interrupts(); return 0; }
        if( up ) up->tail = search_line_node( current_addr() );
        else if( !( up = push_undo_atom( UADD, -1, -1 ) ) )
          { enable_interrupts(); return 0; }
        }
      while( txt != eot );
      enable_interrupts();
      match_found = 1;
      }
    }
  if( !match_found && !( gflags & GLB ) )
    { set_error_msg( "No match" ); return 0; }
  return 1;
  }
Пример #12
0
/* append lines from the yank buffer */
bool put_lines( const int addr )
  {
  undo_t * up = 0;
  line_t *p, *lp = yank_buffer_head.q_forw;

  if( lp == &yank_buffer_head )
    { set_error_msg( "Nothing to put" ); return false; }
  current_addr_ = addr;
  while( lp != &yank_buffer_head )
    {
    disable_interrupts();
    p = dup_line_node( lp );
    if( !p ) { enable_interrupts(); return false; }
    add_line_node( p, current_addr_++ );
    if( up ) up->tail = p;
    else
      {
      up = push_undo_atom( UADD, current_addr_, current_addr_ );
      if( !up ) { enable_interrupts(); return false; }
      }
    modified_ = true;
    lp = lp->q_forw;
    enable_interrupts();
    }
  return true;
  }
Пример #13
0
/* return address of a marked line */
static int get_marked_node_addr( int c )
  {
  c -= 'a';
  if( c < 0 || c >= 26 )
    { set_error_msg( "Invalid mark character" ); return -1; }
  return get_line_node_addr( mark[c]);
  }
Пример #14
0
/* return pointer to copy of substitution template in the command buffer */
static char *extract_subst_template( const char **ibufpp, const char isglobal )
  {
  int i = 0, n = 0;
  char c;
  const char delimiter = **ibufpp;

  ++(*ibufpp);
  if( **ibufpp == '%' && (*ibufpp)[1] == delimiter )
    {
    ++(*ibufpp);
    if( !stbuf ) set_error_msg( "No previous substitution" );
    return stbuf;
    }
  while( **ibufpp != delimiter )
    {
    if( !resize_buffer( &stbuf, &stbufsz, i + 2 ) ) return 0;
    c = stbuf[i++] = *(*ibufpp)++;
    if( c == '\n' && **ibufpp == 0 ) { --i, --(*ibufpp); break; }
    if( c == '\\' && ( stbuf[i++] = *(*ibufpp)++ ) == '\n' && !isglobal )
      {
      while( ( *ibufpp = get_tty_line( &n ) ) &&
             ( n == 0 || ( n > 0 && (*ibufpp)[n-1] != '\n' ) ) )
        clearerr( stdin );
      if( !(*ibufpp) ) return 0;
      }
    }
  if( !resize_buffer( &stbuf, &stbufsz, i + 1 ) ) return 0;
  stbuf[stlen = i] = 0;
  return stbuf;
  }
Пример #15
0
char may_access_filename( const char *name )
  {
  if( restricted_ && ( *name == '!' || !strcmp( name, ".." ) || strchr( name, '/' ) ) )
    {
    set_error_msg( "Shell access restricted" );
    return 0;
    }
  return 1;
  }
Пример #16
0
static bool mark_line_node( const line_t * const lp, int c )
  {
  c -= 'a';
  if( c < 0 || c >= 26 )
    { set_error_msg( "Invalid mark character" ); return false; }
  if( !mark[c] ) ++markno;
  mark[c] = lp;
  return true;
  }
Пример #17
0
/* return line number of pointer */
int get_line_node_addr( const line_t * const lp )
  {
  const line_t * p = &buffer_head;
  int addr = 0;

  while( p != lp && ( p = p->q_forw ) != &buffer_head ) ++addr;
  if( addr && p == &buffer_head )
    { set_error_msg( "Invalid address" ); return -1; }
  return addr;
  }
Пример #18
0
bool SkypeLowIoImpl::send( const std::string & s )
{
    MUTEX_SCOPE_LOCK( mutex_ );

    if( !is_inited__() )
    {
        set_error_msg( "SkypeLowIoImpl: not initialized" );
        throw std::runtime_error( "SkypeLowIoImpl: not initialized" );
    }

    return send__( s );
}
Пример #19
0
/* return a pointer to a copy of a line node, or to a new node if lp == 0 */
static line_t * dup_line_node( line_t * const lp )
  {
  line_t * const p = (line_t *) malloc( sizeof (line_t) );
  if( !p )
    {
    show_strerror( 0, errno );
    set_error_msg( "Memory exhausted" );
    return 0;
    }
  if( lp ) { p->pos = lp->pos; p->len = lp->len; }
  return p;
  }
Пример #20
0
/* open scratch file */
bool open_sbuf( void )
  {
  isbinary_ = newline_added_ = false;
  sfp = tmpfile();
  if( !sfp )
    {
    show_strerror( 0, errno );
    set_error_msg( "Cannot open temp file" );
    return false;
    }
  return true;
  }
Пример #21
0
/* convert a string to int with out_of_range detection */
bool parse_int( int * const i, const char * const str, const char ** const tail )
  {
  char * tmp;
  long li;

  errno = 0;
  *i = li = strtol( str, &tmp, 10 );
  if( tail ) *tail = tmp;
  if( tmp == str )
    {
    set_error_msg( "Bad numerical result" );
    *i = 0;
    return false;
    }
  if( errno == ERANGE || li > INT_MAX || li < INT_MIN )
    {
    set_error_msg( "Numerical result out of range" );
    *i = 0;
    return false;
    }
  return true;
  }
Пример #22
0
Файл: global.c Проект: coliv/ed
/* add a line node to the global-active list */
bool set_active_node( const line_t * const lp )
  {
  disable_interrupts();
  if( !resize_line_buffer( &active_list, &active_size,
                           ( active_len + 1 ) * sizeof (line_t **) ) )
    {
    show_strerror( 0, errno ); set_error_msg( "Memory exhausted" );
    enable_interrupts();
    return false;
    }
  enable_interrupts();
  active_list[active_len++] = lp;
  return true;
  }
Пример #23
0
bool set_highlighter(const char *newhl){
	struct stat st;
	if(*newhl==0){/*turning off highlighting*/
		free(highlighter);
		highlighter = 0;
		return true;
	}
	int r=stat(newhl,&st);
	if(r!=0){
		set_error_msg("Can't stat the highlighter program");
		return false;
	}
	if(!S_ISREG(st.st_mode)){
		set_error_msg("That isn't a normal file");
		return false;
	}
	if(!(st.st_mode & S_IXOTH)){
		set_error_msg("Can't execute highlighter, no exec permission.\nTry doing chmod +x");
		return false;
	}
	free(highlighter);
	highlighter = strdup(newhl);
	return true;
}
Пример #24
0
/* get a valid address from the command buffer */
static bool get_third_addr( const char ** const ibufpp, int * const addr )
  {
  const int old1 = first_addr;
  const int old2 = second_addr;
  int addr_cnt = extract_addr_range( ibufpp );

  if( addr_cnt < 0 ) return false;
  if( traditional() && addr_cnt == 0 )
    { set_error_msg( "Destination expected" ); return false; }
  if( second_addr < 0 || second_addr > last_addr() )
    { invalid_address(); return false; }
  *addr = second_addr;
  first_addr = old1; second_addr = old2;
  return true;
  }
Пример #25
0
/* verify the command suffix in the command buffer */
static bool get_command_suffix( const char ** const ibufpp,
                                int * const gflagsp )
  {
  while( true )
    {
    const char ch = **ibufpp;
    if( ch == 'l' ) *gflagsp |= GLS;
    else if( ch == 'n' ) *gflagsp |= GNP;
    else if( ch == 'p' ) *gflagsp |= GPR;
    else break;
    ++*ibufpp;
    }
  if( *(*ibufpp)++ != '\n' )
    { set_error_msg( "Invalid command suffix" ); return false; }
  return true;
  }
Пример #26
0
/* replace text matched by a pattern according to a substitution
   template; return pointer to the modified text */
static int replace_matching_text( const line_t *lp, const int gflags,
                                  const int snum )
  {
  const int se_max = 30;	/* max subexpressions in a regular expression */
  regmatch_t rm[se_max];
  char *txt = get_sbuf_line( lp );
  char *eot;
  int i = 0, off = 0;
  char changed = 0;

  if( !txt ) return -1;
  if( isbinary() ) nul_to_newline( txt, lp->len );
  eot = txt + lp->len;
  if( !regexec( global_pat, txt, se_max, rm, 0 ) )
    {
    int matchno = 0;
    do {
      if( !snum || snum == ++matchno )
        {
        changed = 1; i = rm[0].rm_so;
        if( !resize_buffer( &rbuf, &rbufsz, off + i ) ) return -1;
        if( isbinary() ) newline_to_nul( txt, rm[0].rm_eo );
        memcpy( rbuf + off, txt, i ); off += i;
        off = apply_subst_template( txt, rm, off, global_pat->re_nsub );
        if( off < 0 ) return -1;
        }
      else
        {
        i = rm[0].rm_eo;
        if( !resize_buffer( &rbuf, &rbufsz, off + i ) ) return -1;
        if( isbinary() ) newline_to_nul( txt, i );
        memcpy( rbuf + off, txt, i ); off += i;
        }
      txt += rm[0].rm_eo;
      }
    while( *txt && ( !changed || ( ( gflags & GSG ) && rm[0].rm_eo ) ) &&
           !regexec( global_pat, txt, se_max, rm, REG_NOTBOL ) );
    i = eot - txt;
    if( !resize_buffer( &rbuf, &rbufsz, off + i + 2 ) ) return -1;
    if( i > 0 && !rm[0].rm_eo && ( gflags & GSG ) )
      { set_error_msg( "Infinite substitution loop" ); return -1; }
    if( isbinary() ) newline_to_nul( txt, i );
    memcpy( rbuf + off, txt, i );
    memcpy( rbuf + off + i, "\n", 2 );
    }
  return ( changed ? off + i + 1 : 0 );
  }
Пример #27
0
/* close scratch file */
bool close_sbuf( void )
  {
  clear_yank_buffer();
  clear_undo_stack();
  if( sfp )
    {
    if( fclose( sfp ) != 0 )
      {
      show_strerror( 0, errno );
      set_error_msg( "Cannot close temp file" );
      return false;
      }
    sfp = 0;
    }
  sfpos = 0;
  seek_write = false;
  return true;
  }
Пример #28
0
/* undo last change to the editor buffer */
bool undo( const bool isglobal )
  {
  int n;
  const int o_current_addr = current_addr_;
  const int o_last_addr = last_addr_;
  const bool o_modified = modified_;

  if( u_ptr <= 0 || u_current_addr < 0 || u_last_addr < 0 )
    { set_error_msg( "Nothing to undo" ); return false; }
  search_line_node( 0 );		/* reset cached value */
  disable_interrupts();
  for( n = u_ptr - 1; n >= 0; --n )
    {
    switch( ustack[n].type )
      {
      case UADD: link_nodes( ustack[n].head->q_back, ustack[n].tail->q_forw );
                 break;
      case UDEL: link_nodes( ustack[n].head->q_back, ustack[n].head );
                 link_nodes( ustack[n].tail, ustack[n].tail->q_forw );
                 break;
      case UMOV:
      case VMOV: link_nodes( ustack[n-1].head, ustack[n].head->q_forw );
                 link_nodes( ustack[n].tail->q_back, ustack[n-1].tail );
                 link_nodes( ustack[n].head, ustack[n].tail ); --n;
                 break;
      }
    ustack[n].type ^= 1;
    }
  /* reverse undo stack order */
  for( n = 0; 2 * n < u_ptr - 1; ++n )
    {
    undo_t tmp = ustack[n];
    ustack[n] = ustack[u_ptr-1-n]; ustack[u_ptr-1-n] = tmp;
    }
  if( isglobal ) clear_active_list();
  current_addr_ = u_current_addr; u_current_addr = o_current_addr;
  last_addr_ = u_last_addr; u_last_addr = o_last_addr;
  modified_ = u_modified; u_modified = o_modified;
  enable_interrupts();
  return true;
  }
Пример #29
0
/* return the address of the next line matching a pattern in a given
   direction. wrap around begin/end of editor buffer if necessary */
int get_matching_node_addr( const char **ibufpp, const char forward )
  {
  regex_t *pat = get_compiled_pattern( ibufpp );
  int addr = current_addr();

  if( !pat ) return -1;
  do {
    addr = ( forward ? inc_addr( addr ) : dec_addr( addr ) );
    if( addr )
      {
      line_t *lp = search_line_node( addr );
      char *s = get_sbuf_line( lp );
      if( !s ) return -1;
      if( isbinary() ) nul_to_newline( s, lp->len );
      if( !regexec( pat, s, 0, 0, 0 ) ) return addr;
      }
    }
  while( addr != current_addr() );
  set_error_msg( "No match" );
  return -1;
  }
Пример #30
0
/* assure at least a minimum size for buffer 'buf' */
bool resize_buffer( char ** const buf, int * const size, const int min_size )
  {
  if( *size < min_size )
    {
    const int new_size = ( min_size < 512 ? 512 : ( min_size / 512 ) * 1024 );
    void * new_buf = 0;
    disable_interrupts();
    if( *buf ) new_buf = realloc( *buf, new_size );
    else new_buf = malloc( new_size );
    if( !new_buf )
      {
      show_strerror( 0, errno );
      set_error_msg( "Memory exhausted" );
      enable_interrupts();
      return false;
      }
    *size = new_size;
    *buf = (char *)new_buf;
    enable_interrupts();
    }
  return true;
  }