#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); }