diff options
| author | Timo Savinen <tjsa@iki.fi> | 2005-09-25 12:05:00 +0000 |
|---|---|---|
| committer | Hadrien Dorio <hadrien.dorio@gmail.com> | 2017-12-16 00:24:05 +0100 |
| commit | b9eb6e4429575318d3c510b99961093c42321529 (patch) | |
| tree | 997ceb30973318a5cb7da0a78a5a9784d8137e61 /src | |
| parent | 35d0e8a808dd1382d5236d1f6f8bfe62b2ebefee (diff) | |
| download | binary-block-editor-b9eb6e4429575318d3c510b99961093c42321529.tar.gz binary-block-editor-b9eb6e4429575318d3c510b99961093c42321529.zip | |
0.1.1
Diffstat (limited to 'src')
| -rw-r--r-- | src/bbe.c | 169 | ||||
| -rw-r--r-- | src/bbe.h | 15 | ||||
| -rw-r--r-- | src/buffer.c | 50 | ||||
| -rw-r--r-- | src/execute.c | 104 |
4 files changed, 307 insertions, 31 deletions
@@ -20,7 +20,7 @@ * */ -/* $Id: bbe.c,v 1.23 2005/09/14 15:48:52 timo Exp $ */ +/* $Id: bbe.c,v 1.30 2005/09/25 10:03:47 timo Exp $ */ #include "bbe.h" #ifdef HAVE_GETOPT_H @@ -28,7 +28,6 @@ #endif #include <ctype.h> -#include <stdio.h> #include <stdlib.h> #ifdef HAVE_STRING_H @@ -44,7 +43,7 @@ static char *program = "bbe"; #ifdef VERSION static char *version = VERSION; #else -static char *version = "0.1.0"; +static char *version = "0.1.1"; #endif #ifdef PACKAGE_BUGREPORT @@ -54,19 +53,34 @@ static char *email_address = "tjsa@iki.fi"; #endif - +/* global block */ struct block block; + +/* commands to be executed */ struct command *commands = NULL; + +/* extra info for panic */ char *panic_info = NULL; +/* -s switch state */ +int output_only_block = 0; + +/* c command conversions */ char *convert_strings[] = { "BCDASC", "ASCBCD", "", }; -static char short_opts[] = "b:e:f:o:?V"; +/* format types for p command */ +char *p_formats="DOHA"; +/* formats for F and B commands */ +char *FB_formats="DOH"; + +static char short_opts[] = "b:e:f:o:s?V"; + +#ifdef HAVE_GETOPT_LONG static struct option long_opts[] = { {"block",1,NULL,'b'}, {"expression",1,NULL,'e'}, @@ -74,8 +88,10 @@ static struct option long_opts[] = { {"output",1,NULL,'o'}, {"help",0,NULL,'?'}, {"version",0,NULL,'V'}, + {"suppress",0,NULL,'s'}, {NULL,0,NULL,0} }; +#endif void panic(char *msg,char *info,char *syserror) @@ -160,9 +176,9 @@ parse_string(char *string,off_t *length) if(*p == '\\') { p++; - if(*p == '\\') + if(*p == '\\' || *p == ';') { - num[i] = *p++; + buf[i] = *p++; } else { j = 0; @@ -345,6 +361,7 @@ parse_command(char *command_string) { struct command *curr,*new; char *c,*p,*buf; + char *f; char *token[10]; char slash_char; int i,j; @@ -352,6 +369,9 @@ parse_command(char *command_string) p = command_string; while(isspace(*p)) p++; // remove leading spaces + if (p[0] == 0) return; // empty line + if (p[0] == '#') return; // comment + c = strdup(p); if(c == NULL) panic("Out of memory",NULL,NULL); @@ -361,9 +381,6 @@ parse_command(char *command_string) while(token[i - 1] != NULL && i < 10) token[i++] = strtok(NULL," \t\n"); i--; - if (token[0] == NULL ) return; // empty line - if (*token[0] == '#') return; // comment - curr = commands; if (curr != NULL) { @@ -468,6 +485,30 @@ parse_command(char *command_string) if(new->letter == 'y' && new->s1_len != new->s2_len) panic("Strings in y-command must have equal length",command_string,NULL); free(buf); break; + case 'F': + case 'B': + if(i > 1 && (strlen(token[1]) != 1)) panic("Error in command",command_string,NULL); + case 'p': + if(i != 2 || strlen(token[0]) > 1) panic("Error in command",command_string,NULL); + new->s1 = parse_string(token[1],&new->s1_len); + j = 0; + while(new->s1[j] != 0) { + new->s1[j] = toupper(new->s1[j]); + j++; + } + if (new->letter == 'p') + { + f = p_formats; + } else + { + f = FB_formats; + } + while(*f != 0 && strchr(new->s1,*f) == NULL) f++; + if (*f == 0) panic("Error in command",command_string,NULL); + break; + case 'N': + if(i != 1 || strlen(token[0]) > 1) panic("Error in command",command_string,NULL); + break; default: panic("Unknown command",command_string,NULL); break; @@ -475,30 +516,95 @@ parse_command(char *command_string) free(c); } -/* read commands from file */ +/* parse commands, commands are separated by ;. ; can be escaped as \; + and ;s inside " or ' are not separators + */ +void +parse_commands(char *command_string) +{ + char *c; + char *start; + int inside_d = 0; // double + int inside_s = 0; // single + + c = command_string; + start = c; + + while(*start != 0) + { + switch(*c) + { + case '\\': + c++; + break; + case '"': + if(inside_d) + { + inside_d--; + } else + { + inside_d++; + } + break; + case '\'': + if(inside_s) + { + inside_s--; + } else + { + inside_s++; + } + break; + case ';': + if(!inside_d && !inside_s) + { + *c = 0; + parse_command(start); + start = c + 1; + } + break; + case 0: + parse_command(start); + start = c; + break; + } + c++; + } +} + + + +/* parse one command, commands are in list + read commands from file */ void parse_command_file(char *file) { FILE *fp; char *line; - char info[1024]; - size_t line_len = 1024; + char *info; + size_t line_len = (8*1024); int line_no = 0; line = xmalloc(line_len); + info = xmalloc(strlen(file) + 100); fp = fopen(file,"r"); if (fp == NULL) panic("Error in opening file",file,strerror(errno)); +#ifdef HAVE_GETLINE while(getline(&line,&line_len,fp) != -1) +#else + while(fgets(line,line_len,fp) != NULL) +#endif { line_no++; sprintf(info,"Error in file '%s' in line %d\n",file,line_no); panic_info=info; - parse_command(line); + parse_commands(line); } free(line); + free(info); fclose(fp); panic_info=NULL; } @@ -507,6 +613,7 @@ void help(FILE *stream) { fprintf(stream,"Usage: %s [OPTION]...\n\n",program); +#ifdef HAVE_GETOPT_LONG fprintf(stream,"-b, --block=BLOCK\n"); fprintf(stream,"\t\tBlock definition.\n"); fprintf(stream,"-e, --expression=COMMAND\n"); @@ -515,13 +622,30 @@ help(FILE *stream) fprintf(stream,"\t\tAdd commands from script-file to the commands to be executed.\n"); fprintf(stream,"-o, --output=name\n"); fprintf(stream,"\t\tWrite output to name instead of standard output.\n"); + fprintf(stream,"-s, --suppress\n"); + fprintf(stream,"\t\tSuppress normal output, print only block contents.\n"); fprintf(stream,"-?, --help\n"); - fprintf(stream,"\t\tDisplay this help and exit\n"); + fprintf(stream,"\t\tDisplay this help and exit.\n"); fprintf(stream,"-V, --Version\n"); - fprintf(stream,"\t\tShow version and exit\n"); +#else + fprintf(stream,"-b BLOCK\n"); + fprintf(stream,"\t\tBlock definition.\n"); + fprintf(stream,"-e COMMAND\n"); + fprintf(stream,"\t\tAdd command to the commands to be executed.\n"); + fprintf(stream,"-f script-file\n"); + fprintf(stream,"\t\tAdd commands from script-file to the commands to be executed.\n"); + fprintf(stream,"-o name\n"); + fprintf(stream,"\t\tWrite output to name instead of standard output.\n"); + fprintf(stream,"-s\n"); + fprintf(stream,"\t\tSuppress normal output, print only block contents.\n"); + fprintf(stream,"-?\n"); + fprintf(stream,"\t\tDisplay this help and exit.\n"); + fprintf(stream,"-V\n"); +#endif + fprintf(stream,"\t\tShow version and exit.\n"); fprintf(stream,"\nAll remaining arguments are names of input files;\n"); fprintf(stream,"if no input files are specified, then the standard input is read.\n"); - fprintf(stream,"\nSend bug reports to %s\n",email_address); + fprintf(stream,"\nSend bug reports to %s.\n",email_address); } void @@ -547,7 +671,11 @@ main (int argc, char **argv) int opt; block.type = 0; +#ifdef HAVE_GETOPT_LONG while ((opt = getopt_long(argc,argv,short_opts,long_opts,NULL)) != -1) +#else + while ((opt = getopt(argc,argv,short_opts)) != -1) +#endif { switch(opt) { @@ -556,7 +684,7 @@ main (int argc, char **argv) parse_block(optarg); break; case 'e': - parse_command(optarg); + parse_commands(optarg); break; case 'f': parse_command_file(optarg); @@ -564,6 +692,9 @@ main (int argc, char **argv) case 'o': set_output_file(optarg); break; + case 's': + output_only_block = 1; + break; case '?': help(stdout); exit(EXIT_SUCCESS); @@ -586,7 +717,7 @@ main (int argc, char **argv) while(optind < argc) set_input_file(argv[optind++]); } else { - set_input_file(NULL); + set_input_file("-"); } init_buffer(); @@ -20,7 +20,7 @@ * */ -/* $Id: bbe.h,v 1.15 2005/09/14 15:48:52 timo Exp $ */ +/* $Id: bbe.h,v 1.20 2005/09/25 10:03:47 timo Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -34,6 +34,10 @@ #include <errno.h> #endif +#ifdef HAVE_ERROR_H +#include <error.h> +#endif + #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -113,6 +117,7 @@ struct command { struct io_file { char *file; int fd; + off_t start_offset; struct io_file *next; }; @@ -203,9 +208,17 @@ execute_program(struct command *c); extern void reverse_bytes(size_t count); + +extern void +write_string(char *string); + +extern char * +get_current_file(void); + /* global variables */ extern struct block block; extern struct command *commands; extern struct io_file out_stream; extern struct input_buffer in_buffer; extern struct output_buffer out_buffer; +extern int output_only_block; diff --git a/src/buffer.c b/src/buffer.c index f9b45eb..b5798d3 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -20,11 +20,10 @@ * */ -/* $Id: buffer.c,v 1.19 2005/09/14 15:48:52 timo Exp $ */ +/* $Id: buffer.c,v 1.25 2005/09/25 10:03:47 timo Exp $ */ #include "bbe.h" #include <stdlib.h> -#include <error.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> @@ -34,6 +33,7 @@ struct io_file out_stream; /* list of input files, points to current file */ struct io_file *in_stream = NULL; +struct io_file *in_stream_start = NULL; /* input buffer */ struct input_buffer in_buffer; @@ -80,6 +80,7 @@ set_input_file(char *file) if(in_stream == NULL) { in_stream = new; + in_stream_start = in_stream; } else { curr = in_stream; @@ -90,7 +91,8 @@ set_input_file(char *file) curr->next = new; } - if(file == NULL) + new->start_offset = (off_t) 0; + if(file[0] == '-' && file[1] == 0) { new->fd = STDIN_FILENO; new->file = "stdin"; @@ -103,6 +105,28 @@ set_input_file(char *file) } } +/* return the name of current input file */ +char * +get_current_file(void) +{ + struct io_file *f = in_stream_start; + struct io_file *prev; + off_t current_offset = in_buffer.stream_offset + (off_t) (in_buffer.read_pos-in_buffer.buffer); + + while(f != NULL) + { + prev = f; + f = f->next; + if(f != NULL && (f->start_offset == (off_t) 0 || f->start_offset > current_offset)) + { + f = NULL; + } + } + return prev->file; +} + + + /* initialize in and out buffers */ void init_buffer() @@ -129,6 +153,7 @@ read_input_stream() if(in_buffer.read_pos == NULL) // first read, so just fill buffer { to_be_read = INPUT_BUFFER_SIZE; + to_be_saved = 0; buffer_write_pos = in_buffer.buffer; in_buffer.stream_offset = (off_t) 0; } else //we have allready read something @@ -153,6 +178,8 @@ read_input_stream() { if (close(in_stream->fd) == -1) panic("Error in closing file",in_stream->file,strerror(errno)); in_stream = in_stream->next; + if (in_stream != NULL) + in_stream->start_offset = in_buffer.stream_offset + (off_t) read_count + (off_t) to_be_saved; } read_count += last_read; } while (in_stream != NULL && read_count < to_be_read); @@ -395,16 +422,29 @@ find_block() found = 1; } } - if(in_buffer.read_pos > scan_start) + if(in_buffer.read_pos > scan_start && !output_only_block) write_output_stream(scan_start,in_buffer.read_pos - scan_start); if(found) mark_block_end(); } } while (!found && !end_of_stream()); - if(end_of_stream() && !found) write_output_stream(in_buffer.read_pos,1); + if(end_of_stream() && !found && !output_only_block) write_output_stream(in_buffer.read_pos,1); if(found) in_buffer.block_num++; return found; } +/* write null terminated string */ +void +write_string(char *string) +{ + register char *f; + + f = string; + + while(*f != 0) f++; + + write_buffer(string,(off_t) (f - string)); +} + /* write_buffer at the current write position */ void write_buffer(unsigned char *buf,off_t length) diff --git a/src/execute.c b/src/execute.c index 5ad5cc0..9d43bc5 100644 --- a/src/execute.c +++ b/src/execute.c @@ -20,14 +20,14 @@ * */ -/* $Id: execute.c,v 1.12 2005/09/14 17:34:44 timo Exp $ */ +/* $Id: execute.c,v 1.17 2005/09/25 10:03:47 timo Exp $ */ #include "bbe.h" #include <stdlib.h> -#include <error.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> +#include <ctype.h> /* tells if current byte should be deleted */ static int delete_this_byte; @@ -40,20 +40,79 @@ static struct command *current_commands; /* commands to be executed at start of buffer */ /* note J and L must be in every string becaus ethey affect the whole block */ -#define BLOCK_START_COMMANDS "DAJL" +#define BLOCK_START_COMMANDS "DAJLFBN" /* commands to be executed for each byte */ -#define BYTE_COMMANDS "acdirsywjlJL" +#define BYTE_COMMANDS "acdirsywjplJL" /* commands to be executed at end of buffer */ #define BLOCK_END_COMMANDS "IJL" + +/* byte_to_string, convert byte value to visible string, + either hex (H), decimal (D), octal (O) or ascii (A) + */ +char * +byte_to_string(unsigned char byte,char format) +{ + static char string[10]; + + switch(format) + { + case 'H': + sprintf(string,"x%02x",(int) byte); + break; + case 'D': + sprintf(string,"% 3d",(int) byte); + break; + case 'O': + sprintf(string,"%03o",(int) byte); + break; + case 'A': + sprintf(string,"%c",isprint(byte) ? byte : ' '); + break; + default: + string[0] = 0; + break; + } + return string; +} + +/* convert off_t to string */ +char * +off_t_to_string(off_t number,char format) +{ + static char string[16]; + + switch(format) + { + case 'H': + sprintf(string,"x%llx",(long long) number); + break; + case 'D': + sprintf(string,"%lld",(long long) number); + break; + case 'O': + sprintf(string,"0%llo",(long long) number); + break; + default: + string[0] = 0; + break; + } + return string; +} + + + + /* execute given commands */ void execute_commands(struct command *c,char *command_letters) { register int i; unsigned char a,b; + char *f; + char *str; while(c != NULL) { @@ -215,6 +274,39 @@ execute_commands(struct command *c,char *command_letters) while(c->next != NULL) c = c->next; // skip rest of commands } break; + case 'p': + if (delete_this_byte) break; + f = c->s1; + while(*f != 0) + { + str = byte_to_string(read_byte(),*f); + write_string(str); + f++; + if (*f != 0) + { + put_byte('-'); + write_next_byte(); + } + } + put_byte(' '); + break; + case 'F': + str = off_t_to_string(in_buffer.stream_offset + (off_t) (in_buffer.read_pos-in_buffer.buffer),c->s1[0]); + write_string(str); + put_byte(':'); + write_next_byte(); + break; + case 'B': + str = off_t_to_string(in_buffer.block_num,c->s1[0]); + write_string(str); + put_byte(':'); + write_next_byte(); + break; + case 'N': + write_string(get_current_file()); + put_byte(':'); + write_next_byte(); + break; case 'w': break; } @@ -300,10 +392,10 @@ execute_program(struct command *c) while(find_block()) { - delete_this_block = 0; reset_rpos(c); - execute_commands(c,BLOCK_START_COMMANDS); + delete_this_block = 0; out_buffer.block_offset = 0; + execute_commands(c,BLOCK_START_COMMANDS); do { set_cycle_start(); |

