#include #include #include #include #include #include #ifdef WIN32 #include #endif #include #include #include #include "testcase.h" #include "testcaseinput.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* * As write(), but with error handling. */ static size_t write_file(int fd,const char *buf,size_t count,GError **error) { if (write(fd,buf,count)). * The file is written in the encoding specified for communicating with * bookloupe. The name_used field of is filled in with the name * of the created file (which may be different than the name specified * if that contained "XXXXXX" to be replaced by a unique string). */ gboolean testcase_input_create(Testcase *testcase,TestcaseInput *input, GError **error) { int fd; size_t n; char *filename,*s,*t; GError *tmp_err=NULL; if (input->contents) { if (testcase->encoding) { t=convert_newlines(input->contents,testcase->flags); s=g_convert(t,-1,testcase->encoding,"UTF-8",NULL,&n,&tmp_err); g_free(t); if (!s) { g_propagate_prefixed_error(error,tmp_err, "Conversion to %s failed: ",testcase->encoding); return FALSE; } } else { s=convert_newlines(input->contents,testcase->flags); n=strlen(s); } } else { n=0; s=NULL; } g_free(input->name_used); input->name_used=NULL; if (testcase->tmpdir) filename=g_build_filename(testcase->tmpdir,input->name,NULL); else filename=g_strdup(input->name); if (strstr(input->name,"XXXXXX")) fd=g_mkstemp(filename); else fd=g_open(filename,O_WRONLY|O_CREAT|O_EXCL|O_BINARY,0600); if (fd<0) { g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno), "%s: %s",filename,g_strerror(errno)); g_free(s); return FALSE; } input->name_used=g_strdup(filename+strlen(filename)-strlen(input->name)); if (n && write_file(fd,s,n,error)!=n) { g_free(s); close(fd); (void)g_unlink(filename); g_free(filename); g_free(input->name_used); input->name_used=NULL; return FALSE; } g_free(s); if (close(fd)<0) { g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno), "%s: %s",filename,g_strerror(errno)); (void)g_unlink(filename); g_free(filename); g_free(input->name_used); input->name_used=NULL; return FALSE; } g_free(filename); return TRUE; } /* * Remove an input file created with testcase_input_create() */ gboolean testcase_input_remove(Testcase *testcase,TestcaseInput *input, GError **error) { char *filename; if (input->name_used) { if (testcase->tmpdir) filename=g_build_filename(testcase->tmpdir,input->name_used,NULL); else filename=g_strdup(input->name_used); if (g_unlink(filename)<0) { g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno), "%s: %s",filename,g_strerror(errno)); return FALSE; } g_free(filename); g_free(input->name_used); input->name_used=NULL; } return TRUE; } /* Create a new description of an input file needed for a testcase */ TestcaseInput *testcase_input_new(const char *name,const char *contents) { TestcaseInput *input; input=g_new0(TestcaseInput,1); input->name=g_strdup(name); input->contents=g_strdup(contents); return input; } /* Free the description of a testcase input file */ void testcase_input_free(TestcaseInput *input) { g_free(input->name); g_free(input->name_used); g_free(input->contents); g_free(input); }