/* * Deep Blue C linker ver. 1.1 subrs */#define luse 128#define ldef 129#define bcon 130#define wcon 131#define rdat 132#define ladr 133#define dspc 134#define lext 135#define lglb 136#define BSIZE 5000#include "clinkg"ps(s)char *s;$(cprints(s);$)pl(s)char *s;$(ps(s);putchar(eol);$)gfname(s,i)char *s;int i;$(int j;char c;while(1)$(j=0;while((c = cgetc(i)) > 0)$(putchar(c);if(c==eol)$(if(j==0)continue; /*blank line*/else break;$)else s[j++]=c;$)if(j)$(s[j]=0;if(s[0]==';') /* comment */continue;normalize(s,"CCC");return 1;$)else return 0;$)$)pass1()$(char c,buf[BSIZE],*b,*e;int i;/* no cc0 & cc1 is for string lits */cbp[0]=cbp[1]=1;  /* read in file */if(bgetchr(buf,BSIZE,&i))return;b=buf;e=buf+i;while(b<e)$(if((c=*b++)<128)++pc;else switch(c)$(case luse:case wcon:case ladr:b+=2;pc+=2;break;case bcon:++b;      ++pc;break;case dspc:pc=pc+b[0]+(b[1]<<8);b+=2;break;case rdat:pc+=(i=b[0]+(b[1]<<8));b+=(i+2);break;case ldef:if((i=b[0]+(b[1]<<8))>=gmin)vbp[i-gmin]=pc;else cbp[i]=pc;b+=2;break;case lglb:case lext:i=b[0]+(b[1]<<8)-gmin;b+=2;b+=1+strcpy(stab+sptr*symsiz,b);slink[sptr]=vbp-vtab+i;/* link will index off ofvtab, not vbp! */if(c==lglb)type[sptr]=global;else$(type[sptr]=external;vbp[i]=i+1; /* mark as used (no ldef) */$)if(++sptr>maxsym)error("Too many globals\n");break;default:error("bad byte code.\n");break;$)$)if(b!=e)error("bad CCC file\n");$)/* Get the whole file at once * (return non-zero if error) */bgetchr(buf,max,len)char *buf;int max,*len;$(int i;if((i=ciov(input,7,buf,max,-1,-1))>0)$(error("CCC file too large\n");return 1;$)else if(i!=-136)$(ioerror("can't read file",".CCC file",i);return 1;$)else$(*len=dpeek(0x348+(input<<4));return 0;$)$)error(s)char *s;$(ps("error ");ps(s);++errcnt;$)ioerror(kind,name,val)char *kind,*name;int val;$(++errcnt;printf("[%s]%s:%d\n",name,kind,-val);$)flush()$(int i;if(bptr==0)$(bad=pc;return;$)pad(bad);pad(bad+bptr-1);i=0;while(bptr--)pby(buf[i++]);bad=pc;bptr=0;$)pad(a)int a;$(pby(a & 255);pby((a >> 8) & 255);$)pby(b)char b;$(cputc(b,output);$)ws(s)char *s;$(while(*s)wb(*s++);$)wa(a)int a;$(wb(a & 255);wb((a >> 8) & 255);$)wb(b)char b;$(buf[bptr]=b;++pc;if(++bptr >= block)flush();$)pass2()$(char c,buf[BSIZE],*b,*e;int i,lbase;lbase=cbp[1]; /* cc1 */if(bgetchr(buf,BSIZE,&i))return;b=buf;e=buf+i;while(b<e)$(if((c=*b++) < 128)wb(c);else switch(c)$(case bcon:wb(*b++);break;case wcon:wb(b[0]);wb(b[1]);b+=2;break;case ladr:wa(lbase+b[0]+(b[1]<<8));b+=2;break;case ldef:b+=2; /* skip it */break;case luse:if((i=b[0]+(b[1]<<8)) < gmin)wa(cbp[i]);else wa(vbp[i-gmin]);b+=2;break;case rdat:i=b[0]+(b[1]<<8);b+=2;while(i-- > 0)wb(*b++);break;case dspc:pc+=b[0]+(b[1]<<8);b+=2;flush();break;case lglb:case lext:b+=find(b+2,BSIZE,0)+3;break;default:error("bad op code\n");break;$)$)if(b!=e)error("bad CCC code\n");$)