summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTimo Savinen <tjsa@iki.fi>2005-09-25 12:05:00 +0000
committerHadrien Dorio <hadrien.dorio@gmail.com>2017-12-16 00:24:05 +0100
commitb9eb6e4429575318d3c510b99961093c42321529 (patch)
tree997ceb30973318a5cb7da0a78a5a9784d8137e61 /src
parent35d0e8a808dd1382d5236d1f6f8bfe62b2ebefee (diff)
downloadbinary-block-editor-b9eb6e4429575318d3c510b99961093c42321529.tar.gz
binary-block-editor-b9eb6e4429575318d3c510b99961093c42321529.zip
0.1.1
Diffstat (limited to 'src')
-rw-r--r--src/bbe.c169
-rw-r--r--src/bbe.h15
-rw-r--r--src/buffer.c50
-rw-r--r--src/execute.c104
4 files changed, 307 insertions, 31 deletions
diff --git a/src/bbe.c b/src/bbe.c
index 7c1ed00..9743ac2 100644
--- a/src/bbe.c
+++ b/src/bbe.c
@@ -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();
diff --git a/src/bbe.h b/src/bbe.h
index 93b3e0c..721ad66 100644
--- a/src/bbe.h
+++ b/src/bbe.h
@@ -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();
OpenPOWER on IntegriCloud