1 /*****************************************************************************
2
3 RdLine()
4
5 This function reads a line from the current input file into the
6 edit buffer. The input is placed into the edit buffer by appending it
7 to the edit buffer and adjusting the EBfEnd pointer. IBfEnd points to the
8 last byte of allocated, unused memory at the end of the edit buffer.
9
10 *****************************************************************************/
11
12 #include "zport.h" /* define portability identifiers */
13 #include "tecoc.h" /* define general identifiers */
14 #include "defext.h" /* define external global variables */
15 #include "deferr.h" /* define identifiers for error messages */
16 #include "dchars.h" /* define identifiers for characters */
17
18 /*
19 * The input buffer needs to be expanded. If there's room in the edit buffer
20 * gap, then we can shuffle memory to steal some room from the gap. If
21 * there's still not enough room in the input buffer we re-allocate the
22 * entire edit/input buffer and then adjust the pointers to reflect the
23 * reallcatin. If the reallocation fails, set EBfFul to TRUE.
24 */
25
26 #if USE_PROTOTYPES
expand_ibf(BOOLEAN * EBfFul)27 static void expand_ibf(BOOLEAN *EBfFul)
28 #else
29 static void expand_ibf(EBfFul)
30 BOOLEAN *EBfFul; /* indicates edit buffer full */
31 #endif
32 {
33 SIZE_T TmpSiz;
34 SIZE_T NewSiz;
35 charptr NewBeg;
36
37 DBGFEN(3,"expabd_ibf",NULL);
38
39 /*
40 * If the size of the edit buffer gap exceeds GAPMIN, make it GAPMIN and
41 * add the leftover space to the input buffer.
42 *
43 * from: EbfBeg...GapBeg<GAPMIN><slack>GapEnd...EBfEnd...IBfEnd
44 * to: EbfBeg...GapBeg<GAPMIN>GapEnd...EBfEnd...<slack>IBfEnd
45 */
46 TmpSiz = GapEnd-GapBeg+1;
47 if (TmpSiz > GAPMIN) {
48 TmpSiz -= GAPMIN;
49 MEMMOVE(GapEnd+1-TmpSiz, GapEnd+1, (SIZE_T)(EBfEnd-GapEnd));
50 GapEnd -= TmpSiz;
51 EBfEnd -= TmpSiz;
52 }
53 /*
54 * If there's still not enough room in the input buffer, expand the input
55 * buffer by reallocating everything. Since reallocating is expensive,
56 * take this opportunity to expand it by IBFEXP bytes more than what we
57 * need.
58 *
59 * from: EbfBeg...GapBeg...GapEnd...EBfEnd<TmpSiz>IBfEnd
60 * to: EbfBeg...GapBeg...GapEnd...EBfEnd<IBFMIN+IBFEXP>IBfEnd
61 */
62 TmpSiz = IBfEnd-EBfEnd;
63 if (TmpSiz < IBFMIN) {
64 NewSiz = (IBfEnd-EBfBeg+1) + (IBFMIN-TmpSiz) + IBFEXP;
65 #if DEBUGGING
66 sprintf(DbgSBf,"ZRaloc-ing EBf, NewSiz = %ld", NewSiz);
67 DbgFMs(3,DbgFNm,DbgSBf);
68 #endif
69 NewBeg = (charptr)ZRaloc(EBfBeg, NewSiz);
70 if (NewBeg == NULL) {
71 *EBfFul = TRUE; /* we're full: stop reading lines */
72 } else {
73 if (NewBeg != EBfBeg) { /* if ZRaloc moved us, adjust ptrs */
74 GapBeg = NewBeg + (GapBeg - EBfBeg);
75 GapEnd = NewBeg + (GapEnd - EBfBeg);
76 EBfEnd = NewBeg + (EBfEnd - EBfBeg);
77 EBfBeg = NewBeg;
78 }
79 IBfEnd = (NewBeg + NewSiz) - 1;
80 }
81 }
82 DBGFEX(3,DbgFNm,NULL);
83 }
84
85
RdLine(EBfFul)86 DEFAULT RdLine(EBfFul) /* read a line */
87 BOOLEAN *EBfFul;
88 {
89 DEFAULT length;
90
91 DBGFEN(3,"RdLine",NULL);
92
93 FFPage = 0; /* clear the form-feed flag */
94
95 if (!IsOpnI[CurInp]) { /* if current input stream not open */
96 ErrMsg(ERR_NFI); /* NFI = "no file for input" */
97 DBGFEX(3,DbgFNm,"FAILURE, no file for input");
98 return FAILURE;
99 }
100
101 if (IsEofI[CurInp]) { /* if already at end-of-file */
102 DBGFEX(3,DbgFNm,"SUCCESS, already at eof");
103 return SUCCESS;
104 }
105
106 /*
107 * Before trying to read the next line from the input file, we have to be
108 * sure there's enough room for the record. IBFMIN is the minimum amount of
109 * room to provide when reading a record. If there's not IBFMIN bytes
110 * available, we have to get more room.
111 */
112 if ((IBfEnd-EBfEnd) < IBFMIN) { /* if not enough room */
113 expand_ibf(EBfFul);
114 }
115
116 /*
117 * Read the line from the input file.
118 */
119 if (*EBfFul == FALSE) {
120 if (ZRdLin(EBfEnd+1, IBfEnd-EBfEnd, CurInp, &length) == FAILURE) {
121 ErrMsg(ERR_URL); /* unable to read line */
122 DBGFEX(3,DbgFNm,"FAILURE, ZRdLin() failed");
123 return FAILURE;
124 }
125 if (!IsEofI[CurInp]) { /* if not end-of-file */
126 EBfEnd += length;
127 }
128 }
129
130 DBGFEX(3,DbgFNm,"SUCCESS, final");
131 return SUCCESS;
132 }
133