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