Implement feof(x) in zzcat, to break out of a loop after EOF was hit x times.

This commit is contained in:
Sam Hocevar 2010-01-08 00:48:33 +00:00 committed by sam
parent 0977f25944
commit 23f4274f85
2 changed files with 41 additions and 14 deletions

View File

@ -56,7 +56,7 @@ checkutils()
# Regression tests for stuff that used to break
check "$ZZOPTS" "$ZZCAT \"fread(1,33000) fseek(1,SEEK_SET) fread(1,1) fseek(4093,SEEK_CUR) fread(1,1) fseek(1,SEEK_CUR) fread(1,1)\" $file" \
"eglibc (2.9-21) bug regression"
check "$ZZOPTS" "$ZZCAT \"repeat(33000,getc_unlocked() ungetc() getline())\" $file" \
check "$ZZOPTS" "$ZZCAT \"repeat(33000,getc_unlocked() ungetc() getline() feof(10))\" $file" \
"sed getc_unlocked() bug regression"
# Misc tests
for n in \
@ -71,10 +71,10 @@ checkutils()
"getc_unlocked() ungetc() fread(1,33000)" \
"fgetc() ungetc() fread(1,33000)" \
"fgetc_unlocked() ungetc() fread(1,33000)" \
"repeat(33000,getc())" \
"repeat(33000,getc_unlocked())" \
"repeat(33000,fgetc())" \
"repeat(33000,fgetc_unlocked())" \
"repeat(33000,getc(),feof(10))" \
"repeat(33000,getc_unlocked(),feof(10))" \
"repeat(33000,fgetc(),feof(10))" \
"repeat(33000,fgetc_unlocked(),feof(10))" \
"repeat(8000,getc()) fread(1,33000)" \
"repeat(8000,getc_unlocked()) fread(1,33000)" \
"repeat(8000,fgetc()) fread(1,33000)" \
@ -88,12 +88,12 @@ checkutils()
"fread(1,33000) rewind() repeat(10000,fseek(2,SEEK_CUR) fread(1,2))" \
"fread(1,33000) rewind() repeat(10000,fseek(3,SEEK_CUR) fread(1,3))" \
"fread(1,33000) rewind() repeat(10000,fseek(4,SEEK_CUR) fread(1,4))" \
"repeat(33000,getc() ungetc() getline())" \
"repeat(33000,fgetc() ungetc() getline())" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,fread(1,2))" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,getc())" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,fgetc())" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,getc_unlocked())" \
"repeat(33000,getc() ungetc() getline() feof(10))" \
"repeat(33000,fgetc() ungetc() getline() feof(10))" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,fread(1,2),feof(10))" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,getc(),feof(10))" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,fgetc(),feof(10))" \
"fread(1,33000) fseek(1000,SEEK_CUR) repeat(10000,getc_unlocked(),feof(10))" \
; do
check "$ZZOPTS" "$ZZCAT \"$n\" $file" "$n"
done

View File

@ -1,6 +1,6 @@
/*
* zzcat - various cat reimplementations for testing purposes
* Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* $Id$
@ -104,6 +104,24 @@ static inline unsigned int myrand(void)
p = strchr(p, ')') + 1; \
} while(0)
#define FEOF() \
do { \
if (!f) \
{ \
f = fopen(file, "r"); \
if (!f) \
{ \
fprintf(stderr, "E: zzcat: cannot open `%s'\n", file); \
return EXIT_FAILURE; \
} \
} \
if (feof(f)) \
feofs++; \
if (feofs >= l1) \
finish = 1; \
p = strchr(p, ')') + 1; \
} while(0)
/*
* Command parser. We rewrite fmt by replacing the last character with
* '%c' and check that the sscanf() call returns the expected number of
@ -152,7 +170,7 @@ static int cat_file(char const *p, char const *file)
char *retbuf = NULL, *tmp;
FILE *f = NULL;
size_t retlen = 0, retoff = 0;
int nloops = 0, fd = -1;
int nloops = 0, fd = -1, feofs = 0, finish = 0;
/* Allocate 32MB for our temporary buffer. Any larger value will crash. */
tmp = malloc(32 * 1024 * 1024);
@ -187,7 +205,7 @@ static int cat_file(char const *p, char const *file)
return EXIT_FAILURE;
}
loops[nloops - 1].count--;
if (loops[nloops - 1].count <= 0)
if (loops[nloops - 1].count <= 0 || finish)
{
nloops--;
p = strchr(p, ')') + 1;
@ -196,6 +214,8 @@ static int cat_file(char const *p, char const *file)
{
p = loops[nloops - 1].p;
}
finish = 0;
}
/* FILE * opening functions */
@ -220,6 +240,10 @@ static int cat_file(char const *p, char const *file)
FOPEN(f = __freopen64(file, "r", f));
#endif
/* FILE * EOF detection */
else if (PARSECMD("feof ( %li )", &l1))
FEOF();
/* FILE * closing functions */
else if (PARSECMD("fclose ( )"))
FCLOSE(fclose(f));
@ -333,6 +357,9 @@ static int cat_file(char const *p, char const *file)
/* Clean up our mess */
if (lineptr)
free(lineptr);
if (finish && !nloops)
break;
}
if (f)