+/*
+ * FML interpreter. Europagate, 1995
+ *
+ * $Log: fmlmarc.c,v $
+ * Revision 1.1 1995/02/10 15:50:56 adam
+ * MARC interface implemented. Minor bugs fixed. fmltest can
+ * be used to format single MARC records. New function '\list'
+ * implemented.
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <fmlmarc.h>
+#include <iso2709p.h>
+
+#include "fmlp.h"
+
+struct fml_node *marc_to_fml (Fml fml, Iso2709Rec rec)
+{
+ struct fml_node *ptr_0 = NULL, *ptr_1;
+ struct iso2709_dir *dir;
+
+ for (dir = rec->directory; dir; dir=dir->next)
+ {
+ struct fml_node *ptr;
+
+ ptr = fml_node_alloc (fml);
+ if (ptr_0)
+ ptr_1->p[1] = ptr;
+ else
+ ptr_0 = ptr_1 = ptr;
+
+ ptr_1 = ptr;
+
+ if (dir->fields)
+ {
+ struct iso2709_field *fields = dir->fields;
+
+ ptr = fml_node_alloc (fml);
+ ptr->p[0] = fml_atom_alloc (fml, fields->data);
+ ptr->is_atom = 1;
+
+ while ((fields = fields->next))
+ {
+ ptr = ptr->p[0] = fml_node_alloc (fml);
+ ptr->p[0] = fml_atom_alloc (fml, fields->data);
+ ptr->is_atom = 1;
+ }
+ }
+ }
+ return ptr_0;
+}
+
+
+static void add_string (const char *str, char **buf, int *max, int *size)
+{
+ if (*size + strlen(str) >= *max)
+ {
+ char *nbuf;
+ int nsize = *size + strlen(str) + 2048;
+
+ nbuf = malloc (nsize);
+ assert (nbuf);
+ if (*buf)
+ strcpy (nbuf, *buf);
+ else
+ *nbuf = '\0';
+ free (*buf);
+ *buf = nbuf;
+ *max = nsize;
+ }
+ strcpy (*buf + *size, str);
+ *size += strlen(str);
+}
+
+char *marc_to_str (Fml fml, Iso2709Rec rec)
+{
+ struct iso2709_dir *dir;
+ static char *buf = NULL;
+ static int max = 0;
+ int size = 0;
+
+ add_string ("{", &buf, &max, &size);
+ for (dir = rec->directory; dir; dir=dir->next)
+ {
+ struct iso2709_field *fields;
+
+ add_string ("{", &buf, &max, &size);
+ add_string (dir->tag, &buf, &max, &size);
+ add_string ("{", &buf, &max, &size);
+
+ for (fields = dir->fields; fields; fields=fields->next)
+ {
+ add_string ("{", &buf, &max, &size);
+
+ if (fields->indicator)
+ {
+ add_string ("\'", &buf, &max, &size);
+ add_string (fields->indicator, &buf, &max, &size);
+ add_string ("\'", &buf, &max, &size);
+ }
+ else
+ add_string ("{}", &buf, &max, &size);
+ add_string (" ", &buf, &max, &size);
+ if (fields->identifier)
+ {
+ add_string ("\'", &buf, &max, &size);
+ add_string (fields->identifier, &buf, &max, &size);
+ add_string ("\'", &buf, &max, &size);
+ }
+ else
+ add_string ("{}", &buf, &max, &size);
+ add_string (" ", &buf, &max, &size);
+ add_string ("\'", &buf, &max, &size);
+ add_string (fields->data, &buf, &max, &size);
+ add_string ("\'", &buf, &max, &size);
+ add_string ("}", &buf, &max, &size);
+ }
+ add_string ("}}\n", &buf, &max, &size);
+ }
+ add_string ("}", &buf, &max, &size);
+ return buf;
+}