|
|
1.1 root 1: /*************************************************************************
2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is *
3: * provided to you without charge for use only on a licensed Unix *
4: * system. You may copy JOVE provided that this notice is included with *
5: * the copy. You may not sell copies of this program or versions *
6: * modified for use on microcomputer systems, unless the copies are *
7: * included with a Unix system distribution and the source is provided. *
8: *************************************************************************/
9:
10: #include "jove.h"
11: #include "io.h"
12: #include "ctype.h"
13: #include "temp.h"
14: #include "termcap.h"
15:
16: extern int BufSize;
17:
18: int OkayAbort,
19: tabstop = 8;
20:
21: int (*TTins_line)(),
22: (*TTdel_line)();
23:
24: struct scrimage
25: *DesiredScreen = 0,
26: *PhysScreen = 0;
27:
28: struct screenline *Screen = 0, /* the screen (a bunch of screenline) */
29: *Savelines = 0, /* another bunch (LI of them) */
30: *Curline = 0; /* current line */
31: char *cursor, /* offset into current Line */
32: *cursend;
33:
34: int CapCol,
35: CapLine,
36:
37: i_line,
38: i_col;
39:
40: make_scr()
41: {
42: register int i;
43: register struct screenline *ns;
44: register char *nsp;
45:
46: #ifdef RESHAPING
47: /* In case we are RESHAPING the window! */
48: if (DesiredScreen)
49: free((char *) DesiredScreen);
50: if (PhysScreen)
51: free((char *) PhysScreen);
52: if (Savelines)
53: free((char *) Savelines);
54: if (Screen) {
55: ns = Screen;
56: for (i = 0; i < LI; i++)
57: free((ns++)->s_line);
58: free((char *) Screen);
59: }
60: #endif RESHAPING
61:
62: DesiredScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
63: PhysScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
64:
65: Savelines = (struct screenline *)
66: malloc((unsigned) LI * sizeof(struct screenline));
67: ns = Screen = (struct screenline *)
68: malloc((unsigned) LI * sizeof(struct screenline));
69:
70: nsp = (char *) malloc((unsigned)CO * LI);
71: if (nsp == 0) {
72: printf("\n\rCannot malloc screen!\n");
73: finish(1);
74: }
75:
76: for (i = 0; i < LI; i++) {
77: ns->s_line = nsp;
78: nsp += CO;
79: ns->s_length = nsp - 1; /* End of Line */
80: ns++;
81: }
82: cl_scr(0);
83: }
84:
85: clrline(cp1, cp2)
86: register char *cp1,
87: *cp2;
88: {
89: while (cp1 <= cp2)
90: *cp1++ = ' ';
91: }
92:
93: #define sputc(c) ((*cursor != (char) (c)) ? dosputc(c) : (cursor++, i_col++))
94: #define soutputc(c) if (--n <= 0) break; else sputc(c)
95:
96: cl_eol()
97: {
98: if (cursor > cursend)
99: return;
100:
101: if (cursor < Curline->s_length) {
102: if (CE) {
103: Placur(i_line, i_col);
104: putpad(CE, 1);
105: clrline(cursor, Curline->s_length);
106: } else {
107: /* Ugh. The slow way for dumb terminals. */
108: register char *savecp = cursor;
109:
110: while (cursor <= Curline->s_length)
111: sputc(' ');
112: cursor = savecp;
113: }
114: Curline->s_length = cursor;
115: }
116: }
117:
118: cl_scr(doit)
119: {
120: register int i;
121: register struct screenline *sp = Screen;
122:
123: for (i = 0; i < LI; i++, sp++) {
124: clrline(sp->s_line, sp->s_length);
125: sp->s_length = sp->s_line;
126: PhysScreen[i].s_id = 0;
127: }
128: if (doit) {
129: putpad(CL, LI);
130: CapCol = CapLine = 0;
131: UpdMesg++;
132: }
133: }
134:
135: #ifdef ID_CHAR
136: extern int IN_INSmode;
137: #endif
138:
139: /* Output one character (if necessary) at the current position */
140:
141: dosputc(c)
142: register char c;
143: {
144: if (*cursor != c) {
145: #ifdef ID_CHAR
146: if (IN_INSmode)
147: INSmode(0);
148: #endif
149: if (i_line != CapLine || i_col != CapCol)
150: Placur(i_line, i_col);
151: if (UL && (c & 0177) == '_' && (*cursor & 0177) != ' ')
152: putstr(" \b"); /* Erase so '_' looks right. */
153: *cursor++ = c;
154: putchar(c & 0177);
155: CapCol++;
156: i_col++;
157: } else {
158: cursor++;
159: i_col++;
160: }
161: }
162:
163: /* Write `line' at the current position of `cursor'. Stop when we
164: reach the end of the screen. Aborts if there is a character
165: waiting. */
166:
167: swrite(line, inversep, abortable)
168: register char *line;
169: register int abortable;
170: {
171: register int c;
172: int col = i_col,
173: aborted = 0;
174: register int n = cursend - cursor;
175: int or_byte = inversep ? 0200 : 0,
176: thebyte;
177:
178: if (n <= 0)
179: return 1;
180:
181: OkayAbort = 0;
182: while (c = *line++) {
183: if (abortable && OkayAbort) {
184: OkayAbort = NO;
185: if (InputPending = charp()) {
186: aborted = 1;
187: break;
188: }
189: }
190: if (c == '\t') {
191: int nchars;
192:
193: nchars = (tabstop - (col % tabstop));
194: col += nchars;
195:
196: thebyte = (' ' | or_byte);
197: while (nchars--)
198: soutputc(thebyte);
199: if (n <= 0)
200: break;
201: } else if (isctrl(c)) {
202: thebyte = ('^' | or_byte);
203: soutputc(thebyte);
204: thebyte = (((c == '\177') ? '?' : c + '@') | or_byte);
205: soutputc(thebyte);
206: col += 2;
207: } else {
208: thebyte = (c | or_byte);
209: soutputc(thebyte);
210: col++;
211: }
212: }
213: if (n <= 0) {
214: thebyte = ('!' | or_byte);
215: sputc(thebyte);
216: }
217: if (cursor > Curline->s_length)
218: Curline->s_length = cursor;
219: return !aborted;
220: }
221:
222: /* This is for writing a buffer line to the screen. This is to
223: minimize the amount of copying from one buffer to another buffer.
224: This gets the info directly from the disk buffers. */
225:
226: BufSwrite(linenum)
227: {
228: char *bp;
229: register int n = cursend - cursor,
230: col = 0,
231: c;
232: int StartCol = DesiredScreen[linenum].s_offset,
233: visspace = DesiredScreen[linenum].s_window->w_visspace,
234: aborted = 0;
235:
236: bp = lcontents(DesiredScreen[linenum].s_lp);
237: if (*bp) for (;;) {
238: if (col >= StartCol) {
239: DesiredScreen[linenum].s_offset = col;
240: break;
241: }
242:
243: c = *bp++ & 0177;
244: if (c == '\t')
245: col += (tabstop - (col % tabstop));
246: else if (isctrl(c))
247: col += 2;
248: else
249: col++;
250: }
251:
252: OkayAbort = 0;
253: while (c = (*bp++ & 0177)) {
254: if (OkayAbort) {
255: OkayAbort = NO;
256: if (InputPending = charp()) {
257: aborted = 1;
258: break;
259: }
260: }
261: if (c == '\t') {
262: int nchars = (tabstop - (col % tabstop));
263:
264: col += nchars;
265: if (visspace) {
266: soutputc('>');
267: nchars--;
268: }
269: while (--nchars >= 0)
270: soutputc(' ');
271: if (n <= 0)
272: break;
273: } else if (isctrl(c)) {
274: soutputc('^');
275: soutputc((c == '\177') ? '?' : c + '@');
276: col += 2;
277: } else {
278: if (visspace && c == ' ')
279: c = '_';
280: soutputc(c);
281: col++;
282: }
283: }
284: if (n <= 0)
285: sputc('!');
286: if (cursor > Curline->s_length)
287: Curline->s_length = cursor;
288: return !aborted; /* Didn't abort */
289: }
290:
291: i_set(nline, ncol)
292: register int nline,
293: ncol;
294: {
295: Curline = &Screen[nline];
296: cursor = Curline->s_line + ncol;
297: cursend = &Curline->s_line[CO - 1];
298: i_line = nline;
299: i_col = ncol;
300: }
301:
302: /* Insert `num' lines a top, but leave all the lines BELOW `bottom'
303: alone (at least they won't look any different when we are done).
304: This changes the screen array AND does the physical changes. */
305:
306: v_ins_line(num, top, bottom)
307: {
308: register int i;
309:
310: /* Save the screen pointers. */
311:
312: for(i = 0; i < num && top + i <= bottom; i++)
313: Savelines[i] = Screen[bottom - i];
314:
315: /* Num number of bottom lines will be lost.
316: Copy everything down num number of times. */
317:
318: for (i = bottom; i > top && i-num >= 0; i--)
319: Screen[i] = Screen[i - num];
320:
321: /* Restore the saved ones, making them blank. */
322:
323: for (i = 0; i < num; i++) {
324: Screen[top + i] = Savelines[i];
325: clrline(Screen[top + i].s_line, Screen[top + i].s_length);
326: Screen[top + i].s_length = Screen[top + i].s_line;
327: }
328:
329: (*TTins_line)(top, bottom, num);
330: }
331:
332: /* Delete `num' lines starting at `top' leaving the lines below `bottom'
333: alone. This updates the internal image as well as the physical image. */
334:
335: v_del_line(num, top, bottom)
336: {
337: register int i,
338: bot;
339:
340: bot = bottom;
341:
342: /* Save the lost lines. */
343:
344: for (i = 0; i < num && top + i <= bottom; i++)
345: Savelines[i] = Screen[top + i];
346:
347: /* Copy everything up num number of lines. */
348:
349: for (i = top; num + i <= bottom; i++)
350: Screen[i] = Screen[i + num];
351:
352: /* Restore the lost ones, clearing them. */
353:
354: for (i = 0; i < num; i++) {
355: Screen[bottom - i] = Savelines[i];
356: clrline(Screen[bot].s_line, Screen[bot].s_length);
357: Screen[bot].s_length = Screen[bot].s_line;
358: bot--;
359: }
360:
361: (*TTdel_line)(top, bottom, num);
362: }
363:
364:
365: /* The cursor optimization happens here. You may decide that this
366: is going too far with cursor optimization, or perhaps it should
367: limit the amount of checking to when the output speed is slow.
368: What ever turns you on ... */
369:
370: private struct cursaddr {
371: int c_numchars,
372: (*c_proc)();
373: };
374:
375: private char *Cmstr;
376: private struct cursaddr *HorMin,
377: *VertMin,
378: *DirectMin;
379:
380: private ForMotion(),
381: ForTab(),
382: BackMotion(),
383: RetTab(),
384: DownMotion(),
385: UpMotion(),
386: GoDirect(),
387: HomeGo(),
388: BottomUp();
389:
390:
391: private struct cursaddr WarpHor[] = {
392: 0, ForMotion,
393: 0, ForTab,
394: 0, BackMotion,
395: 0, RetTab
396: };
397:
398: private struct cursaddr WarpVert[] = {
399: 0, DownMotion,
400: 0, UpMotion
401: };
402:
403: private struct cursaddr WarpDirect[] = {
404: 0, GoDirect,
405: 0, HomeGo,
406: 0, BottomUp
407: };
408:
409: #undef FORWARD
410: #define FORWARD 0 /* Move forward */
411: #define FORTAB 1 /* Forward using tabs */
412: #undef BACKWARD
413: #define BACKWARD 2 /* Move backward */
414: #define RETFORWARD 3 /* Beginning of line and then tabs */
415: #define NUMHOR 4
416:
417: #define DOWN 0 /* Move down */
418: #define UPMOVE 1 /* Move up */
419: #define NUMVERT 2
420:
421: #define DIRECT 0 /* Using CM */
422: #define HOME 1 /* HOME */
423: #define LOWER 2 /* Lower Line */
424: #define NUMDIRECT 3
425:
426: #define home() Placur(0, 0)
427: #define LowLine() putpad(LL, 1), CapLine = ILI, CapCol = 0
428: #define PrintHo() putpad(HO, 1), CapLine = CapCol = 0
429:
430: int phystab = 8;
431:
432: private
433: GoDirect(line, col)
434: register int line,
435: col;
436: {
437: putpad(Cmstr, 1);
438: CapLine = line;
439: CapCol = col;
440: }
441:
442: private
443: RetTab(col)
444: register int col;
445: {
446: putchar('\r');
447: CapCol = 0;
448: ForTab(col);
449: }
450:
451: private
452: HomeGo(line, col)
453: {
454: PrintHo();
455: DownMotion(line);
456: ForTab(col);
457: }
458:
459: private
460: BottomUp(line, col)
461: register int line,
462: col;
463: {
464: LowLine();
465: UpMotion(line);
466: ForTab(col);
467: }
468:
469: /* Tries to move forward using tabs (if possible). It tabs to the
470: closest tabstop which means it may go past 'destcol' and backspace
471: to it. */
472:
473: private
474: ForTab(destcol)
475: int destcol;
476: {
477: register int tabgoal,
478: ntabs,
479: tabstp = phystab;
480:
481: if (TABS && (tabstp > 0)) {
482: tabgoal = destcol + (tabstp / 2);
483: tabgoal -= (tabgoal % tabstp);
484:
485: /* Don't tab to last place or else it is likely to screw up. */
486: if (tabgoal >= CO)
487: tabgoal -= tabstp;
488:
489: ntabs = (tabgoal / tabstp) - (CapCol / tabstp);
490: while (--ntabs >= 0)
491: putchar('\t');
492: CapCol = tabgoal;
493: }
494: if (CapCol > destcol)
495: BackMotion(destcol);
496: else if (CapCol < destcol)
497: ForMotion(destcol);
498: }
499:
500: private
501: ForMotion(destcol)
502: register int destcol;
503: {
504: register int nchars = destcol - CapCol;
505: register char *cp = &Screen[CapLine].s_line[CapCol];
506:
507: while (--nchars >= 0)
508: putchar(*cp++ & 0177);
509: CapCol = destcol;
510: }
511:
512: private
513: BackMotion(destcol)
514: register int destcol;
515: {
516: register int nchars = CapCol - destcol;
517:
518: if (BC)
519: while (--nchars >= 0)
520: putpad(BC, 1);
521: else
522: while (--nchars >= 0)
523: putchar('\b');
524: CapCol = destcol;
525: }
526:
527: private
528: DownMotion(destline)
529: register int destline;
530: {
531: register int nlines = destline - CapLine;
532:
533: while (--nlines >= 0)
534: putchar('\n');
535: CapLine = destline;
536: }
537:
538: private
539: UpMotion(destline)
540: register int destline;
541: {
542: register int nchars = CapLine - destline;
543:
544: while (--nchars >= 0)
545: putpad(UP, 1);
546: CapLine = destline;
547: }
548:
549: #ifdef ID_CHAR
550: static int EIlen;
551: #endif
552: extern int IMlen;
553:
554: InitCM()
555: {
556: HOlen = HO ? strlen(HO) : 1000;
557: LLlen = LL ? strlen(LL) : 1000;
558: UPlen = UP ? strlen(UP) : 1000;
559: #ifdef ID_CHAR
560: if (EI)
561: EIlen = strlen(EI);
562: #endif
563: }
564:
565: Placur(line, col)
566: {
567: int dline, /* Number of lines to move */
568: dcol; /* Number of columns to move */
569: register int best,
570: i;
571: register struct cursaddr *cp;
572: int xtracost = 0; /* Misc addition to cost. */
573:
574: #define CursMin(which,addrs,max) \
575: for (best = 0, cp = &addrs[1], i = 1; i < max; i++, cp++) \
576: if (cp->c_numchars < addrs[best].c_numchars) \
577: best = i; \
578: which = &addrs[best];
579:
580: if (line == CapLine && col == CapCol)
581: return; /* We are already there. */
582:
583: dline = line - CapLine;
584: dcol = col - CapCol;
585: #ifdef ID_CHAR
586: if (IN_INSmode && MI)
587: xtracost = EIlen + IMlen;
588: /* If we're already in insert mode, it is likely that we will
589: want to be in insert mode again, after the insert. */
590: #endif
591:
592: /* Number of characters to move horizontally for each case.
593: 1: Just move forward by typing the right character on the screen.
594: 2: Print the correct number of back spaces.
595: 3: Try tabbing to the correct place.
596: 4: Try going to the beginning of the line, and then tab. */
597:
598: if (dcol == 1 || dcol == 0) { /* Most common case. */
599: HorMin = &WarpHor[FORWARD];
600: HorMin->c_numchars = dcol + xtracost;
601: } else {
602: WarpHor[FORWARD].c_numchars = dcol >= 0 ? dcol + xtracost : 1000;
603: WarpHor[BACKWARD].c_numchars = dcol < 0 ? -(dcol + xtracost) : 1000;
604: WarpHor[FORTAB].c_numchars = dcol >= 0 && TABS ?
605: ForNum(CapCol, col) + xtracost : 1000;
606: WarpHor[RETFORWARD].c_numchars = (xtracost + 1 + (TABS ? ForNum(0, col) : col));
607:
608: /* Which is the shortest of the bunch */
609:
610: CursMin(HorMin, WarpHor, NUMHOR);
611: }
612:
613: /* Moving vertically is more simple. */
614:
615: WarpVert[DOWN].c_numchars = dline >= 0 ? dline : 1000;
616: WarpVert[UPMOVE].c_numchars = dline < 0 ? ((-dline) * UPlen) : 1000;
617:
618: /* Which of these is simpler */
619: CursMin(VertMin, WarpVert, NUMVERT);
620:
621: /* Homing first and lowering first are considered
622: direct motions.
623: Homing first's total is the sum of the cost of homing
624: and the sum of tabbing (if possible) to the right. */
625:
626: if (VertMin->c_numchars + HorMin->c_numchars <= 3) {
627: DirectMin = &WarpDirect[DIRECT]; /* A dummy ... */
628: DirectMin->c_numchars = 100;
629: } else {
630: WarpDirect[DIRECT].c_numchars = CM ?
631: strlen(Cmstr = tgoto(CM, col, line)) : 1000;
632: WarpDirect[HOME].c_numchars = HOlen + line +
633: WarpHor[RETFORWARD].c_numchars;
634: WarpDirect[LOWER].c_numchars = LLlen + ((ILI - line) * UPlen) +
635: WarpHor[RETFORWARD].c_numchars;
636: CursMin(DirectMin, WarpDirect, NUMDIRECT);
637: }
638:
639: if (HorMin->c_numchars + VertMin->c_numchars < DirectMin->c_numchars) {
640: if (line != CapLine)
641: (*VertMin->c_proc)(line);
642: if (col != CapCol) {
643: #ifdef ID_CHAR
644: if (IN_INSmode) /* We may use real characters ... */
645: INSmode(0);
646: #endif
647: (*HorMin->c_proc)(col);
648: }
649: } else {
650: #ifdef ID_CHAR
651: if (IN_INSmode && !MI)
652: INSmode(0);
653: #endif
654: (*DirectMin->c_proc)(line, col);
655: }
656: }
657:
658: #define abs(x) ((x) >= 0 ? (x) : -(x))
659:
660: ForNum(from, to)
661: register int from;
662: {
663: register int tabgoal,
664: tabstp = phystab;
665: int numchars = 0;
666:
667: if (from >= to)
668: return from - to;
669: if (TABS && (tabstp > 0)) {
670: tabgoal = to + (tabstp / 2);
671: tabgoal -= (tabgoal % tabstp);
672: if (tabgoal >= CO)
673: tabgoal -= tabstp;
674: numchars = (tabgoal / tabstop) - (from / tabstp);
675: from = tabgoal;
676: }
677: return numchars + abs(from - to);
678: }
679:
680: #ifdef WIRED_TERMS
681:
682: BGi_lines(top, bottom, num)
683: {
684: printf("\033[%d;%dr\033[%dL\033[r", top + 1, bottom + 1, num);
685: CapCol = CapLine = 0;
686: }
687:
688: SUNi_lines(top, bottom, num)
689: {
690: Placur(bottom - num + 1, 0);
691: printf("\033[%dM", num);
692: Placur(top, 0);
693: printf("\033[%dL", num);
694: }
695:
696: C100i_lines(top, bottom, num)
697: {
698: if (num <= 1) {
699: GENi_lines(top, bottom, num);
700: return;
701: }
702: printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO);
703: CapLine = CapCol = 0;
704: Placur(top, 0);
705: while (num--)
706: putpad(AL, ILI - CapLine);
707: printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO);
708: CapLine = CapCol = 0;
709: }
710:
711: #endif WIRED_TERMS
712:
713: GENi_lines(top, bottom, num)
714: {
715: register int i;
716:
717: if (CS) {
718: printf(tgoto(CS, bottom, top));
719: CapCol = CapLine = 0;
720: Placur(top, 0);
721: for (i = 0; i < num; i++)
722: putpad(SR, bottom - top);
723: printf(tgoto(CS, ILI, 0));
724: CapCol = CapLine = 0;
725: } else {
726: Placur(bottom - num + 1, 0);
727: if (M_DL && (num > 1)) {
728: char minibuf[16];
729:
730: sprintf(minibuf, M_DL, num);
731: putpad(minibuf, ILI - CapLine);
732: } else {
733: for (i = 0; i < num; i++)
734: putpad(DL, ILI - CapLine);
735: }
736: Placur(top, 0);
737: if (M_AL && (num > 1)) {
738: char minibuf[16];
739:
740: sprintf(minibuf, M_AL, num);
741: putpad(minibuf, ILI - CapLine);
742: } else {
743: for (i = 0; i < num; i++)
744: putpad(AL, ILI - CapLine);
745: }
746: }
747: }
748:
749: #ifdef WIRED_TERMS
750:
751: BGd_lines(top, bottom, num)
752: {
753: printf("\033[%d;%dr\033[%dM\033[r", top + 1, bottom + 1, num);
754: CapCol = CapLine = 0;
755: }
756:
757: SUNd_lines(top, bottom, num)
758: {
759: Placur(top, 0);
760: printf("\033[%dM", num);
761: Placur(bottom + 1 - num, 0);
762: printf("\033[%dL", num);
763: }
764:
765: C100d_lines(top, bottom, num)
766: {
767: if (num <= 1) {
768: GENd_lines(top, bottom, num);
769: return;
770: }
771: printf("\033v%c%c%c%c", ' ', ' ', ' ' + bottom + 1, ' ' + CO);
772: CapLine = CapCol = 0;
773: Placur(top, 0);
774: while (num--)
775: putpad(DL, ILI - CapLine);
776: printf("\033v%c%c%c%c", ' ', ' ', ' ' + LI, ' ' + CO);
777: CapLine = CapCol = 0;
778: }
779:
780: #endif WIRED_TERMS
781:
782: GENd_lines(top, bottom, num)
783: {
784: register int i;
785:
786: if (CS) {
787: printf(tgoto(CS, bottom, top));
788: CapCol = CapLine = 0;
789: Placur(bottom, 0);
790: for (i = 0; i < num; i++)
791: putpad(SF, bottom - top);
792: printf(tgoto(CS, ILI, 0));
793: CapCol = CapLine = 0;
794: } else {
795: Placur(top, 0);
796: if (M_DL && (num > 1)) {
797: char minibuf[16];
798:
799: sprintf(minibuf, M_DL, num);
800: putpad(minibuf, ILI - top);
801: } else {
802: for (i = 0; i < num; i++)
803: putpad(DL, ILI - top);
804: }
805: Placur(bottom + 1 - num, 0);
806: if (M_AL && (num > 1)) {
807: char minibuf[16];
808:
809: sprintf(minibuf, M_AL, num);
810: putpad(minibuf, ILI - CapLine);
811: } else {
812: for (i = 0; i < num; i++)
813: putpad(AL, ILI - CapLine);
814: }
815: }
816: }
817:
818: struct ID_lookup {
819: char *ID_name;
820: int (*I_proc)(); /* proc to insert lines */
821: int (*D_proc)(); /* proc to delete lines */
822: } ID_trms[] = {
823: "generic", GENi_lines, GENd_lines, /* This should stay here */
824: #ifdef WIRED_TERMS
825: "sun", SUNi_lines, SUNd_lines,
826: "bg", BGi_lines, BGd_lines,
827: "c1", C100i_lines, C100d_lines,
828: #endif WIRED_TERMS
829: 0, 0, 0
830: };
831:
832: IDline_setup(tname)
833: char *tname;
834: {
835: register struct ID_lookup *idp;
836:
837: for (idp = &ID_trms[1]; idp->ID_name; idp++)
838: if (strncmp(idp->ID_name, tname, strlen(idp->ID_name)) == 0)
839: break;
840: if (idp->ID_name == 0)
841: idp = &ID_trms[0];
842: TTins_line = idp->I_proc;
843: TTdel_line = idp->D_proc;
844: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.