/* ------------------------------------------------------------------- */ /* marc2line : Reads an ISO 2709 MARC record, converts to MARC */ /* "Line format" */ /* */ /* author : Ole Husby, BIBSYS */ /* updated : 1998-09-30 */ /* ------------------------------------------------------------------- */ #include #include #include #include #define DIRL 3600 #define LINEL 72 #define SUBFIELD_CODE '\x1f' #define SUBFIELD_STR "\x1f" #define FIELD_TERMINATOR '\x1e' #define RECORD_TERMINATOR '\x1d' #define BIBSYS_TYPE 0 #define NORMARC_TYPE 1 union LDR { char ldr_string[24+1]; struct { char record_length[5], record_status, record_type, bibliographic_level, unused1[2], indicator_count, subfield_code_count, base_adress[5], unused2[3], entry1, entry2, entry3, entry4; } ltab; } ldr; static char out_record[10240]; static int out_type; /* ------------------------------------------------------------------- */ /* One subfield string is split into output lines */ /* ------------------------------------------------------------------- */ static void out_subfield(data, prefix, slen) char *data, *prefix; int slen; { char lineprefix[7], subprefix[4], *spre; int i, more, len, max; if (out_type == BIBSYS_TYPE) strcpy(lineprefix, prefix); else { if (prefix[0] == ' ') strcpy(lineprefix, " "); else strcpy(lineprefix, "*"); strcat(lineprefix, prefix); } max = LINEL; if (slen) { spre = (char *) subprefix; strcpy(spre, "$"); /* Construct subfield */ strncat(spre, data, 1); /* prefix */ if (out_type == BIBSYS_TYPE) strcat(spre, " "); data++; max = LINEL - 2; if (out_type == BIBSYS_TYPE) max--; } else spre = NULL; more = 1; while (more) { if (slen) while (data[0] == ' ') data++; /* skip leading blanks */ strcat(out_record, lineprefix); /* Start with prefix */ strcpy(lineprefix, " "); if (out_type == NORMARC_TYPE) strcat(lineprefix, " "); len = strlen(data); if (len > max) /* Must fit into one line */ { len = max; for (i = max; i > max - 15; i--) { if (data[i] == ' ') { len = i; break; } } } else more = 0; if (spre) { strcat(out_record, spre); /* subfield pref needed */ spre = NULL; /* only first line */ max = LINEL; } strncat(out_record, data, len); /* append data */ if (more) data += len; strcat(out_record, "\n"); } } /* ------------------------------------------------------------------- */ /* One MARC field is split into subfields and given to output */ /* ------------------------------------------------------------------- */ static int out_field(data, ftag, find) char *data, *ftag, *find; { char prefix[5]; char subfield[5120], *sub = subfield; int subcode = 0; strcpy(prefix, ftag); if (!find) /* output entire field */ { out_subfield(data, prefix, subcode); return 1; } strcat(prefix, find); if (data[0] != SUBFIELD_CODE) return 0; /* requires subf code in */ data++; /* first byte */ sub = strtok(data, SUBFIELD_STR); /* find first subfield */ if (!sub) return 0; subcode = 1; out_subfield(sub, prefix, subcode); /* output subfield */ strcpy(prefix, " "); /* reset prefix */ while (sub = strtok(NULL, SUBFIELD_STR)) /* find and output rest */ out_subfield(sub, prefix, subcode); /* of the subfields */ return 1; } /* ------------------------------------------------------------------- */ /* Main program */ /* ------------------------------------------------------------------- */ char *marc2line(record, type) char *record, *type; { char buffer[10240], tag[4], indicators[3]; char *cp, *fld, *buf = buffer, *cq; char directory[DIRL+1], *dir = directory, *ind; char sBase[6], fLen[5], fStart[6]; int dlen, base, x = 0, more = 1, len, start; if (!record || !*record) return (char *) NULL; strcpy(buf, record); *out_record = 0; /* reset out area */ if (strcmp(type, "bibsys") == 0) out_type = BIBSYS_TYPE; else out_type = NORMARC_TYPE; strncpy(ldr.ldr_string, buf, 24); /* get leader */ ldr.ldr_string[24] = '\0'; buf += 24; strncpy(sBase, ldr.ltab.base_adress, 5); sBase[5] = '\0'; base = atoi(sBase); dlen = base - 24; /* get directory */ strncpy(dir, buf, dlen); dir[dlen] = '\0'; buf += dlen; cp = dir; while (more) /* loop until EOdir */ { if (*cp == FIELD_TERMINATOR) break; if (strlen(cp) < 13) return (char *) NULL; strncpy(tag, cp, 3); /* get tag */ tag[3] = '\0'; cp +=3; strncpy(fLen, cp, 4); /* get length */ fLen[4] = '\0'; len = atoi(fLen) -1; /* discard field term. */ cp += 4; strncpy(fStart, cp, 5); /* get start of field */ fStart[5] = '\0'; start = atoi(fStart); cp += 5; fld = buf + start; /* get field */ fld[len] = '\0'; if (strncmp(tag, "00", 2) != 0) /* get indicators */ { indicators[0] = '\0'; strncat(indicators, fld, 2); ind = (char *) indicators; fld += 2; } else ind = NULL; if (!out_field(fld, tag, ind)) /* output field */ return (char *) NULL; } return (char *) out_record; }