X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=util%2Fmarcdump.c;h=1542fb1d1df65df0f18aef782505fdc9de2cdad4;hp=3b6163ca2002bba981d782deeba106b1746454d9;hb=4f8ea8cfaf2f3d95e4efcf9494526c2b4be43eb8;hpb=fc6d778b923000b5c6ad8e108b0b184178a9d33f diff --git a/util/marcdump.c b/util/marcdump.c index 3b6163c..1542fb1 100644 --- a/util/marcdump.c +++ b/util/marcdump.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 1995-2006, Index Data ApS + * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: marcdump.c,v 1.40 2006-07-06 10:17:55 adam Exp $ + * $Id: marcdump.c,v 1.47 2007-01-03 08:42:16 adam Exp $ */ #define _FILE_OFFSET_BITS 64 @@ -50,10 +50,52 @@ static char *prog; static void usage(const char *prog) { - fprintf (stderr, "Usage: %s [-c cfile] [-f from] [-t to] [-x] [-X] [-e] [-I] [-v] [-s splitfname] file...\n", + fprintf (stderr, "Usage: %s [-c cfile] [-f from] [-t to] " + "[-i format] [-o format] " + "[-n] [-l pos=value] [-v] [-C chunk] [-s splitfname] file...\n", prog); } +static int getbyte_stream(void *client_data) +{ + FILE *f = (FILE*) client_data; + + int c = fgetc(f); + if (c == EOF) + return 0; + return c; +} + +static void ungetbyte_stream(int c, void *client_data) +{ + FILE *f = (FILE*) client_data; + + if (c == 0) + c = EOF; + ungetc(c, f); +} + +static void marcdump_read_line(yaz_marc_t mt, const char *fname) +{ + FILE *inf = fopen(fname, "rb"); + if (!inf) + { + fprintf (stderr, "%s: cannot open %s:%s\n", + prog, fname, strerror (errno)); + exit(1); + } + + while (yaz_marc_read_line(mt, getbyte_stream, + ungetbyte_stream, inf) == 0) + { + WRBUF wrbuf = wrbuf_alloc(); + yaz_marc_write_mode(mt, wrbuf); + fputs(wrbuf_buf(wrbuf), stdout); + wrbuf_free(wrbuf, 1); + } + fclose(inf); +} + #if YAZ_HAVE_XML2 static void marcdump_read_xml(yaz_marc_t mt, const char *fname) { @@ -70,11 +112,12 @@ static void marcdump_read_xml(yaz_marc_t mt, const char *fname) r = yaz_marc_read_xml(mt, ptr); if (r) fprintf(stderr, "yaz_marc_read_xml failed\n"); - - yaz_marc_write_mode(mt, wrbuf); - - fputs(wrbuf_buf(wrbuf), stdout); - + else + { + yaz_marc_write_mode(mt, wrbuf); + + fputs(wrbuf_buf(wrbuf), stdout); + } wrbuf_free(wrbuf, 1); } xmlFreeDoc(doc); @@ -82,13 +125,20 @@ static void marcdump_read_xml(yaz_marc_t mt, const char *fname) #endif static void dump(const char *fname, const char *from, const char *to, - int read_xml, int xml, - int print_offset, const char *split_fname, int verbose, - FILE *cfile) + int input_format, int output_format, + int write_using_libxml2, + int print_offset, const char *split_fname, int split_chunk, + int verbose, FILE *cfile, const char *leader_spec) { yaz_marc_t mt = yaz_marc_create(); yaz_iconv_t cd = 0; - + + if (yaz_marc_leader_spec(mt, leader_spec)) + { + fprintf(stderr, "bad leader spec: %s\n", leader_spec); + yaz_marc_destroy(mt); + exit(2); + } if (from && to) { cd = yaz_iconv_open(to, from); @@ -96,26 +146,31 @@ static void dump(const char *fname, const char *from, const char *to, { fprintf(stderr, "conversion from %s to %s " "unsupported\n", from, to); + yaz_marc_destroy(mt); exit(2); } yaz_marc_iconv(mt, cd); } - yaz_marc_xml(mt, xml); + yaz_marc_xml(mt, output_format); + yaz_marc_write_using_libxml2(mt, write_using_libxml2); yaz_marc_debug(mt, verbose); - if (read_xml) + if (input_format == YAZ_MARC_MARCXML || input_format == YAZ_MARC_XCHANGE) { #if YAZ_HAVE_XML2 marcdump_read_xml(mt, fname); -#else - return; #endif } - else + else if (input_format == YAZ_MARC_LINE) + { + marcdump_read_line(mt, fname); + } + else if (input_format == YAZ_MARC_ISO2709) { FILE *inf = fopen(fname, "rb"); - int count = 0; int num = 1; + int marc_no = 0; + int split_file_no = -1; if (!inf) { fprintf (stderr, "%s: cannot open %s:%s\n", @@ -124,117 +179,120 @@ static void dump(const char *fname, const char *from, const char *to, } if (cfile) fprintf (cfile, "char *marc_records[] = {\n"); - if (1) + for(;; marc_no++) { - int marc_no = 0; - for(;; marc_no++) + char *result = 0; + size_t len; + size_t rlen; + int len_result; + size_t r; + char buf[100001]; + + r = fread (buf, 1, 5, inf); + if (r < 5) { - size_t len; - char *result = 0; - size_t rlen; - size_t r; - char buf[100001]; - - r = fread (buf, 1, 5, inf); - if (r < 5) - { - if (r && print_offset && verbose) - printf ("\n", - (long) r); - break; - } - while (*buf < '0' || *buf > '9') - { - int i; - long off = ftell(inf) - 5; - if (verbose || print_offset) - printf("\n", - *buf & 0xff, *buf & 0xff, - off, off); - for (i = 0; i<4; i++) - buf[i] = buf[i+1]; - r = fread(buf+4, 1, 1, inf); - if (r < 1) - break; - } + if (r && print_offset && verbose) + printf ("\n", + (long) r); + break; + } + while (*buf < '0' || *buf > '9') + { + int i; + long off = ftell(inf) - 5; + if (verbose || print_offset) + printf("\n", + *buf & 0xff, *buf & 0xff, + off, off); + for (i = 0; i<4; i++) + buf[i] = buf[i+1]; + r = fread(buf+4, 1, 1, inf); if (r < 1) - { - if (verbose || print_offset) - printf ("\n"); break; - } - if (print_offset) + } + if (r < 1) + { + if (verbose || print_offset) + printf ("\n"); + break; + } + if (print_offset) + { + long off = ftell(inf) - 5; + printf ("\n", + num, off, off); + } + len = atoi_n(buf, 5); + if (len < 25 || len > 100000) + { + long off = ftell(inf) - 5; + printf("Bad Length %ld read at offset %ld (%lx)\n", + (long)len, (long) off, (long) off); + break; + } + rlen = len - 5; + r = fread (buf + 5, 1, rlen, inf); + if (r < rlen) + break; + if (split_fname) + { + char fname[256]; + const char *mode = 0; + FILE *sf; + if ((marc_no % split_chunk) == 0) { - long off = ftell(inf) - 5; - printf ("\n", - num, off, off); + mode = "wb"; + split_file_no++; } - len = atoi_n(buf, 5); - if (len < 25 || len > 100000) + else + mode = "ab"; + sprintf(fname, "%.200s%07d", split_fname, split_file_no); + sf = fopen(fname, mode); + if (!sf) { - long off = ftell(inf) - 5; - printf("Bad Length %d read at offset %ld (%lx)\n", - len, (long) off, (long) off); - break; + fprintf(stderr, "Could not open %s\n", fname); + split_fname = 0; } - rlen = len - 5; - r = fread (buf + 5, 1, rlen, inf); - if (r < rlen) - break; - if (split_fname) + else { - char fname[256]; - FILE *sf; - sprintf(fname, "%.200s%07d", split_fname, marc_no); - sf = fopen(fname, "wb"); - if (!sf) + if (fwrite(buf, 1, len, sf) != len) { - fprintf(stderr, "Could not open %s\n", fname); + fprintf(stderr, "Could write content to %s\n", + fname); split_fname = 0; } - else - { - if (fwrite(buf, 1, len, sf) != len) - { - fprintf(stderr, "Could write content to %s\n", - fname); - split_fname = 0; - } - fclose(sf); - } - } - { int rlentmp = (int) rlen; - r = yaz_marc_decode_buf (mt, buf, -1, &result, &rlentmp); - rlen = (size_t) rlentmp; } - if (r > 0 && result) - { - fwrite (result, rlen, 1, stdout); + fclose(sf); } - if (r > 0 && cfile) + } + len_result = (int) rlen; + r = yaz_marc_decode_buf(mt, buf, -1, &result, &len_result); + if (r > 0 && result) + { + fwrite (result, len_result, 1, stdout); + } + if (r > 0 && cfile) + { + char *p = buf; + size_t i; + if (marc_no) + fprintf (cfile, ","); + fprintf (cfile, "\n"); + for (i = 0; i < r; i++) { - char *p = buf; - size_t i; - if (count) - fprintf (cfile, ","); - fprintf (cfile, "\n"); - for (i = 0; i < r; i++) - { - if ((i & 15) == 0) - fprintf (cfile, " \""); - fprintf (cfile, "\\x%02X", p[i] & 255); - - if (i < r - 1 && (i & 15) == 15) - fprintf (cfile, "\"\n"); - - } - fprintf (cfile, "\"\n"); + if ((i & 15) == 0) + fprintf (cfile, " \""); + fprintf (cfile, "\\x%02X", p[i] & 255); + + if (i < r - 1 && (i & 15) == 15) + fprintf (cfile, "\"\n"); + } - num++; - if (verbose) - printf("\n"); + fprintf (cfile, "\"\n"); } - count++; + num++; + if (verbose) + printf("\n"); } if (cfile) fprintf (cfile, "};\n"); @@ -252,11 +310,14 @@ int main (int argc, char **argv) char *arg; int verbose = 0; int no = 0; - int xml = 0; + int output_format = YAZ_MARC_LINE; FILE *cfile = 0; char *from = 0, *to = 0; - int read_xml = 0; + int input_format = YAZ_MARC_ISO2709; + int split_chunk = 1; const char *split_fname = 0; + const char *leader_spec = 0; + int write_using_libxml2 = 0; #if HAVE_LOCALE_H setlocale(LC_CTYPE, ""); @@ -268,11 +329,37 @@ int main (int argc, char **argv) #endif prog = *argv; - while ((r = options("pvc:xOeXIf:t:s:", argv, argc, &arg)) != -2) + while ((r = options("i:o:C:npvc:xOeXIf:t:s:l:", argv, argc, &arg)) != -2) { no++; switch (r) { + case 'i': + input_format = yaz_marc_decode_formatstr(arg); + if (input_format == -1) + { + fprintf(stderr, "%s: bad input format: %s\n", prog, arg); + exit(1); + } + break; + case 'o': + /* dirty hack so we can make Libxml2 do the writing .. + rather than WRBUF */ + if (strlen(arg) > 4 && strncmp(arg, "xml,", 4) == 0) + { + arg = arg + 4; + write_using_libxml2 = 1; + } + output_format = yaz_marc_decode_formatstr(arg); + if (output_format == -1) + { + fprintf(stderr, "%s: bad output format: %s\n", prog, arg); + exit(1); + } + break; + case 'l': + leader_spec = arg; + break; case 'f': from = arg; break; @@ -285,13 +372,9 @@ int main (int argc, char **argv) cfile = fopen(arg, "w"); break; case 'x': -#if YAZ_HAVE_XML2 - read_xml = 1; -#else - fprintf(stderr, "%s: -x not supported." - " YAZ not compiled with Libxml2 support\n", prog); - exit(3); -#endif + fprintf(stderr, "%s: -x no longer supported. " + "Use -i marcxml instead\n", prog); + exit(1); break; case 'O': fprintf(stderr, "%s: OAI MARC no longer supported." @@ -299,13 +382,22 @@ int main (int argc, char **argv) exit(1); break; case 'e': - xml = YAZ_MARC_XCHANGE; + fprintf(stderr, "%s: -e no longer supported. " + "Use -o marcxchange instead\n", prog); + exit(1); break; case 'X': - xml = YAZ_MARC_MARCXML; + fprintf(stderr, "%s: -X no longer supported. " + "Use -o marcxml instead\n", prog); + exit(1); break; case 'I': - xml = YAZ_MARC_ISO2709; + fprintf(stderr, "%s: -I no longer supported. " + "Use -o marc instead\n", prog); + exit(1); + break; + case 'n': + output_format = YAZ_MARC_CHECK; break; case 'p': print_offset = 1; @@ -313,16 +405,21 @@ int main (int argc, char **argv) case 's': split_fname = arg; break; + case 'C': + split_chunk = atoi(arg); + break; case 0: - dump(arg, from, to, read_xml, xml, - print_offset, split_fname, verbose, cfile); + dump(arg, from, to, input_format, output_format, + write_using_libxml2, + print_offset, split_fname, split_chunk, + verbose, cfile, leader_spec); break; case 'v': verbose++; break; default: usage(prog); - exit (1); + exit(1); } } if (cfile)