/* trees.c * last revised at 8, Apr. 1994 * * Copyright (C) 1994, All rights reserved. * written by Gyudong Kim(chilly@eleceng.adelaide.edu.au) * */ #include "findhier.h" extern struct names *nametop,*fhpath; extern FORMAT Format; extern FILE *dbfile; extern char EXT[5]; extern char *(*getcell)(); extern void (*set_tree)(); extern char *(*mycase)(); struct branch *trees = (struct branch *)NULL; struct branch *subtop = (struct branch *)NULL; void add_cell(buf,pname,mytop) char *buf,*pname; struct branch **mytop; { struct branch *tmp; char *nbuf; nbuf = global(buf,pname); if (nbuf == pname) { bell(); warning("self recursion found in %s.\n",pname); return; } for(tmp = *mytop;tmp!=NULL;tmp=tmp->next) { if (tmp->name==nbuf) return; } tmp = (struct branch *)myalloc(sizeof(struct branch),"add_cell"); tmp->name = nbuf; tmp->offspring = (struct branch *)NULL; tmp->next = *mytop; (*mytop) = tmp; } static void anal_cell(name) char *name; { FILE *mag; struct branch *parent; char *buf; struct names *pbuf; static char fname[BUFSIZE]; for(pbuf=fhpath;pbuf!=NULL;pbuf=pbuf->next) { (void)sprintf(fname,"%s/%s%s",pbuf->name,name,EXT); if (Format==PCSTR) mag = fopen(fname,OPENMODE); else mag = fopen(fname,"r"); if (mag != NULL) break; } if (mag == NULL) { bell(); warning("input file [%s",name); warning("%s] Permission Denied.\n",EXT); return; } while((buf=(*getcell)(mag))!=NULL) if (buf[0]!=0) add_cell(buf,name,&subtop); (void)fclose(mag); parent = (struct branch *)myalloc(sizeof(struct branch),"anal_cell"); parent->name = name; parent->offspring = subtop; subtop = (struct branch *)NULL; /* clean subtop but not free */ parent->next = trees; trees = parent; } /* * tree reversal function == path_reversal * This is a general singly linked list reversal routine. */ static void tree_reversal(topbr) struct branch **topbr; { struct branch *tmp,*save,*prev; prev = (struct branch *)NULL; for(tmp=(*topbr);tmp!=NULL;) { save = tmp->next; tmp->next = prev; prev = tmp; tmp = save; } (*topbr) = prev; } static void tree_reverse(parent) struct branch *parent; { struct branch *bros; for (bros = parent;bros != NULL;bros = bros->next) { tree_reversal(&(bros->offspring)); tree_reverse(bros->offspring); } } void make_tree() { struct names *tmp; struct branch *parent,*offs,*save; int TOP; switch (Format) { case MAGIC: case PCSTR: case TeX: for(tmp=nametop;tmp!=NULL;tmp=tmp->next) { if (!isvacant(tmp->name)) anal_cell(tmp->name); } break; case CIF: case GDSII: case VALID: (*set_tree)(); break; default: break; } if (trees==NULL) no_target(); for (offs=trees;offs!=NULL;offs = offs->next) { for (parent=trees;parent!=NULL;parent=parent->next) { if (parent==offs) continue; if (find_parent(parent,offs->name)) graft(parent,offs); } } for (offs=trees;offs!=NULL;) { TOP = 1; for (parent=trees;parent!=NULL;parent=parent->next) { if (parent==offs) continue; if (find_parent(parent,offs->name)) { TOP = 0; break; } } if (!TOP) { save = offs->next; prune(offs); /* redundant topcells removal */ offs = save; /* offs will be invalidated in prune */ } else offs = offs->next; } tree_reverse(trees); if (Format!=CIF || trees->next || trees->offspring->next) return; if (trees->offspring->name==global(CIFTOP,"Main")) { save = trees->offspring->offspring; myfree(trees->offspring); trees->offspring=save; } } /* trees.c */