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; }
/* 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; }
/* 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; }
/* 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; }
/* 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 ); }
/* 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; }
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; }
/* 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; }
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"); } }
/* 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; }
/* 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; }
/* 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; }
/* 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]); }
/* 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; }
char may_access_filename( const char *name ) { if( restricted_ && ( *name == '!' || !strcmp( name, ".." ) || strchr( name, '/' ) ) ) { set_error_msg( "Shell access restricted" ); return 0; } return 1; }
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; }
/* 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; }
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 ); }
/* 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; }
/* 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; }
/* 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; }
/* 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; }
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; }
/* 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; }
/* 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; }
/* 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 ); }
/* 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; }
/* 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; }
/* 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; }
/* 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; }