2 * IR toolkit for tcl/tk
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.2 1995-05-26 11:44:11 adam
8 * Bugs fixed. More work on MARC utilities and queries. Test
9 * client is up-to-date again.
11 * Revision 1.1 1995/05/26 08:54:19 adam
12 * New MARC utilities. Uses prefix query.
23 #define ISO2709_RS 035
24 #define ISO2709_FS 036
25 #define ISO2709_IDFS 037
27 int atoi_n (const char *buf, int len)
34 val = val*10 + (*buf - '0');
40 static int marc_compare (const char *f, const char *p)
46 for (; *f && *p; f++, p++)
58 char *ir_tcl_fread_marc (FILE *inf, size_t *size)
63 if (fread (length, 1, 5, inf) != 5)
65 *size = atoi_n (length, 5);
68 if (!(buf = malloc (*size+1)))
70 if (fread (buf+5, 1, *size-5, inf) != (*size-5))
75 memcpy (buf, length, 5);
80 int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf,
81 int argc, char **argv)
86 int identifier_length;
88 int length_data_entry;
90 int length_implementation;
95 if (!strcmp (argv[3], "field"))
97 else if (!strcmp (argv[3], "lines") || !strcmp (argv[3], "list"))
101 Tcl_AppendResult (interp, "Unknown MARC extract mode", NULL);
104 record_length = atoi_n (buf, 5);
105 if (record_length < 25)
107 Tcl_AppendResult (interp, "Not a MARC record", NULL);
110 indicator_length = atoi_n (buf+10, 1);
111 identifier_length = atoi_n (buf+11, 1);
112 base_address = atoi_n (buf+12, 4);
114 length_data_entry = atoi_n (buf+20, 1);
115 length_starting = atoi_n (buf+21, 1);
116 length_implementation = atoi_n (buf+22, 1);
118 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
119 entry_p += 3+length_data_entry+length_starting;
120 base_address = entry_p+1;
121 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
129 char identifier[128];
131 memcpy (tag, buf+entry_p, 3);
134 data_length = atoi_n (buf+entry_p, length_data_entry);
135 entry_p += length_data_entry;
136 data_offset = atoi_n (buf+entry_p, length_starting);
137 entry_p += length_starting;
138 i = data_offset + base_address;
139 end_offset = i+data_length-1;
141 if (memcmp (tag, "00", 2) && indicator_length)
143 for (j = 0; j<indicator_length; j++)
144 indicator[j] = buf[i++];
147 if (marc_compare (tag, argv[4]) || marc_compare (indicator, argv[5]))
149 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
153 if (memcmp (tag, "00", 2) && identifier_length)
156 for (j = 1; j<identifier_length; j++)
157 identifier[j-1] = buf[i++];
158 identifier[j-1] = '\0';
159 for (i0 = i; buf[i] != ISO2709_RS &&
160 buf[i] != ISO2709_IDFS &&
161 buf[i] != ISO2709_FS && i < end_offset;
167 for (i0 = i; buf[i] != ISO2709_RS &&
168 buf[i] != ISO2709_FS && i < end_offset;
173 if (marc_compare (identifier, argv[6])==0)
175 char *data = malloc (i-i0+1);
177 memcpy (data, buf+i0, i-i0);
181 if (strcmp (tag, ptag))
184 Tcl_AppendResult (interp, "}} ", NULL);
186 Tcl_AppendResult (interp, "{", tag, " {} {", NULL);
188 Tcl_AppendResult (interp, "{", tag, " {",
189 indicator, "} {", NULL);
193 Tcl_AppendResult (interp, "{{}", NULL);
195 Tcl_AppendResult (interp, "{", identifier, NULL);
196 Tcl_AppendElement (interp, data);
197 Tcl_AppendResult (interp, "} ", NULL);
200 Tcl_AppendElement (interp, data);
205 logf (LOG_WARN, "MARC: separator but not at end of field");
206 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
207 logf (LOG_WARN, "MARC: no separator at end of field");
209 if (mode == 'l' && *ptag)
210 Tcl_AppendResult (interp, "}} ", NULL);