/*LINTLIBRARY*/ #include #include "net.h" /* useful subroutines for dealing with network */ char *ttype[NTTYPES] = { "n-channel", "p-channel", "depletion", "pullup", "resistor", "capacitor" }; #define HASHSIZE 731 char *pnode(); nptr hash[HASHSIZE]; /* hashing function used in interning symbols */ char lcase[128] = { 0, 01, 02, 03, 04, 05, 06, 07, 010, 011, 012, 013, 014, 015, 016, 017, 020, 021, 022, 023, 024, 025, 026, 027, 030, 031, 032, 033, 034, 035, 036, 037, ' ', '!', '"', '#', '$', '%', '&', 047, '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', 0134, ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0177 }; int sym_hash(name,hashsize) register char *name; { register int hashcode = 0; while (*name) hashcode = (hashcode*10 + lcase[*name++] - '0') % hashsize; return (hashcode<0 ? hashcode+hashsize : hashcode); } /* compare two strings, case doesn't matter */ int str_eql(p,q) register char *p,*q; { while (*p) if (lcase[*p++] != lcase[*q++]) return(0); return (*q == 0); } /* compare pattern with string, case doesn't matter. "*" wildcard accepted */ int str_match(p,s) register char *p,*s; { while (1) { if (*p == '*') { /* skip past multiple wildcards */ do p++; while (*p == '*'); /* if pattern ends with wild card, automatic match */ if (*p == 0) return(1); /* *p now points to first non-wildcard character, find matching * character in string, then recursively match remaining pattern. * if recursive match fails, assume current '*' matches more... */ while (*s != 0) { while (lcase[*s] != lcase[*p]) if (*s++ == 0) return(0); if (str_match(p+1,++s)) return(1); } /* couldn't find matching character after '*', no match */ return(0); } else if (*p == 0) return(*s == 0); else if (lcase[*p++] != lcase[*s++]) return(0); } } /* find node in network */ nptr find(name) register char *name; { register nptr ntemp; register unsigned num = numberp(name); for (ntemp = hash[sym_hash(name,HASHSIZE)]; ntemp != 0; ntemp = ntemp->hnext) if ((ntemp->nflags&NAMED && str_eql(name,ntemp->nname)) || (char *)num==ntemp->nname) { while (ntemp->nflags & ALIAS) ntemp = ntemp->nlink; return(ntemp); } return(0); } /* insert node into hash table */ n_insert(n) register nptr n; { register int temp; register char *name; name = pnode(n); temp = sym_hash(name,HASHSIZE); n->hnext = hash[temp]; hash[temp] = n; } /* visit each node in network, calling function passed as arg with current node */ walk_net(fun) int (*fun)(); { register int index; register nptr n; int total = 0; for (index=0; indexhnext) total += (*fun)(n); return(total); } /* visit each node in network, calling function passed as arg with any node * whose name matches pattern */ match_net(pattern,fun,arg) char *pattern; int (*fun)(); int arg; { register int index; register nptr n; int total = 0; for (index=0; indexhnext) if (str_match(pattern,pnode(n))) total += (*fun)(n,arg); return(total); } /* see if asciz string is an integer -- if so, return it; otherwise return 0 */ numberp(s) register char *s; { register unsigned num = 0; register unsigned temp; if (*s == '0') return(0); /* if it starts with zero, forget it */ while (*s) { if (*s>='0' && *s<='9') { temp = num*10 + *s - '0'; if (temp < num) return(0); else num = temp; } else return(0); s++; } return(num); } /* return pointer to asciz name of node */ char *pnode(n) register nptr n; { static char number[50]; if (n == NULL) return("(null)"); if (n->nflags & NAMED) return(n->nname); sprintf(number,"%ld",(long)n->nname); return(number); } /* initialize hash table */ init_hash() { register int i; for (i = 0; i < HASHSIZE; i += 1) hash[i] = NULL; }