Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ksh93/sh/fcin.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1982-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* David Korn <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Routines to implement fast character input
23
*
24
* David Korn
25
* AT&T Labs
26
*
27
*/
28
29
#include <ast.h>
30
#include <sfio.h>
31
#include <error.h>
32
#include <fcin.h>
33
34
Fcin_t _Fcin = {0};
35
36
/*
37
* open stream <f> for fast character input
38
*/
39
int fcfopen(register Sfio_t* f)
40
{
41
register int n;
42
char *buff;
43
Fcin_t save;
44
errno = 0;
45
_Fcin.fcbuff = _Fcin.fcptr;
46
_Fcin._fcfile = f;
47
fcsave(&save);
48
if(!(buff=(char*)sfreserve(f,SF_UNBOUND,SF_LOCKR)))
49
{
50
fcrestore(&save);
51
_Fcin.fcchar = 0;
52
_Fcin.fcptr = _Fcin.fcbuff = &_Fcin.fcchar;
53
_Fcin.fclast = 0;
54
_Fcin._fcfile = (Sfio_t*)0;
55
return(EOF);
56
}
57
n = sfvalue(f);
58
fcrestore(&save);
59
sfread(f,buff,0);
60
_Fcin.fcoff = sftell(f);;
61
buff = (char*)sfreserve(f,SF_UNBOUND,SF_LOCKR);
62
_Fcin.fclast = (_Fcin.fcptr=_Fcin.fcbuff=(unsigned char*)buff)+n;
63
if(sffileno(f) >= 0)
64
*_Fcin.fclast = 0;
65
return(n);
66
}
67
68
69
/*
70
* With _Fcin.fcptr>_Fcin.fcbuff, the stream pointer is advanced and
71
* If _Fcin.fclast!=0, performs an sfreserve() for the next buffer.
72
* If a notify function has been set, it is called
73
* If last is non-zero, and the stream is a file, 0 is returned when
74
* the previous character is a 0 byte.
75
*/
76
int fcfill(void)
77
{
78
register int n;
79
register Sfio_t *f;
80
register unsigned char *last=_Fcin.fclast, *ptr=_Fcin.fcptr;
81
if(!(f=fcfile()))
82
{
83
/* see whether pointer has passed null byte */
84
if(ptr>_Fcin.fcbuff && *--ptr==0)
85
_Fcin.fcptr=ptr;
86
else
87
_Fcin.fcoff = 0;
88
return(0);
89
}
90
if(last)
91
{
92
if( ptr<last && ptr>_Fcin.fcbuff && *(ptr-1)==0)
93
return(0);
94
if(_Fcin.fcchar)
95
*last = _Fcin.fcchar;
96
if(ptr > last)
97
_Fcin.fcptr = ptr = last;
98
}
99
if((n = ptr-_Fcin.fcbuff) && _Fcin.fcfun)
100
(*_Fcin.fcfun)(f,(const char*)_Fcin.fcbuff,n,_Fcin.context);
101
sfread(f, (char*)_Fcin.fcbuff, n);
102
_Fcin.fcoff +=n;
103
_Fcin._fcfile = 0;
104
if(!last)
105
return(0);
106
else if(fcfopen(f) < 0)
107
return(EOF);
108
return(*_Fcin.fcptr++);
109
}
110
111
/*
112
* Synchronize and close the current stream
113
*/
114
int fcclose(void)
115
{
116
register unsigned char *ptr;
117
if(_Fcin.fclast==0)
118
return(0);
119
if((ptr=_Fcin.fcptr)>_Fcin.fcbuff && *(ptr-1)==0)
120
_Fcin.fcptr--;
121
if(_Fcin.fcchar)
122
*_Fcin.fclast = _Fcin.fcchar;
123
_Fcin.fclast = 0;
124
_Fcin.fcleft = 0;
125
return(fcfill());
126
}
127
128
/*
129
* Set the notify function that is called for each fcfill()
130
*/
131
void fcnotify(void (*fun)(Sfio_t*,const char*,int,void*),void* context)
132
{
133
_Fcin.fcfun = fun;
134
_Fcin.context = context;
135
}
136
137
#ifdef __EXPORT__
138
# define extern __EXPORT__
139
#endif
140
141
#undef fcsave
142
extern void fcsave(Fcin_t *fp)
143
{
144
*fp = _Fcin;
145
}
146
147
#undef fcrestore
148
extern void fcrestore(Fcin_t *fp)
149
{
150
_Fcin = *fp;
151
}
152
153
/* for testing purposes with small buffers */
154
#if defined(IOBSIZE) && (IOBSIZE < 2*MB_LEN_MAX)
155
# undef MB_LEN_MAX
156
# define MB_LEN_MAX (IOBSIZE/2)
157
#endif
158
159
struct Extra
160
{
161
unsigned char buff[2*MB_LEN_MAX];
162
unsigned char *next;
163
};
164
165
int _fcmbget(short *len)
166
{
167
static struct Extra extra;
168
register int i, c, n;
169
if(_Fcin.fcleft)
170
{
171
if((c = mbsize(extra.next)) < 0)
172
c = 1;
173
if((_Fcin.fcleft -= c) <=0)
174
{
175
_Fcin.fcptr = (unsigned char*)fcfirst() - _Fcin.fcleft;
176
_Fcin.fcleft = 0;
177
}
178
*len = c;
179
if(c==1)
180
c = *extra.next++;
181
else if(c==0)
182
_Fcin.fcleft = 0;
183
else
184
c = mbchar(extra.next);
185
return(c);
186
}
187
switch(*len = mbsize(_Fcin.fcptr))
188
{
189
case -1:
190
if(_Fcin._fcfile && (n=(_Fcin.fclast-_Fcin.fcptr)) < MB_LEN_MAX)
191
{
192
memcpy(extra.buff, _Fcin.fcptr, n);
193
_Fcin.fcptr = _Fcin.fclast;
194
for(i=n; i < MB_LEN_MAX+n; i++)
195
{
196
if((extra.buff[i] = fcgetc(c))==0)
197
break;
198
}
199
_Fcin.fcleft = n;
200
extra.next = extra.buff;
201
return(fcmbget(len));
202
}
203
*len = 1;
204
/* fall through */
205
case 0:
206
case 1:
207
c=fcget();
208
break;
209
default:
210
c = mbchar(_Fcin.fcptr);
211
}
212
return(c);
213
}
214
215
216