Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / sfio / sfgetr.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: sfgetr.c /main/3 1995/11/01 18:29:52 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46 #include        "sfhdr.h"
47
48 /*      Read a record delineated by a character.
49 **      The record length can be accessed via sfslen().
50 **      Note that the reg declarations below must be kept in
51 **      their relative order so that the code will configured
52 **      correctly on Vaxes to use "asm()".
53 **
54 **      Written by Kiem-Phong Vo (06/27/90)
55 */
56
57 #if __STD_C
58 char* sfgetr(reg Sfio_t *f, reg int rc, int string)
59 #else
60 char* sfgetr(f,rc,string)
61 reg Sfio_t*     f;      /* stream to read from. r11 on vax              */
62 reg int         rc;     /* record separator. r10 on Vax                 */
63 int             string; /* <0: get last, 0: rc as is, 1: rc to nul      */
64 #endif
65 {
66         reg int         n;              /* r9 on vax            */
67         reg uchar       *s, *ends, *us; /* r8, r7, r6 on vax    */
68         reg int         un, found;
69         reg Sfrsrv_t*   frs;
70
71         /* buffer to be returned */
72         frs = NIL(Sfrsrv_t*);
73         us = NIL(uchar*);
74         un = 0;
75         found = 0;
76
77         /* restore the byte changed by the last getr */
78         if(f->mode&SF_GETR)
79         {       f->mode &= ~SF_GETR;
80                 f->next[-1] = f->getr;
81         }
82
83         /* set the right mode */
84         if(rc < 0 || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0) )
85                 goto done;
86
87         SFLOCK(f,0);
88
89         if(string < 0) /* return the previously read string only */
90         {       if((frs = _sfrsrv(f,0)) && (un = -frs->slen) > 0)
91                 {       us = frs->data;
92                         found = 1;
93                 }
94                 goto done;
95         }
96
97         while(!found)
98         {       /* fill buffer if necessary */
99                 if((n = (ends = f->endb) - (s = f->next)) <= 0)
100                 {       /* for unseekable devices, peek-read 1 record */
101                         f->getr = rc;
102                         f->mode |= SF_RC;
103
104                         /* fill buffer the conventional way */
105                         if(SFRPEEK(f,s,n) <= 0)
106                         {       us = NIL(uchar*);
107                                 goto done;
108                         }
109                         else
110                         {       ends = s+n;
111                                 if(f->mode&SF_RC)
112                                 {       s = ends[-1] == rc ? ends-1 : ends;
113                                         goto do_copy;
114                                 }
115                         }
116                 }
117
118 #if _vax_asm    /* rc is r10, n is r9, s is r8, ends is r7 */
119                 asm( "locc      r10,r9,(r8)" ); /* find rc */
120                 asm( "movl      r1,r8" );       /* set s to be where it is */
121 #else
122 #if _lib_memchr
123                 if(!(s = (uchar*)memchr((char*)s,rc,n)))
124                         s = ends;
125 #else
126                 while(s < ends)
127                 {       if(*s++ == rc)
128                         {       s -= 1;
129                                 break;
130                         }
131                 }
132 #endif
133 #endif
134         do_copy:
135                 if(s < ends)
136                 {       s += 1;         /* include the separator */
137                         found = 1;
138                         if(!us && (!string || !(f->flags&(SF_STRING|SF_BOTH))) )
139                         {       /* just returning the buffer */
140                                 us = f->next;
141                                 un = s - f->next;
142                                 f->next = s;
143                                 goto done;
144                         }
145                 }
146
147                 /* amount to be read */
148                 n = s - f->next;
149
150                 /* get internal buffer */
151                 if(!frs || frs->size < un+n+1)
152                 {       if(frs)
153                                 frs->slen = un;
154                         if((frs = _sfrsrv(f,un+n+1)) != NIL(Sfrsrv_t*))
155                                 us = frs->data;
156                         else
157                         {       us = NIL(uchar*);
158                                 goto done;
159                         }
160                 }
161
162                 /* now copy data */
163                 s = us+un;
164                 un += n;
165                 ends = f->next;
166                 f->next += n;
167 #if vax_asm
168                 asm( "movc3     r9,(r7),(r8)" );
169 #else
170                 MEMCPY(s,ends,n);
171 #endif
172         }
173
174 done:
175         _Sfi = un;
176         if(found && string > 0)
177         {       us[un-1] = '\0';
178                 if(us >= f->data && us < f->endb)
179                 {       f->getr = rc;
180                         f->mode |= SF_GETR;
181                 }
182         }
183
184         /* prepare for a call with string < 0 */
185         if(frs)
186                 frs->slen = found ? 0 : -un;
187
188         SFOPEN(f,0);
189         return (char*)us;
190 }