dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libast / common / sfio / sfgetr.c
blob6d422692f5e4e0c7fb56a3c9935ed3fdd1bd6a05
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #include "sfhdr.h"
24 /* Read a record delineated by a character.
25 ** The record length can be accessed via sfvalue(f).
27 ** Written by Kiem-Phong Vo
30 #if __STD_C
31 char* sfgetr(Sfio_t *f, int rc, int type)
32 #else
33 char* sfgetr(f,rc,type)
34 Sfio_t* f; /* stream to read from */
35 int rc; /* record separator */
36 int type;
37 #endif
39 ssize_t n, un;
40 uchar *s, *ends, *us;
41 int found;
42 Sfrsrv_t* rsrv;
43 SFMTXDECL(f);
45 SFMTXENTER(f, NIL(char*));
47 if(rc < 0 || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0) )
48 SFMTXRETURN(f, NIL(char*));
49 SFLOCK(f,0);
51 /* buffer to be returned */
52 rsrv = NIL(Sfrsrv_t*);
53 us = NIL(uchar*);
54 un = 0;
55 found = 0;
57 /* compatibility mode */
58 type = type < 0 ? SF_LASTR : type == 1 ? SF_STRING : type;
60 if(type&SF_LASTR) /* return the broken record */
61 { if((f->flags&SF_STRING) && (un = f->endb - f->next))
62 { us = f->next;
63 f->next = f->endb;
64 found = 1;
66 else if((rsrv = f->rsrv) && (un = -rsrv->slen) > 0)
67 { us = rsrv->data;
68 found = 1;
70 goto done;
73 while(!found)
74 { /* fill buffer if necessary */
75 if((n = (ends = f->endb) - (s = f->next)) <= 0)
76 { /* for unseekable devices, peek-read 1 record */
77 f->getr = rc;
78 f->mode |= SF_RC;
80 /* fill buffer the conventional way */
81 if(SFRPEEK(f,s,n) <= 0)
82 { us = NIL(uchar*);
83 goto done;
85 else
86 { ends = s+n;
87 if(f->mode&SF_RC)
88 { s = ends[-1] == rc ? ends-1 : ends;
89 goto do_copy;
94 #if _lib_memchr
95 if(!(s = (uchar*)memchr((char*)s,rc,n)))
96 s = ends;
97 #else
98 while(*s != rc)
99 if((s += 1) == ends)
100 break;
101 #endif
102 do_copy:
103 if(s < ends) /* found separator */
104 { s += 1; /* include the separator */
105 found = 1;
107 if(!us &&
108 (!(type&SF_STRING) || !(f->flags&SF_STRING) ||
109 ((f->flags&SF_STRING) && (f->bits&SF_BOTH) ) ) )
110 { /* returning data in buffer */
111 us = f->next;
112 un = s - f->next;
113 f->next = s;
114 goto done;
118 /* amount to be read */
119 n = s - f->next;
121 if(!found && (_Sfmaxr > 0 && un+n+1 >= _Sfmaxr || (f->flags&SF_STRING))) /* already exceed limit */
122 { us = NIL(uchar*);
123 goto done;
126 /* get internal buffer */
127 if(!rsrv || rsrv->size < un+n+1)
128 { if(rsrv)
129 rsrv->slen = un;
130 if((rsrv = _sfrsrv(f,un+n+1)) != NIL(Sfrsrv_t*))
131 us = rsrv->data;
132 else
133 { us = NIL(uchar*);
134 goto done;
138 /* now copy data */
139 s = us+un;
140 un += n;
141 ends = f->next;
142 f->next += n;
143 MEMCPY(s,ends,n);
146 done:
147 _Sfi = f->val = un;
148 f->getr = 0;
149 if(found && rc != 0 && (type&SF_STRING) )
150 { us[un-1] = '\0';
151 if(us >= f->data && us < f->endb)
152 { f->getr = rc;
153 f->mode |= SF_GETR;
157 /* prepare for a call to get the broken record */
158 if(rsrv)
159 rsrv->slen = found ? 0 : -un;
161 SFOPEN(f,0);
163 if(us && (type&SF_LOCKR) )
164 { f->mode |= SF_PEEK|SF_GETR;
165 f->endr = f->data;
168 SFMTXRETURN(f, (char*)us);