Bug fixed for unix error "readlink /proc/self/fd/0" on MacOS.
[Faustine.git] / interpreter / lib / src / libsndfile-1.0.25 / regtest / database.c
1 /*
2 ** Copyright (C) 2005-2011 Erik de Castro Lopo
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU General Public License for more details.
13 **
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include "config.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27
28 #include <sndfile.h>
29
30 #include "regtest.h"
31
32 #if HAVE_SQLITE3
33
34 #include <sqlite3.h>
35
36 typedef struct
37 { sqlite3 *sql ;
38
39 int count ;
40 int ekey_max ;
41
42 /* Filename and pathname for file. */
43 char filename [256] ;
44 char pathname [512] ;
45
46 /* Storage for createding SQL commands. Must be larger than logbuf below. */
47 char cmdbuf [1 << 15] ;
48
49 /* Storage for log buffer retrieved from SNDFILE* .*/
50 char logbuf [1 << 14] ;
51
52 } REGTEST_DB ;
53
54 /* In checksum.c */
55 int calc_checksum (SNDFILE * file, const SF_INFO * info) ;
56
57 static void get_filename_pathname (REGTEST_DB * db, const char *filepath) ;
58 static void single_quote_replace (char * buf) ;
59
60 static int get_ekey_from_filename (REGTEST_DB * db, const char *filepath) ;
61 static int get_filename_pathname_by_ekey (REGTEST_DB * db, int ekey) ;
62 static int check_file_by_ekey (REGTEST_DB * db, int ekey) ;
63
64 static int count_callback (REGTEST_DB * db, int argc, char **argv, char **colname) ;
65 static int ekey_max_callback (REGTEST_DB * db, int argc, char **argv, char **colname) ;
66 static int callback (void *unused, int argc, char **argv, char **colname) ;
67
68 REG_DB *
69 db_open (const char * db_name)
70 { REGTEST_DB * db ;
71 int err ;
72
73 if ((db = malloc (sizeof (REGTEST_DB))) == NULL)
74 { perror ("malloc") ;
75 exit (1) ;
76 } ;
77
78 if ((err = sqlite3_open (db_name, &(db->sql))) != 0)
79 { printf ("Can't open database: %s\n", sqlite3_errmsg (db->sql)) ;
80 sqlite3_close (db->sql) ;
81 free (db) ;
82 exit (1) ;
83 } ;
84
85 return (REG_DB *) db ;
86 } /* db_open */
87
88 int
89 db_create (const char * db_name)
90 { REGTEST_DB * db ;
91 const char *cmd ;
92 char * errmsg = NULL ;
93 int err ;
94
95 db = (REGTEST_DB *) db_open (db_name) ;
96
97 cmd = "create table sndfile (ekey INTEGER PRIMARY KEY,"
98 "fname VARCHAR(1),"
99 "fpath VARCHAR(1),"
100 "srate INTEGER,"
101 "frames VARCHAR(1),"
102 "channels INTEGER,"
103 "format VARCHAR(1),"
104 "checksum VARCHAR(1),"
105 "logbuf VARCHAR(1)"
106 ");" ;
107
108 err = sqlite3_exec (db->sql, cmd, callback, 0, &errmsg) ;
109 if (err != SQLITE_OK)
110 printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ;
111
112 sqlite3_close (db->sql) ;
113 free (db) ;
114
115 return 0 ;
116 } /* db_create */
117
118 int
119 db_close (REG_DB * db_handle)
120 { REGTEST_DB * db ;
121
122 db = (REGTEST_DB *) db_handle ;
123
124 sqlite3_close (db->sql) ;
125 free (db) ;
126
127 return 0 ;
128 } /* db_close */
129
130 /*==============================================================================
131 */
132
133 int
134 db_file_exists (REG_DB * db_handle, const char * filename)
135 { REGTEST_DB * db ;
136 const char * cptr ;
137 char * errmsg ;
138 int err ;
139
140 db = (REGTEST_DB *) db_handle ;
141
142 if ((cptr = strrchr (filename, '/')) != NULL)
143 filename = cptr + 1 ;
144
145 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select fname from sndfile where fname='%s'", filename) ;
146
147 db->count = 0 ;
148 err = sqlite3_exec (db->sql, db->cmdbuf, (sqlite3_callback) count_callback, db, &errmsg) ;
149 if (err == 0 && db->count == 1)
150 return 1 ;
151
152 return 0 ;
153 } /* db_file_exists */
154
155 int
156 db_add_file (REG_DB * db_handle, const char * filepath)
157 { REGTEST_DB * db ;
158 SNDFILE * sndfile ;
159 SF_INFO info ;
160 char * errmsg ;
161 int err, checksum ;
162
163 db = (REGTEST_DB *) db_handle ;
164
165 get_filename_pathname (db, filepath) ;
166
167 if (db_file_exists (db_handle, filepath))
168 { printf (" %s : already in database\n", db->filename) ;
169 return 0 ;
170 } ;
171
172 memset (&info, 0, sizeof (info)) ;
173 sndfile = sf_open (db->pathname, SFM_READ, &info) ;
174 sf_command (sndfile, SFC_GET_LOG_INFO, db->logbuf, sizeof (db->logbuf)) ;
175 checksum = (sndfile == NULL) ? 0 : calc_checksum (sndfile, &info) ;
176 sf_close (sndfile) ;
177
178 if (sndfile == NULL)
179 { printf (" %s : could not open : %s\n", db->filename, sf_strerror (NULL)) ;
180 puts (db->logbuf) ;
181 return 1 ;
182 } ;
183
184 single_quote_replace (db->logbuf) ;
185
186 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "insert into sndfile "
187 "(fname, fpath, srate, frames, channels, format, checksum, logbuf) values"
188 "('%s','%s',%d,'%ld', %d, '0x%08x', '0x%08x', '%s');",
189 db->filename, db->pathname, info.samplerate, (long) info.frames, info.channels, info.format, checksum, db->logbuf) ;
190
191 if (strlen (db->cmdbuf) >= sizeof (db->cmdbuf) - 1)
192 { printf ("strlen (db->cmdbuf) too long.\n") ;
193 exit (1) ;
194 } ;
195
196 err = sqlite3_exec (db->sql, db->cmdbuf, callback, 0, &errmsg) ;
197 if (err != SQLITE_OK)
198 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ;
199 puts (db->cmdbuf) ;
200 } ;
201
202 return 0 ;
203 } /* db_add_file */
204
205 int
206 db_check_file (REG_DB * db_handle, const char * filepath)
207 { REGTEST_DB * db ;
208 int ekey ;
209
210 if (db_file_exists (db_handle, filepath) == 0)
211 { printf ("\nFile not in database.\n\n") ;
212 exit (0) ;
213 } ;
214
215 db = (REGTEST_DB *) db_handle ;
216
217 ekey = get_ekey_from_filename (db, filepath) ;
218
219 return check_file_by_ekey (db, ekey) ;
220 } /* db_check_file */
221
222 /*==============================================================================
223 */
224
225 int
226 db_check_all (REG_DB * db_handle)
227 { REGTEST_DB * db ;
228 char * errmsg ;
229 int err, ekey ;
230
231 db = (REGTEST_DB *) db_handle ;
232
233 db->ekey_max = 0 ;
234
235 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select ekey from sndfile") ;
236
237 err = sqlite3_exec (db->sql, db->cmdbuf, (sqlite3_callback) ekey_max_callback, db, &errmsg) ;
238 if (err != SQLITE_OK)
239 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ;
240 puts (db->cmdbuf) ;
241 } ;
242
243 for (ekey = 1 ; ekey <= db->ekey_max ; ekey++)
244 if (get_filename_pathname_by_ekey (db, ekey) != 0)
245 check_file_by_ekey (db, ekey) ;
246
247 return 0 ;
248 } /* db_check_all */
249
250
251 int
252 db_list_all (REG_DB * db_handle)
253 {
254 printf ("%s : %p\n", __func__, db_handle) ;
255 return 0 ;
256 } /* db_list_all */
257
258 int
259 db_del_entry (REG_DB * db_handle, const char * entry)
260 {
261 printf ("%s : %p %s\n", __func__, db_handle, entry) ;
262 return 0 ;
263 } /* db_del_entry */
264
265 /*==============================================================================
266 */
267
268 static int
269 get_ekey_from_filename (REGTEST_DB * db, const char *filepath)
270 { char * errmsg, **result ;
271 int err, ekey = 0, rows, cols ;
272
273 get_filename_pathname (db, filepath) ;
274
275 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select ekey from sndfile where fname='%s'", db->filename) ;
276
277 err = sqlite3_get_table (db->sql, db->cmdbuf, &result, &rows, &cols, &errmsg) ;
278 if (err != SQLITE_OK)
279 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ;
280 puts (db->cmdbuf) ;
281 } ;
282
283 if (cols != 1 || rows != 1)
284 { printf ("Bad juju!! rows = %d cols = %d\n", rows, cols) ;
285 exit (1) ;
286 } ;
287
288 ekey = strtol (result [1], NULL, 10) ;
289
290 sqlite3_free_table (result) ;
291
292 return ekey ;
293 } /* get_ekey_from_filename */
294
295 static int
296 get_filename_pathname_by_ekey (REGTEST_DB * db, int ekey)
297 { char *errmsg, **result ;
298 int err, rows, cols ;
299
300 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select fname,fpath from sndfile where ekey='%d'", ekey) ;
301
302 err = sqlite3_get_table (db->sql, db->cmdbuf, &result, &rows, &cols, &errmsg) ;
303 if (err != SQLITE_OK)
304 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ;
305 puts (db->cmdbuf) ;
306 return 0 ;
307 } ;
308
309 if (cols != 2 || rows != 1)
310 { printf ("\nError (%s %d) : rows = %d cols = %d\n", __func__, __LINE__, rows, cols) ;
311 exit (1) ;
312 } ;
313
314 snprintf (db->filename, sizeof (db->filename), "%s", result [2]) ;
315 snprintf (db->pathname, sizeof (db->pathname), "%s", result [3]) ;
316
317 sqlite3_free_table (result) ;
318
319 return 1 ;
320 } /* get_filename_pathname_by_ekey */
321
322 static int
323 check_file_by_ekey (REGTEST_DB * db, int ekey)
324 { SNDFILE * sndfile ;
325 SF_INFO info ;
326 char * errmsg, **result ;
327 int err, k, rows, cols, checksum ;
328
329 printf (" %s : ", db->filename) ;
330 fflush (stdout) ;
331
332 memset (&info, 0, sizeof (info)) ;
333 sndfile = sf_open (db->pathname, SFM_READ, &info) ;
334 sf_command (sndfile, SFC_GET_LOG_INFO, db->logbuf, sizeof (db->logbuf)) ;
335 checksum = (sndfile == NULL) ? 0 : calc_checksum (sndfile, &info) ;
336 sf_close (sndfile) ;
337
338 if (sndfile == NULL)
339 { printf ("\n\nError : Could not open '%s' : %s\n", db->pathname, sf_strerror (NULL)) ;
340 puts (db->logbuf) ;
341 exit (1) ;
342 } ;
343
344 single_quote_replace (db->logbuf) ;
345
346 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select fname,srate,frames,channels,format,"
347 "checksum,logbuf from sndfile where ekey='%d'", ekey) ;
348
349 err = sqlite3_get_table (db->sql, db->cmdbuf, &result, &rows, &cols, &errmsg) ;
350 if (err != SQLITE_OK)
351 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ;
352 puts (db->cmdbuf) ;
353 } ;
354
355 for (k = 0 ; k < cols ; k++)
356 { if (strcmp (result [k], "fname") == 0)
357 { if (strcmp (result [k + cols], db->filename) == 0)
358 continue ;
359 printf ("\n\nError : fname doesn't match : %s != %s\n", result [k + cols], db->filename) ;
360 } ;
361
362 if (strcmp (result [k], "srate") == 0)
363 { if (strtol (result [k + cols], NULL, 10) == info.samplerate)
364 continue ;
365 printf ("\n\nError : srate doesn't match : %s == %d\n", result [k + cols], info.samplerate) ;
366 } ;
367
368 if (strcmp (result [k], "frames") == 0)
369 { if (strtoll (result [k + cols], NULL, 10) == info.frames)
370 continue ;
371 printf ("\n\nError : frames doesn't match : %s == %ld\n", result [k + cols], (long) info.frames) ;
372 } ;
373
374 if (strcmp (result [k], "channels") == 0)
375 { if (strtol (result [k + cols], NULL, 10) == info.channels)
376 continue ;
377 printf ("\n\nError : channels doesn't match : %s == %d\n", result [k + cols], info.channels) ;
378 } ;
379
380 if (strcmp (result [k], "format") == 0)
381 { if (strtol (result [k + cols], NULL, 16) == info.format)
382 continue ;
383 printf ("\n\nError : format doesn't match : %s == 0x%08x\n", result [k + cols], info.format) ;
384 } ;
385
386 if (strcmp (result [k], "checksum") == 0)
387 { int db_val = (int) strtoll (result [k + cols], NULL, 16) ;
388
389 if (db_val == checksum)
390 continue ;
391 printf ("\n\nError : checksum doesn't match : 0x%08x == 0x%08x\n", db_val, checksum) ;
392 } ;
393
394 if (strcmp (result [k], "logbuf") == 0)
395 continue ;
396
397 printf ("\nHere is the old logubuffer :\n\n%s\n\nand the new :\n\n%s\n\n", result [2 * cols - 1], db->logbuf) ;
398 exit (1) ;
399 } ;
400
401 sqlite3_free_table (result) ;
402
403 puts ("ok") ;
404
405 return 0 ;
406 } /* check_file_by_ekey */
407
408 /*==============================================================================
409 */
410
411 static void
412 get_filename_pathname (REGTEST_DB * db, const char *filepath)
413 { const char * cptr ;
414 int slen ;
415
416 if (filepath [0] != '/')
417 { memset (db->pathname, 0, sizeof (db->pathname)) ;
418 if (getcwd (db->pathname, sizeof (db->pathname)) == NULL)
419 { perror ("\ngetcwd failed") ;
420 exit (1) ;
421 } ;
422
423 slen = strlen (db->pathname) ;
424 db->pathname [slen ++] = '/' ;
425 snprintf (db->pathname + slen, sizeof (db->pathname) - slen, "%s", filepath) ;
426 }
427 else
428 snprintf (db->pathname, sizeof (db->pathname), "%s", filepath) ;
429
430 if ((cptr = strrchr (db->pathname, '/')) == NULL)
431 { printf ("\nError : bad pathname %s\n", filepath) ;
432 exit (1) ;
433 } ;
434
435 snprintf (db->filename, sizeof (db->filename), "%s", cptr + 1) ;
436 } /* get filename_pathname */
437
438 static void
439 single_quote_replace (char * buf)
440 { while ((buf = strchr (buf, '\'')) != 0)
441 buf [0] = '"' ;
442 } /* single_quote_replace */
443
444 static int
445 count_callback (REGTEST_DB * db, int argc, char **argv, char **colname)
446 { db->count ++ ;
447
448 (void) argc ;
449 (void) argv ;
450 (void) colname ;
451 return 0 ;
452 } /* count_callback */
453
454 static int
455 ekey_max_callback (REGTEST_DB * db, int argc, char **argv, char **unused)
456 { int ekey ;
457
458 (void) argc ;
459 (void) unused ;
460
461 ekey = strtol (argv [0], NULL, 10) ;
462 if (ekey > db->ekey_max)
463 db->ekey_max = ekey ;
464
465 return 0 ;
466 } /* ekey_max_callback */
467
468 static int
469 callback (void *unused, int argc, char **argv, char **colname)
470 { int k ;
471
472 (void) unused ;
473
474 for (k = 0 ; k < argc ; k++)
475 printf ("%s = %s\n", colname [k], argv [k] ? argv [k] : "NULL") ;
476
477 printf ("\n") ;
478
479 return 0 ;
480 } /* callback */
481
482 #else
483
484 int dummy (void) ;
485
486 int
487 dummy (void)
488 { /*
489 ** Empty dummy fnction so tha compiler doesn't winge about an
490 ** empty file.
491 */
492 return 0 ;
493 } /* dummy */
494
495 #endif