#include #include #include #include #include #include "list.h" static char *mystrdup(char *s) /* * A quick implementation of strdup() */ { char *copy; if ( (copy = (char *)malloc(strlen(s)+1)) != NULL ) strcpy(copy,s); return copy; } Node *nodeList = nil; void destroy_node_list() { Node *n,*m; for(n=nodeList;!isNil(n);) { m = cdr(n); free(n); n = m; } } static Node *create_node (int type) { Node *n; if (isNil(nodeList)) { n = (Node *) malloc(sizeof(Node)); } else { n = nodeList; nodeList = cdr(nodeList); } if (! isNil(n)){ n->type = type; n->val.list.head = nil; n->val.list.tail = nil; } return n; } static void free_node (Node *n) { if (isNil(n)) ; else { n->type = Node_List; /* entries on the nodeList are ALWAYS lists */ n->val.list.head = nil; n->val.list.tail = nodeList; nodeList = n; } } #define create_node_list() create_node(Node_List) #define create_node_atom() create_node(Node_Atom) void destroy_list (Node *n) { if (isNil(n)) ; else if (isAtom(n)){ free(atomVal(n)); /* free the atom here */ free_node(n); } else { destroy_list(car(n)); destroy_list(cdr(n)); free_node(n); } } Node *copy_list(Node *n) { Node *new; if (isNil(n)) new = nil; else if (isAtom(n)){ new = create_node_atom(); new->val.atom.ptr = mystrdup(atomVal(n)); } else { new = create_node_list(); new->val.list.head = copy_list(car(n)); new->val.list.tail = copy_list(cdr(n)); } return new; } Node *atom_str(char *s) { Node *new; new = create_node_atom(); new->val.atom.ptr = mystrdup(s); return new; } Node *atom_int(int i) { char buffer[200]; sprintf(buffer,"%d",i); return atom_str(buffer); } Node *build_list(Node *n1, ...) { Node *root; Node *next; Node *ROOT; va_list ap; va_start(ap, n1); root = ROOT = create_node_list(); /* * no action if n1 is nil * we are trying to construct '()' */ if (! isNil(n1)) { root->val.list.head = n1; next = va_arg(ap, Node *); while (! isNil(next)) { Node *new; new = create_node_list(); new->val.list.head = next; root->val.list.tail = new; root = new; next = va_arg(ap, Node *); } } va_end(ap); return ROOT; } Node *tail_list(Node *n) { Node *tail; if (isNil(n)) tail = nil; else if (isAtom(n)) tail = nil; else { for ( tail = n; !isNil(cdr(tail)); tail = cdr(tail)) ; } return tail; } Node *join_list(Node *n1,...) { Node *tail; Node *ROOT; Node *next; va_list ap; va_start(ap, n1); ROOT = n1; tail = tail_list(ROOT); next = va_arg(ap, Node *); while (! isNil(next)) { Node *newtail; newtail = tail_list(next); tail->val.list.tail = next; tail = newtail; next = va_arg(ap, Node *); } va_end(ap); return ROOT; } static void _print_list (Node *n) { if ( isNil(n) ) { printf("nil "); } else if (isAtom(n)) printf("%s ", atomVal(n)); else { Node *next; printf("( "); for (next = n; ! isNil(next); next = cdr(next)) _print_list(car(next)); printf(") "); } } void print_list (Node *n) { _print_list(n); nl; } static void printAtom(FILE *f, Atom *n) { char *val = atomVal(n); char *q; for (q=val; *q && !(isspace(*q)) && *q!='"' && *q!='(' && *q!=')'; q++); if (*q) putc('"',f); for (; *val; val++) { if (*val=='"') putc('"',f); putc(*val,f); } if (*q) putc('"',f); } static void _print_list_f (FILE *f,Node *n,int level) { if ( isNil(n) ) { fprintf(f,"nil "); } else if (isAtom(n)) { printAtom(f,n); fprintf(f," "); } else { Node *next; int i; if (level) fprintf(f,"\n"); for (i=0;ival.list.head = item; if (isNil(l)) l = m; if (isNil(t)) t = m; else { t->val.list.tail = m; t = m; } } if (isNil(l)) l = create_node_list(); } else { l = atom_str(s); } return l; }