diff -r 000000000000 -r 707d51fedbe0 test/harness/testcase.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/harness/testcase.c Tue Jan 24 23:57:11 2012 +0000 @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#include +#endif +#include +#include "testcase.h" + +#if !HAVE_MKSTEMP +/* + * An insecure implementation of mkstemp(), for those platforms that + * don't support it. + */ +int mkstemp(char *template) +{ + int fd; + char *s; + for(;;) + { + s=str_dup(template); + mktemp(s); + if (!*s) + { + errno=EEXIST; + mem_free(s); + return -1; + } + fd=open(s,O_RDWR|O_CREAT|O_EXCL,0600); + if (fd>0) + { + strcpy(template,s); + mem_free(s); + return fd; + } + else + mem_free(s); + } +} +#endif /* !HAVE_MKSTEMP */ + +/* + * As write(), but always convert NL to CR NL. + */ +static size_t write_text(int fd,const char *buf,size_t count) +{ + size_t i; + FILE *fp; + fd=dup(fd); + if (fd<0) + return -1; +#ifdef WIN32 + if (_setmode(fd,_O_BINARY)<0) + { + close(fd); + return -1; + } +#endif + fp=fdopen(fd,"wb"); + if (!fp) + { + close(fd); + return -1; + } + for(i=0;iinput) + n=strlen(testcase->input); + else + n=0; + if (n && write_text(fd,testcase->input,n)!=n) + { + perror(input); + close(fd); + (void)remove(input); + return FALSE; + } + close(fd); + command[0]=getenv("GUTCHECK"); + if (!command[0]) + command[0]="." GC_DIR_SEPARATOR_S "gutcheck"; + command[1]=input; + command[2]=NULL; + if (testcase->expected) + r=spawn_sync(command,&output,&exit_status); + else + { + r=spawn_sync(command,NULL,&exit_status); + output=NULL; + } + (void)remove(input); + if (!r) + return FALSE; + if (testcase->expected) + { + expected=string_new("\n\nFile: "); + string_append(expected,input); + string_append(expected,"\n\n\n"); + header_len=expected->len; + string_append(expected,testcase->expected); + } + else + { + expected=NULL; + header_len=0; + } + if (expected && strcmp(output,expected->str)) + { + fprintf(stderr,"%s: FAIL\n",testcase->basename); + offset=common_prefix_length(output,expected->str); + if (offset==header_len && !output[offset]) + fprintf(stderr,"Unexpected zero warnings from gutcheck.\n"); + else + { + endp=strchr(output+offset,'\n'); + if (!endp) + endp=output+strlen(output); + report=string_new(NULL); + string_append_len(report,output,endp-output); + bol=strrchr(report->str,'\n'); + if (bol) + bol++; + else + bol=report->str; + col=offset-(bol-report->str); + fprintf(stderr,"Unexpected output from gutcheck:\n"); + if (report->len>=header_len) + fprintf(stderr,"%s\n%*s^\n",report->str+header_len,col,""); + else + fprintf(stderr,"%s\n%*s^\n",report->str,col,""); + string_free(report,TRUE); + } + string_free(expected,TRUE); + mem_free(output); + return FALSE; + } + string_free(expected,TRUE); + mem_free(output); + if (exit_status) + fprintf(stderr,"gutcheck exited with code %d\n",r); + if (!exit_status) + fprintf(stderr,"%s: PASS\n",testcase->basename); + return !exit_status; +} + +/* + * Free a testcase. + */ +void testcase_free(Testcase *testcase) +{ + mem_free(testcase->basename); + mem_free(testcase->input); + mem_free(testcase->expected); + mem_free(testcase); +}