annotate src/libsndfile-1.0.27/regtest/database.c @ 83:ae30d91d2ffe

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