nopt.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. #ifndef NORCSID
  2. static char rcsid2[] = "$Id$";
  3. #endif
  4. #include "nopt.h"
  5. extern struct dfa OO_checknext[]; /* Initialized in dfa.c */
  6. extern struct dfa *OO_base[]; /* Initialized in dfa.c */
  7. extern struct dodefault OO_default[]; /* Initialized in dfa.c */
  8. extern int OO_maxpattern; /* Initialized in dfa.c */
  9. extern int OO_maxreplacement; /* Initialized in dfa.c */
  10. extern int (*OO_ftrans[])(); /* Initialized in trans.c */
  11. extern char em_mnem[][4];
  12. extern char em_pseu[][4];
  13. int OO_state = 0;
  14. p_instr OO_buffer;
  15. p_instr OO_patternqueue;
  16. p_instr OO_nxtpatt;
  17. p_instr OO_endbackup;
  18. p_instr OO_nxtrepl;
  19. static p_instr OO_replqueue;
  20. static char *filename;
  21. static char *strqueue;
  22. static char *nextstr;
  23. static char *laststr;
  24. arith OO_WSIZE; /* wordlength */
  25. arith OO_DWSIZE; /* 2*wordlength */
  26. arith OO_PSIZE; /* pointer length */
  27. #ifdef STATS
  28. int OO_wrstats = 1; /* pattern statistics output */
  29. #endif
  30. #ifdef DEBUG
  31. #define printstate(s) dumpstate(s)
  32. #else
  33. #define printstate(s)
  34. #endif /* DEBUG */
  35. /**** WHICH IS FASTER? ****
  36. #define BTSCPY(pp,qq,i,p,q,n) btscpy(p,q,(n)*sizeof(struct e_instr))
  37. **************************/
  38. #define BTSCPY(pp,qq,i,p,q,n) for(pp=(p),qq=(q),i=(n);i--;*pp++ = *qq++)
  39. PRIVATE void allocmem();
  40. void
  41. O_init(wsize,psize)
  42. arith wsize, psize;
  43. {
  44. allocmem();
  45. C_init(wsize,psize);
  46. OO_WSIZE = wsize;
  47. OO_DWSIZE = 2*wsize;
  48. OO_PSIZE = psize;
  49. }
  50. int
  51. O_open(fname)
  52. char *fname;
  53. {
  54. filename = fname;
  55. return(C_open(fname));
  56. }
  57. void
  58. O_magic()
  59. {
  60. C_magic();
  61. }
  62. void
  63. O_close()
  64. {
  65. C_close();
  66. }
  67. void
  68. OO_dfa(last)
  69. register int last;
  70. {
  71. register struct dfa *b;
  72. register struct dodefault *d;
  73. register int (*f)();
  74. for(;;) {
  75. printstate("OO_dfa");
  76. if((b=OO_base[OO_state]) && ((b += last)->check==OO_state)) {
  77. if(f=OO_ftrans[OO_state = b->next]) (*f)();
  78. }
  79. else if (OO_state) {
  80. /* consult default entry */
  81. d = &OO_default[OO_state];
  82. if(!OO_endbackup) OO_endbackup = OO_nxtpatt;
  83. OO_nxtpatt--;
  84. OO_patternqueue += d->numout;
  85. if(f=OO_ftrans[OO_state = d->next]) (*f)();
  86. }
  87. else OO_flush();
  88. if (!OO_endbackup) return;
  89. last = (OO_nxtpatt++)->em_opcode;
  90. if (OO_nxtpatt >= OO_endbackup)
  91. OO_endbackup = 0;
  92. }
  93. }
  94. PRIVATE void
  95. fatal(s,a)
  96. char *s;
  97. int a;
  98. {
  99. fprint(STDERR, "%s: ", filename ? filename : "standard input");
  100. fprint(STDERR,s,a);
  101. fprint(STDERR,"\n");
  102. sys_stop(S_EXIT);
  103. }
  104. PRIVATE void
  105. allocmem()
  106. {
  107. /* Allocate memory for queues on heap */
  108. OO_buffer = (p_instr)
  109. Malloc((unsigned)(MAXBUFFER*sizeof(struct e_instr)));
  110. OO_patternqueue = OO_nxtpatt = OO_buffer;
  111. OO_replqueue = (p_instr)
  112. Malloc((unsigned)OO_maxreplacement*sizeof(struct e_instr));
  113. OO_nxtrepl = OO_replqueue;
  114. nextstr = strqueue =
  115. (char *)Malloc(MAXSTRING*sizeof(char));
  116. laststr = strqueue + MAXSTRING - 1;
  117. }
  118. char *
  119. OO_freestr(str)
  120. char *str;
  121. {
  122. register char *s = str;
  123. register char *res;
  124. while (*s++);
  125. again:
  126. if ((s-str) > (laststr-nextstr)) {
  127. unsigned newsize = (laststr - strqueue + 1)*2;
  128. res = Realloc(strqueue,newsize);
  129. laststr = res + newsize - 1;
  130. nextstr = res + (nextstr - strqueue);
  131. strqueue = res;
  132. #ifdef DEBUG
  133. fprintf(stderr,"Warning: Reallocated string area.");
  134. fprintf(stderr,"New size is %d bytes\n", newsize);
  135. #endif
  136. goto again;
  137. }
  138. res=nextstr;
  139. for(s=str;*nextstr++ = *s++;);
  140. return(res);
  141. }
  142. void
  143. OO_flush()
  144. {
  145. /*
  146. /* Output all instructions waiting in the output queue and free their
  147. /* storage including the saved strings.
  148. */
  149. register p_instr p,q;
  150. register int i,n;
  151. printstate("Flush");
  152. for(p=OO_buffer;p<OO_patternqueue;p++)
  153. C_out(p);
  154. if(p->em_opcode!=OTHER)
  155. C_out(p);
  156. if(OO_endbackup) {
  157. n = OO_endbackup-OO_nxtpatt;
  158. BTSCPY(p,q,i,OO_buffer,OO_nxtpatt,n);
  159. OO_endbackup = OO_buffer + n;
  160. }
  161. else nextstr = strqueue;
  162. OO_patternqueue = OO_nxtpatt = OO_buffer;
  163. }
  164. p_instr
  165. OO_halfflush()
  166. {
  167. /*
  168. /* Called when buffer full, flush half the buffer and move the
  169. /* the pattern pointers to the new positions. Return a pointer
  170. /* to the new nxtpatt position and increment it.
  171. /* Note that OO_endbackup is always NIL (i.e. there are no
  172. /* instructions on the backup queue) when this is invoked.
  173. */
  174. register int i,n;
  175. register p_instr p,q;
  176. printstate("Half flush");
  177. n = MAXBUFFER / 2;
  178. for(p=OO_buffer,i=n;i--;)
  179. C_out(p++);
  180. /* now copy the rest of buffer and pattern back */
  181. BTSCPY(p,q,i,OO_buffer,OO_buffer+n,(OO_nxtpatt-OO_buffer)-n);
  182. OO_patternqueue -= n;
  183. OO_nxtpatt -= n;
  184. printstate("after Half flush");
  185. return (OO_nxtpatt++);
  186. }
  187. void
  188. OO_mkext(p,opcode,arg,off)
  189. register p_instr p;
  190. int opcode;
  191. p_instr arg;
  192. arith off;
  193. {
  194. switch(arg->em_argtype) {
  195. case cst_ptyp:
  196. EM_mkcst(p,opcode,off);
  197. break;
  198. case sof_ptyp:
  199. EM_mksof(p,opcode,arg->em_dnam,off);
  200. break;
  201. case nof_ptyp:
  202. EM_mknof(p,opcode,arg->em_dlb,off);
  203. break;
  204. default:
  205. fatal("Unexpected type %d in outext",arg->em_argtype);
  206. }
  207. }
  208. void
  209. OO_mkrepl(lrepl,diff,numbkup)
  210. int lrepl,diff,numbkup;
  211. {
  212. /* copy the replacement queue into the buffer queue */
  213. /* then move the pattern queue back n places */
  214. register p_instr p,q;
  215. register int i;
  216. printstate("Before backup");
  217. if(OO_endbackup) {
  218. /* move the region between OO_nxtpatt and OO_endbackup */
  219. if (diff > 0) {
  220. /* move left by diff */
  221. BTSCPY(p,q,i,OO_nxtpatt-diff,OO_nxtpatt,OO_endbackup-OO_nxtpatt);
  222. OO_nxtpatt -= diff;
  223. OO_endbackup -= diff;
  224. }
  225. else if (diff < 0) {
  226. /* move right by diff */
  227. /* careful of overflowing buffer!! */
  228. if ((OO_nxtpatt-diff)> (OO_buffer+MAXBUFFER) )
  229. OO_halfflush();
  230. /* cannot use btscpy as strings may overlap */
  231. p = (q=OO_endbackup-1) - diff;
  232. while(q>=OO_nxtpatt)
  233. *p-- = *q--;
  234. OO_nxtpatt -= diff;
  235. OO_endbackup -= diff;
  236. }
  237. }
  238. /* copy the replacement */
  239. if (lrepl) {
  240. BTSCPY(p,q,i,OO_patternqueue,OO_replqueue,lrepl);
  241. OO_nxtrepl = OO_replqueue;
  242. OO_patternqueue += lrepl;
  243. }
  244. /* now move the position of interest back nunbkup instructions */
  245. if ((OO_patternqueue-OO_buffer) < numbkup)
  246. numbkup = (OO_patternqueue-OO_buffer);
  247. OO_nxtpatt = OO_patternqueue -= numbkup;
  248. if(!OO_endbackup && numbkup)
  249. OO_endbackup = OO_patternqueue+numbkup;
  250. OO_state = 0;
  251. printstate("After backup");
  252. }
  253. #ifdef DEBUG
  254. void
  255. dumpstate(mess)
  256. char *mess;
  257. {
  258. p_instr p;
  259. fprintf(stderr,"%s - state(%d): ",mess,OO_state);
  260. p = OO_buffer;
  261. while(p<OO_patternqueue)
  262. prtinst(p++);
  263. fprintf(stderr," |==| ");
  264. while(p<OO_nxtpatt)
  265. prtinst(p++);
  266. fprintf(stderr," |==| ");
  267. if(OO_endbackup) {
  268. while(p<OO_endbackup)
  269. prtinst(p++);
  270. }
  271. fprintf(stderr,"\n");
  272. }
  273. void
  274. prtinst(p)
  275. p_instr p;
  276. {
  277. switch(p->em_type) {
  278. case EM_MNEM:
  279. fprintf(stderr,"%s ",em_mnem[p->em_opcode-sp_fmnem]);
  280. break;
  281. case EM_PSEU:
  282. fprintf(stderr,"%s ",em_pseu[p->em_opcode-sp_fpseu]);
  283. break;
  284. case EM_STARTMES:
  285. case EM_MESARG:
  286. case EM_ENDMES:
  287. fprintf(stderr,"MES ");
  288. break;
  289. case EM_DEFILB:
  290. fprintf(stderr,"%ld ", (long)p->em_ilb);
  291. return;
  292. case EM_DEFDLB:
  293. fprintf(stderr,"%ld ", (long)p->em_dlb);
  294. return;
  295. case EM_DEFDNAM:
  296. fprintf(stderr,"%d ", p->em_dnam);
  297. return;
  298. case EM_ERROR:
  299. case EM_FATAL:
  300. case EM_EOF:
  301. return;
  302. }
  303. switch(p->em_argtype) {
  304. case 0:
  305. break;
  306. case cst_ptyp:
  307. fprintf(stderr,"%d ",p->em_cst);
  308. break;
  309. case nof_ptyp:
  310. fprintf(stderr,".%d+%d ",p->em_dlb,p->em_off);
  311. break;
  312. case sof_ptyp:
  313. fprintf(stderr,"%s+%d ",p->em_dnam,p->em_off);
  314. break;
  315. case ilb_ptyp:
  316. fprintf(stderr,"*%d ",p->em_ilb);
  317. break;
  318. case pro_ptyp:
  319. fprintf(stderr,"$%s ",p->em_pnam);
  320. break;
  321. case str_ptyp:
  322. case ico_ptyp:
  323. case uco_ptyp:
  324. fprintf(stderr,"\"%s\"",p->em_string);
  325. break;
  326. default:
  327. fatal(" prtinst - Unregognized arg %d ",p->em_argtype);
  328. }
  329. }
  330. #endif