11 #include <glib/gstdio.h>
14 #include "testcaseinput.h"
21 * As write(), but with error handling.
23 static size_t write_file(int fd,const char *buf,size_t count,GError **error)
25 if (write(fd,buf,count)<count)
27 g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
28 "Error writing bookloupe input file: %s",g_strerror(errno));
35 * Replace \n with requested newline, U+240A (visible symbol for LF)
36 * with \n and U+240D (visible symbol for CR) with \r.
38 static char *convert_newlines(const char *text,int flags)
41 const gunichar visible_lf=0x240A;
42 const gunichar visible_cr=0x240D;
44 string=g_string_new(NULL);
47 c=g_utf8_get_char(text);
48 text=g_utf8_next_char(text);
49 if (c=='\n' && !(flags&TESTCASE_UNIX_NEWLINES))
51 if (flags&TESTCASE_OS9_NEWLINES)
52 g_string_append_c(string,'\r');
54 g_string_append(string,"\r\n");
56 else if (c==visible_lf)
57 g_string_append_c(string,'\n');
58 else if (c==visible_cr)
59 g_string_append_c(string,'\r');
61 g_string_append_unichar(string,c);
63 return g_string_free(string,FALSE);
67 * Create an input file needed for a testcase (as specified in <input>).
68 * The file is written in the encoding specified for communicating with
69 * bookloupe. The name_used field of <input> is filled in with the name
70 * of the created file (which may be different than the name specified
71 * if that contained "XXXXXX" to be replaced by a unique string).
73 gboolean testcase_input_create(Testcase *testcase,TestcaseInput *input,
82 if (testcase->encoding)
84 t=convert_newlines(input->contents,testcase->flags);
85 s=g_convert(t,-1,testcase->encoding,"UTF-8",NULL,&n,&tmp_err);
89 g_propagate_prefixed_error(error,tmp_err,
90 "Conversion to %s failed: ",testcase->encoding);
96 s=convert_newlines(input->contents,testcase->flags);
105 g_free(input->name_used);
106 input->name_used=NULL;
107 if (testcase->tmpdir)
108 filename=g_build_filename(testcase->tmpdir,input->name,NULL);
110 filename=g_strdup(input->name);
111 if (strstr(input->name,"XXXXXX"))
112 fd=g_mkstemp(filename);
114 fd=g_open(filename,O_WRONLY|O_CREAT|O_EXCL|O_BINARY,0600);
117 g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
118 "%s: %s",filename,g_strerror(errno));
122 input->name_used=g_strdup(filename+strlen(filename)-strlen(input->name));
123 if (n && write_file(fd,s,n,error)!=n)
127 (void)g_unlink(filename);
129 g_free(input->name_used);
130 input->name_used=NULL;
136 g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
137 "%s: %s",filename,g_strerror(errno));
138 (void)g_unlink(filename);
140 g_free(input->name_used);
141 input->name_used=NULL;
149 * Remove an input file created with testcase_input_create()
151 gboolean testcase_input_remove(Testcase *testcase,TestcaseInput *input,
155 if (input->name_used)
157 if (testcase->tmpdir)
158 filename=g_build_filename(testcase->tmpdir,input->name_used,NULL);
160 filename=g_strdup(input->name_used);
161 if (g_unlink(filename)<0)
163 g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
164 "%s: %s",filename,g_strerror(errno));
168 g_free(input->name_used);
169 input->name_used=NULL;
174 /* Create a new description of an input file needed for a testcase */
175 TestcaseInput *testcase_input_new(const char *name,const char *contents)
177 TestcaseInput *input;
178 input=g_new0(TestcaseInput,1);
179 input->name=g_strdup(name);
180 input->contents=g_strdup(contents);
184 /* Free the description of a testcase input file */
185 void testcase_input_free(TestcaseInput *input)
188 g_free(input->name_used);
189 g_free(input->contents);