summaryrefslogtreecommitdiffstats
path: root/src/execute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/execute.c')
-rw-r--r--src/execute.c129
1 files changed, 124 insertions, 5 deletions
diff --git a/src/execute.c b/src/execute.c
index b0a29cd..7980221 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -20,7 +20,7 @@
*
*/
-/* $Id: execute.c,v 1.27 2005/10/14 13:23:20 timo Exp $ */
+/* $Id: execute.c,v 1.31 2005/10/21 07:53:26 timo Exp $ */
#include "bbe.h"
#include <stdlib.h>
@@ -41,6 +41,11 @@ static int skip_this_block;
/* tells if i or s commands are inserting bytes, meaningfull at end of the block */
static int inserting;
+/* tells if there is w-command with file having %d
+ this is only for performance
+ */
+static int w_commands_block_num = 0;
+
/* command list for write_w_command */
static struct command_list *current_byte_commands;
@@ -381,25 +386,119 @@ write_w_command(unsigned char *buf,size_t length)
{
struct command_list *c;
+ if(skip_this_block) return;
+
c = current_byte_commands;
while(c != NULL)
{
if(c->letter == 'w')
{
- if(fwrite(buf,1,length,c->fd) != length) panic("Cannot write to file",c->s1,strerror(errno));
+ if(fwrite(buf,1,length,c->fd) != length) panic("Cannot write to file",c->s2,strerror(errno));
+ if(length) c->count = 1; // file was written
}
c = c->next;
}
}
+/* finds the %B or %nB format string from the filename of w-command
+ returns pointer to %-postion and the length of the format string
+ */
+char *
+find_block_w_file(char *file,int *len)
+{
+ char *f,*ppos;
+
+ f = file;
+
+ while(*f != 0)
+ {
+ if(*f == '%')
+ {
+ ppos = f;
+ f++;
+ while(f - ppos < 4 && isdigit(*f)) f++;
+ if(*f == 'B')
+ {
+ *len = (int) (f - ppos) + 1;
+ return ppos;
+ }
+ f = ppos;
+ }
+ f++;
+ }
+ return NULL;
+}
+
+/* replaces all %B or %nB format strings with block number in a file name */
+void
+bn_printf(char *file,char *str,off_t block_number)
+{
+ char *bstart,*f;
+ char num[128],format[64];
+ int blen;
+
+ f = str;
+ file[0] = 0;
+
+ while((bstart = find_block_w_file(f,&blen)) != NULL)
+ {
+ num[0] = 0;
+ format[0] = 0;
+ strncat(file,f,bstart - f);
+ strncpy(format,bstart,blen-1);
+ format[blen-1] = 0;
+ strcat(format,"lld");
+ sprintf(num,format,(long long) block_number);
+ if(strlen(file) + strlen(num) >= 4096) panic("Filename for w-command too long",str,NULL);
+ strcat(file,num);
+ f = bstart + blen;
+ }
+ strcat(file,f);
+}
+
+/* close (if open) and open next w-command files for new block */
+void
+open_w_files(off_t block_number)
+{
+ struct command_list *c;
+ static char file[4096];
+ c = current_byte_commands;
+
+ while(c != NULL)
+ {
+ if(c->letter == 'w' && c->offset)
+ {
+ if(c->fd != NULL)
+ {
+ if(fclose(c->fd) != 0) panic("Error closing file",c->s2,strerror(errno));
+ if (!c->count && c->s2 != NULL) // remove if empty
+ {
+ unlink(c->s2);
+ }
+ c->fd = NULL;
+ }
+
+ bn_printf(file,c->s1,block_number);
+ c->fd = fopen(file,"w");
+ if(c->fd == NULL) panic("Cannot open file for writing",file,strerror(errno));
+ c->count = 0;
+ if(c->s2 != NULL) free(c->s2);
+ c->s2 = xstrdup(file);
+ }
+ c = c->next;
+ }
+}
+
+
/* init_commands, initialize those wich need it, currently w - open file and rpos=0 for all */
void
init_commands(struct commands *commands)
{
struct command_list *c;
+ int wlen;
c = commands->byte;
@@ -408,8 +507,20 @@ init_commands(struct commands *commands)
switch(c->letter)
{
case 'w':
- c->fd = fopen(c->s1,"w");
- if(c->fd == NULL) panic("Cannot open file for writing",c->s1,strerror(errno));
+ if(find_block_w_file(c->s1,&wlen) != NULL)
+ {
+ c->fd = NULL;
+ c->offset = 1;
+ w_commands_block_num = 1;
+ c->s2 = NULL;
+ } else
+ {
+ c->fd = fopen(c->s1,"w");
+ if(c->fd == NULL) panic("Cannot open file for writing",c->s1,strerror(errno));
+ c->offset = 0;
+ c->s2 = xstrdup(c->s1);
+ }
+ c->count = 0;
break;
}
c = c->next;
@@ -430,7 +541,14 @@ close_commands(struct commands *commands)
switch(c->letter)
{
case 'w':
- if(fclose(c->fd) != 0) panic("Error in closing file",c->s1,strerror(errno));
+ if(c->fd != NULL)
+ {
+ if(fclose(c->fd) != 0) panic("Error in closing file",c->s2,strerror(errno));
+ if(!c->count && c->s2 != NULL)
+ {
+ unlink(c->s2);
+ }
+ }
break;
}
c = c->next;
@@ -464,6 +582,7 @@ execute_program(struct commands *commands)
delete_this_block = 0;
out_buffer.block_offset = 0;
skip_this_block = 0;
+ if(w_commands_block_num) open_w_files(in_buffer.block_num);
execute_commands(commands->block_start);
do
{
OpenPOWER on IntegriCloud