+ struct yaz_marc_subfield *n = (struct yaz_marc_subfield *)
+ nmem_malloc(mt->nmem, sizeof(*n));
+ n->code_data = nmem_strdupn(mt->nmem, code_data, code_data_len);
+ n->next = 0;
+ /* mark subfield_pp to point to this one, so we append here next */
+ *mt->subfield_pp = n;
+ mt->subfield_pp = &n->next;
+ }
+}
+
+int atoi_n_check(const char *buf, int size, int *val)
+{
+ int i;
+ for (i = 0; i < size; i++)
+ if (!isdigit(i[(const unsigned char *) buf]))
+ return 0;
+ *val = atoi_n(buf, size);
+ return 1;
+}
+
+void yaz_marc_set_leader(yaz_marc_t mt, const char *leader_c,
+ int *indicator_length,
+ int *identifier_length,
+ int *base_address,
+ int *length_data_entry,
+ int *length_starting,
+ int *length_implementation)
+{
+ char leader[24];
+
+ memcpy(leader, leader_c, 24);
+
+ if (!atoi_n_check(leader+10, 1, indicator_length))
+ {
+ yaz_marc_cprintf(mt,
+ "Indicator length at offset 10 should hold a digit."
+ " Assuming 2");
+ leader[10] = '2';
+ *indicator_length = 2;
+ }
+ if (!atoi_n_check(leader+11, 1, identifier_length))
+ {
+ yaz_marc_cprintf(mt,
+ "Identifier length at offset 11 should hold a digit."
+ " Assuming 2");
+ leader[11] = '2';
+ *identifier_length = 2;
+ }
+ if (!atoi_n_check(leader+12, 5, base_address))
+ {
+ yaz_marc_cprintf(mt,
+ "Base address at offsets 12..16 should hold a number."
+ " Assuming 0");
+ *base_address = 0;
+ }
+ if (!atoi_n_check(leader+20, 1, length_data_entry))
+ {
+ yaz_marc_cprintf(mt,
+ "Length data entry at offset 20 should hold a digit."
+ " Assuming 4");
+ *length_data_entry = 4;
+ leader[20] = '4';
+ }
+ if (!atoi_n_check(leader+21, 1, length_starting))
+ {
+ yaz_marc_cprintf(mt,
+ "Length starting at offset 21 should hold a digit."
+ " Assuming 5");
+ *length_starting = 5;
+ leader[21] = '5';
+ }
+ if (!atoi_n_check(leader+22, 1, length_implementation))
+ {
+ yaz_marc_cprintf(mt,
+ "Length implementation at offset 22 should hold a digit."
+ " Assuming 0");
+ *length_implementation = 0;
+ leader[22] = '0';
+ }
+
+ if (mt->debug)
+ {
+ yaz_marc_cprintf(mt, "Indicator length %5d", *indicator_length);
+ yaz_marc_cprintf(mt, "Identifier length %5d", *identifier_length);
+ yaz_marc_cprintf(mt, "Base address %5d", *base_address);
+ yaz_marc_cprintf(mt, "Length data entry %5d", *length_data_entry);
+ yaz_marc_cprintf(mt, "Length starting %5d", *length_starting);
+ yaz_marc_cprintf(mt, "Length implementation %5d", *length_implementation);
+ }
+ yaz_marc_add_leader(mt, leader, 24);
+}
+
+void yaz_marc_subfield_str(yaz_marc_t mt, const char *s)
+{
+ strncpy(mt->subfield_str, s, sizeof(mt->subfield_str)-1);
+ mt->subfield_str[sizeof(mt->subfield_str)-1] = '\0';
+}
+
+void yaz_marc_endline_str(yaz_marc_t mt, const char *s)
+{
+ strncpy(mt->endline_str, s, sizeof(mt->endline_str)-1);
+ mt->endline_str[sizeof(mt->endline_str)-1] = '\0';
+}
+
+/* try to guess how many bytes the identifier really is! */
+static size_t cdata_one_character(yaz_marc_t mt, const char *buf)
+{
+ if (mt->iconv_cd)
+ {
+ size_t i;
+ for (i = 1; i<5; i++)