/* cif.c * last revised at 15, October, 1995 * * Copyright (C) 1994-5, All rights reserved. * written by Gyudong Kim(chilly@iclab.snu.ac.kr) * * may make weird result from damaged cif file. * every cell should have a name with '9' extension of magic for cell name * */ #include "findhier.h" extern FILE *dbfile; extern char *dbname; extern struct branch *trees; extern struct branch *subtop; extern struct names *nametop; extern int (*mystrcmp)(); static struct branch *ciftop = (struct branch *)NULL; static char buf[BUFSIZE]; /* * cif input routine -! not general */ static char *get_cif_line(cif) FILE *cif; { int i=0; int c; while((c=fgetc(cif))!=EOF) { switch (c) { case '(': seek_char(')',cif); break; case ';': if (i) { buf[i]=0; return(buf); } break; case 'P': case 'p': if (!i) seek_char(';',cif); else { buf[i]=c; i++; } break; case ' ': case '\t': case '\n': if (!i) break; c=' '; default: buf[i]=c; i++; break; } if (i>=BUFSIZE-1) { buf[i]=0; warning("Too long line \n^[[7m%s[[m\n detected. Truncated.\n", buf); seek_char(';',cif); return(buf); } } if (buf[0]!='E') return(NULL); buf[i]=0; return(buf); } static void new_cell(i) int i; { struct names *tmp; for(tmp=nametop;tmp!=NULL;tmp=tmp->next) if (i==tmp->num) return; tmp=(struct names *)myalloc(sizeof(struct names),"cif"); tmp->num = i; tmp->name = (char *)NULL; tmp->next = nametop; nametop = tmp; } static void putcif(name) char *name; { nametop->name = (char *)myalloc((SIZE)((strlen(name)+1)*sizeof(char)),"putcif"); (void)strcpy(nametop->name,name); } void cif_init() { char *tmp; char *tok; int open=0; while ((tmp=get_cif_line(dbfile))!=NULL) switch (tmp[0]) { case 'E': (void)rewind(dbfile); return; case 'D': switch (tmp[1]) { case 'S': if (open) { warning("%cnested declaration not supported.\n",7); break; } open=1; tok=strtok(tmp+2," \t\n"); new_cell(atoi(tok)); break; case 'F': open=0; default: break; } break; case '9': /* magic extention of cif */ switch (tmp[1]) { case ' ': tok=strtok(tmp+2," \t\n"); putcif(tok); break; case '1': /* instance name - ignored */ case '4': /* label - ignored */ case '5': /* labeled area - ignored */ default: break; } default: break; } warning("Incomplete CIF file %s\n",dbname); (void)rewind(dbfile); return; } static char *cif_name(id) int id; { struct names *tmp; if (id==-1) { new_cell(id); putcif(CIFTOP); return(nametop->name); } for(tmp=nametop;tmp!=NULL;tmp=tmp->next) if (id==tmp->num) return(tmp->name); new_cell(id); (void)sprintf(buf,"%d",id); putcif(buf); vacant(nametop->name); return(nametop->name); } char *cif_global(name,pname) char *name,*pname; { struct names *tmp; int minid = -2; for(tmp=nametop;tmp!=NULL;tmp=tmp->next) if (!(*mystrcmp)(tmp->name,name)) return(tmp->name); if (!glob_error(name,pname)) return((char *)NULL); for(tmp=nametop;tmp!=NULL;tmp=tmp->next) if (tmp->numnum-1; new_cell(minid); (void)sprintf(buf,"%d",minid); putcif(buf); vacant(nametop->name); return(nametop->name); } void cif_tree() { struct branch *parent = NULL; struct branch *root = NULL; char *tmp; char *cellname; char *tok; while ((tmp=get_cif_line(dbfile))!=NULL) switch (tmp[0]) { case 'E': goto return_point; case 'D': switch (tmp[1]) { case 'S': if (parent) { warning("%cnested declaration not supported.\n",7); return; } parent = (struct branch *) myalloc(sizeof(struct branch),"cif_tree"); tok=strtok(tmp+2," \t\n"); parent->name = cif_name(atoi(tok)); parent->next = trees; trees = parent; break; case 'F': parent->offspring = subtop; subtop = (struct branch *)NULL; parent = (struct branch *)NULL; default: break; } break; case 'C': tok=strtok(tmp+1," \t\n"); cellname = cif_name(atoi(tok)); if (cellname==NULL) { warning("Invalid cell number %d.\n",atoi(tok)); break; } if (parent) { if (cellname !=NULL) add_cell(cellname,parent->name,&subtop); } else { if (root==NULL) { root = (struct branch *) myalloc(sizeof(struct branch),"cif_tree"); root->name = cif_name(-1); } add_cell(cellname,root->name,&ciftop); } default: break; } return_point: if (root!=NULL) { root->offspring = ciftop; root->next = trees; trees = root; } (void)fclose(dbfile); return; } /* cif.c */