This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
PATCH std stdio for (Free)BSD
[metaconfig.git] / U / compline / d_stdstdio.U
1 ?RCS: $Id: d_stdstdio.U,v 3.0.1.3 1997/02/28 15:46:32 ram Exp $
2 ?RCS:
3 ?RCS: Copyright (c) 1991-1993, Raphael Manfredi
4 ?RCS: 
5 ?RCS: You may redistribute only under the terms of the Artistic Licence,
6 ?RCS: as specified in the README file that comes with the distribution.
7 ?RCS: You may reuse parts of this distribution only within the terms of
8 ?RCS: that same Artistic Licence; a copy of which may be found at the root
9 ?RCS: of the source tree for dist 3.0.
10 ?RCS:
11 ?RCS: Original Author: Tye McQueen <tye@metronet.com>
12 ?RCS:
13 ?RCS: $Log: d_stdstdio.U,v $
14 ?RCS: Revision 3.0.1.3  1997/02/28  15:46:32  ram
15 ?RCS: patch61: merged with perl5's unit
16 ?RCS:
17 ?RCS: Revision 3.0.1.2  1995/07/25  14:06:54  ram
18 ?RCS: patch56: typo fix on ?C: line for FILE_bufsiz
19 ?RCS: patch56: fixed unbalanced parenthesis (ADO)
20 ?RCS: patch56: check whether FILE_cnt and FILE_ptr can be assigned to (ADO)
21 ?RCS:
22 ?RCS: Revision 3.0.1.1  1995/05/12  12:12:11  ram
23 ?RCS: patch54: complete rewrite by Tye McQueen to fit modern systems
24 ?RCS:
25 ?RCS: Revision 3.0  1993/08/18  12:07:31  ram
26 ?RCS: Baseline for dist 3.0 netwide release.
27 ?RCS:
28 ?MAKE:d_stdstdio d_stdiobase stdio_ptr stdio_cnt \
29         d_stdio_ptr_lval_sets_cnt d_stdio_ptr_lval_nochange_cnt stdio_base \
30         stdio_bufsiz d_stdio_cnt_lval d_stdio_ptr_lval stdio_filbuf: cat \
31         Compile contains rm exe_ext \
32         Setvar Findhdr Oldconfig
33 ?MAKE:  -pick weed $@ %<
34 ?S:d_stdstdio:
35 ?S:     This variable conditionally defines USE_STDIO_PTR if this system
36 ?S:     has a FILE structure declaring usable _ptr and _cnt fields (or
37 ?S:     equivalent) in stdio.h.
38 ?S:.
39 ?S:stdio_ptr:
40 ?S:     This variable defines how, given a FILE pointer, fp, to access the
41 ?S:     _ptr field (or equivalent) of stdio.h's FILE structure.  This will
42 ?S:     be used to define the macro FILE_ptr(fp).
43 ?S:.
44 ?S:d_stdio_ptr_lval:
45 ?S:     This variable conditionally defines STDIO_PTR_LVALUE if the
46 ?S:     FILE_ptr macro can be used as an lvalue.
47 ?S:.
48 ?S:stdio_cnt:
49 ?S:     This variable defines how, given a FILE pointer, fp, to access the
50 ?S:     _cnt field (or equivalent) of stdio.h's FILE structure.  This will
51 ?S:     be used to define the macro FILE_cnt(fp).
52 ?S:.
53 ?S:d_stdio_cnt_lval:
54 ?S:     This variable conditionally defines STDIO_CNT_LVALUE if the
55 ?S:     FILE_cnt macro can be used as an lvalue.
56 ?S:.
57 ?S:d_stdio_ptr_lval_sets_cnt:
58 ?S:     This symbol is defined if using the FILE_ptr macro as an lvalue
59 ?S:     to increase the pointer by n has the side effect of decreasing the
60 ?S:     value of File_cnt(fp) by n.
61 ?S:.
62 ?S:d_stdio_ptr_lval_nochange_cnt:
63 ?S:     This symbol is defined if using the FILE_ptr macro as an lvalue
64 ?S:     to increase the pointer by n leaves File_cnt(fp) unchanged.
65 ?S:.
66 ?S:stdio_filbuf:
67 ?S:     This variable defines how, given a FILE pointer, fp, to tell
68 ?S:     stdio to refill it's internal buffers (?).  This will
69 ?S:     be used to define the macro FILE_filbuf(fp).
70 ?S:.
71 ?S:d_stdiobase:
72 ?S:     This variable conditionally defines USE_STDIO_BASE if this system
73 ?S:     has a FILE structure declaring a usable _base field (or equivalent)
74 ?S:     in stdio.h.
75 ?S:.
76 ?S:stdio_base:
77 ?S:     This variable defines how, given a FILE pointer, fp, to access the
78 ?S:     _base field (or equivalent) of stdio.h's FILE structure.  This will
79 ?S:     be used to define the macro FILE_base(fp).
80 ?S:.
81 ?S:stdio_bufsiz:
82 ?S:     This variable defines how, given a FILE pointer, fp, to determine
83 ?S:     the number of bytes store in the I/O buffer pointer to by the
84 ?S:     _base field (or equivalent) of stdio.h's FILE structure.  This will
85 ?S:     be used to define the macro FILE_bufsiz(fp).
86 ?S:.
87 ?C:USE_STDIO_PTR ~ d_stdstdio (USE_STD_STDIO STDSTDIO):
88 ?C:     This symbol is defined if the _ptr and _cnt fields (or similar)
89 ?C:     of the stdio FILE structure can be used to access the stdio buffer
90 ?C:     for a file handle.  If this is defined, then the FILE_ptr(fp)
91 ?C:     and FILE_cnt(fp) macros will also be defined and should be used
92 ?C:     to access these fields.
93 ?C:.
94 ?C:FILE_ptr:
95 ?C:     This macro is used to access the _ptr field (or equivalent) of the
96 ?C:     FILE structure pointed to by its argument. This macro will always be
97 ?C:     defined if USE_STDIO_PTR is defined.
98 ?C:.
99 ?C:STDIO_PTR_LVALUE:
100 ?C:     This symbol is defined if the FILE_ptr macro can be used as an
101 ?C:     lvalue.
102 ?C:.
103 ?C:FILE_cnt:
104 ?C:     This macro is used to access the _cnt field (or equivalent) of the
105 ?C:     FILE structure pointed to by its argument. This macro will always be
106 ?C:     defined if USE_STDIO_PTR is defined.
107 ?C:.
108 ?C:STDIO_CNT_LVALUE:
109 ?C:     This symbol is defined if the FILE_cnt macro can be used as an
110 ?C:     lvalue.
111 ?C:.
112 ?C:STDIO_PTR_LVAL_SETS_CNT:
113 ?C:     This symbol is defined if using the FILE_ptr macro as an lvalue
114 ?C:     to increase the pointer by n has the side effect of decreasing the
115 ?C:     value of File_cnt(fp) by n.
116 ?C:.
117 ?C:STDIO_PTR_LVAL_NOCHANGE_CNT:
118 ?C:     This symbol is defined if using the FILE_ptr macro as an lvalue
119 ?C:     to increase the pointer by n leaves File_cnt(fp) unchanged.
120 ?C:.
121 ?C:FILE_filbuf:
122 ?C:     This macro is used to access the internal stdio _filbuf function
123 ?C:     (or equivalent), if STDIO_CNT_LVALUE and STDIO_PTR_LVALUE
124 ?C:     are defined.  It is typically either _filbuf or __filbuf.
125 ?C:     This macro will only be defined if both STDIO_CNT_LVALUE and
126 ?C:     STDIO_PTR_LVALUE are defined.
127 ?C:.
128 ?H:?d_stdstdio:#$d_stdstdio USE_STDIO_PTR       /**/
129 ?H:?d_stdstdio:#ifdef USE_STDIO_PTR
130 ?H:#define FILE_ptr(fp) $stdio_ptr
131 ?H:#$d_stdio_ptr_lval STDIO_PTR_LVALUE          /**/
132 ?H:#define FILE_cnt(fp) $stdio_cnt
133 ?H:#$d_stdio_cnt_lval STDIO_CNT_LVALUE          /**/
134 ?H:#$d_stdio_ptr_lval_sets_cnt STDIO_PTR_LVAL_SETS_CNT  /**/
135 ?H:#$d_stdio_ptr_lval_nochange_cnt STDIO_PTR_LVAL_NOCHANGE_CNT  /**/
136 ?H:?FILE_filbuf:#if defined(STDIO_PTR_LVALUE) && defined(STDIO_CNT_LVALUE)
137 ?H:?FILE_filbuf:#define FILE_filbuf(fp) $stdio_filbuf           /**/
138 ?H:?FILE_filbuf:#endif
139 ?H:?d_stdstdio:#endif
140 ?H:.
141 ?W:d_stdstdio:FILE_ptr FILE_cnt FILE_filbuf
142 ?C:USE_STDIO_BASE ~ d_stdiobase:
143 ?C:     This symbol is defined if the _base field (or similar) of the
144 ?C:     stdio FILE structure can be used to access the stdio buffer for
145 ?C:     a file handle.  If this is defined, then the FILE_base(fp) macro
146 ?C:     will also be defined and should be used to access this field.
147 ?C:     Also, the FILE_bufsiz(fp) macro will be defined and should be used
148 ?C:     to determine the number of bytes in the buffer.  USE_STDIO_BASE
149 ?C:     will never be defined unless USE_STDIO_PTR is.
150 ?C:.
151 ?C:FILE_base:
152 ?C:     This macro is used to access the _base field (or equivalent) of the
153 ?C:     FILE structure pointed to by its argument. This macro will always be
154 ?C:     defined if USE_STDIO_BASE is defined.
155 ?C:.
156 ?C:FILE_bufsiz:
157 ?C:     This macro is used to determine the number of bytes in the I/O
158 ?C:     buffer pointed to by _base field (or equivalent) of the FILE
159 ?C:     structure pointed to its argument. This macro will always be defined
160 ?C:     if USE_STDIO_BASE is defined.
161 ?C:.
162 ?H:?d_stdiobase:#$d_stdiobase USE_STDIO_BASE    /**/
163 ?H:?d_stdiobase:#ifdef USE_STDIO_BASE
164 ?H:#define FILE_base(fp)        $stdio_base
165 ?H:#define FILE_bufsiz(fp)      $stdio_bufsiz
166 ?H:?d_stdiobase:#endif
167 ?H:.
168 ?W:d_stdiobase:FILE_base FILE_bufsiz
169 ?LINT:set d_stdstdio d_stdiobase d_stdio_ptr_lval d_stdio_cnt_lval
170 ?T:ptr_lval cnt_lval filbuf xxx
171 ?F:!try
172 : see if _ptr and _cnt from stdio act std
173 echo " "
174
175 if $contains '_lbfsize' `./findhdr stdio.h` >/dev/null 2>&1 ; then
176         echo "(Looks like you have stdio.h from BSD.)"
177         case "$stdio_ptr" in
178         '') stdio_ptr='((fp)->_p)'
179                 ptr_lval=$define
180                 ;;
181         *)      ptr_lval=$d_stdio_ptr_lval;;
182         esac
183         case "$stdio_cnt" in
184         '') stdio_cnt='((fp)->_r)'
185                 cnt_lval=$define
186                 ;;
187         *)      cnt_lval=$d_stdio_cnt_lval;;
188         esac
189         case "$stdio_base" in
190         '') stdio_base='((fp)->_ub._base ? (fp)->_ub._base : (fp)->_bf._base)';;
191         esac
192         case "$stdio_bufsiz" in
193         '') stdio_bufsiz='((fp)->_ub._base ? (fp)->_ub._size : (fp)->_bf._size)';;
194         esac
195 elif $contains '_IO_fpos_t' `./findhdr stdio.h` `./findhdr libio.h` >/dev/null 2>&1 ; then
196         echo "(Looks like you have stdio.h from Linux.)"
197         case "$stdio_ptr" in
198         '') stdio_ptr='((fp)->_IO_read_ptr)'
199                 ptr_lval=$define
200                 ;;
201         *)      ptr_lval=$d_stdio_ptr_lval;;
202         esac
203         case "$stdio_cnt" in
204         '') stdio_cnt='((fp)->_IO_read_end - (fp)->_IO_read_ptr)'
205                 cnt_lval=$undef
206                 ;;
207         *)      cnt_lval=$d_stdio_cnt_lval;;
208         esac
209         case "$stdio_base" in
210         '') stdio_base='((fp)->_IO_read_base)';;
211         esac
212         case "$stdio_bufsiz" in
213         '') stdio_bufsiz='((fp)->_IO_read_end - (fp)->_IO_read_base)';;
214         esac
215 else
216         case "$stdio_ptr" in
217         '') stdio_ptr='((fp)->_ptr)'
218                 ptr_lval=$define
219                 ;;
220         *)      ptr_lval=$d_stdio_ptr_lval;;
221         esac
222         case "$stdio_cnt" in
223         '') stdio_cnt='((fp)->_cnt)'
224                 cnt_lval=$define
225                 ;;
226         *)      cnt_lval=$d_stdio_cnt_lval;;
227         esac
228         case "$stdio_base" in
229         '') stdio_base='((fp)->_base)';;
230         esac
231         case "$stdio_bufsiz" in
232         '') stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)';;
233         esac
234 fi
235
236 : test whether _ptr and _cnt really work
237 echo "Checking how std your stdio is..." >&4
238 $cat >try.c <<EOP
239 #include <stdio.h>
240 #define FILE_ptr(fp)    $stdio_ptr
241 #define FILE_cnt(fp)    $stdio_cnt
242 int main() {
243         FILE *fp = fopen("try.c", "r");
244         char c = getc(fp);
245         if (
246                 18 <= FILE_cnt(fp) &&
247                 strncmp(FILE_ptr(fp), "include <stdio.h>\n", 18) == 0
248         )
249                 exit(0);
250         exit(1);
251 }
252 EOP
253 val="$undef"
254 set try
255 if eval $compile; then
256         if ./try; then
257                 echo "Your stdio acts pretty std."
258                 val="$define"
259         else
260                 echo "Your stdio isn't very std."
261         fi
262 else
263         echo "Your stdio doesn't appear very std."
264 fi
265 $rm -f try.c try
266 set d_stdstdio
267 eval $setvar
268
269 @if STDIO_PTR_LVALUE || d_stdio_ptr_lval
270 : Can _ptr be used as an lvalue?
271 ?X: Only makes sense if we have a known stdio implementation.
272 case "$d_stdstdio$ptr_lval" in
273 $define$define) val=$define ;;
274 *) val=$undef ;;
275 esac
276 set d_stdio_ptr_lval
277 eval $setvar
278 @end
279
280 @if STDIO_CNT_LVALUE || d_stdio_cnt_lval
281 : Can _cnt be used as an lvalue?
282 ?X: Only makes sense if we have a known stdio implementation.
283 case "$d_stdstdio$cnt_lval" in
284 $define$define) val=$define ;;
285 *) val=$undef ;;
286 esac
287 set d_stdio_cnt_lval
288 eval $setvar
289 @end
290
291 @if FILE_filbuf
292 : How to access the stdio _filbuf or __filbuf function.
293 : If this fails, check how the getc macro in stdio.h works.
294 case "${d_stdio_ptr_lval}${d_stdio_cnt_lval}" in
295 ${define}${define})
296         : Try $hint value, if any, then _filbuf, __filbuf, _fill, then punt.
297         : _fill is for os/2.
298         xxx='notok'
299         for filbuf in $stdio_filbuf '_filbuf(fp)' '__filbuf(fp) ' '_fill(fp)' ; do
300                 $cat >try.c <<EOP
301 #include <stdio.h>
302 #define FILE_ptr(fp)    $stdio_ptr
303 #define FILE_cnt(fp)    $stdio_cnt
304 #define FILE_filbuf(fp) $filbuf
305 int main() {
306         FILE *fp = fopen("try.c", "r");
307         int c;
308         c = getc(fp);
309         c = FILE_filbuf(fp);  /* Just looking for linker errors.*/
310         exit(0);
311 }
312 EOP
313                 set try
314                 if eval $compile && ./try; then
315                         echo "Your stdio appears to use $filbuf"
316                         stdio_filbuf="$filbuf"
317                         xxx='ok'
318                         break
319                 else
320                         echo "Hmm.  $filbuf doesn't seem to work."
321                 fi
322                 $rm -f try.c try
323         done
324         case "$xxx" in
325         notok)  echo "I can't figure out how to access _filbuf"
326                         echo "I'll just have to work around it."
327                         d_stdio_ptr_lval="$undef"
328                         d_stdio_cnt_lval="$undef"
329                         ;;
330         esac
331         ;;
332 esac
333 @end
334
335 @if STDIO_PTR_LVALUE
336 : test whether setting _ptr sets _cnt as a side effect
337 d_stdio_ptr_lval_sets_cnt="$undef"
338 d_stdio_ptr_lval_nochange_cnt="$undef"
339 case "$d_stdio_ptr_lval$d_stdstdio" in
340 $define$define)
341         echo "Checking to see what happens if we set the stdio ptr..." >&4
342 $cat >try.c <<EOP
343 #include <stdio.h>
344 /* Can we scream? */
345 /* Eat dust sed :-) */
346 /* In the buffer space, no one can hear you scream. */
347 #define FILE_ptr(fp)    $stdio_ptr
348 #define FILE_cnt(fp)    $stdio_cnt
349 #include <sys/types.h>
350 int main() {
351         FILE *fp = fopen("try.c", "r");
352         int c;
353         char *ptr;
354         size_t cnt;
355         if (!fp) {
356             puts("Fail even to read");
357             exit(1);
358         }
359         c = getc(fp); /* Read away the first # */
360         if (c == EOF) {
361             puts("Fail even to read");
362             exit(1);
363         }
364         if (!(
365                 18 <= FILE_cnt(fp) &&
366                 strncmp(FILE_ptr(fp), "include <stdio.h>\n", 18) == 0
367         )) {
368                 puts("Fail even to read");
369                 exit (1);
370         }
371         ptr = (char*) FILE_ptr(fp);
372         cnt = (size_t)FILE_cnt(fp);
373
374         FILE_ptr(fp) += 42;
375
376         if ((char*)FILE_ptr(fp) != (ptr + 42)) {
377                 printf("Fail ptr check %p != %p", FILE_ptr(fp), (ptr + 42));
378                 exit (1);
379         }
380         if (FILE_cnt(fp) <= 20) {
381                 printf ("Fail (<20 chars to test)");
382                 exit (1);
383         }
384         if (strncmp(FILE_ptr(fp), "Eat dust sed :-) */\n", 20) != 0) {
385                 puts("Fail compare");
386                 exit (1);
387         }
388         if (cnt == FILE_cnt(fp)) {
389                 puts("Pass_unchanged");
390                 exit (0);
391         }       
392         if (FILE_cnt(fp) == (cnt - 42)) {
393                 puts("Pass_changed");
394                 exit (0);
395         }
396         printf("Fail count was %d now %d\n", cnt, FILE_cnt(fp));
397         return 1;
398
399 }
400 EOP
401         set try
402         if eval $compile; then
403                 case `./try$exe_ext` in
404                 Pass_changed)
405                         echo "Increasing ptr in your stdio decreases cnt by the same amount.  Good." >&4
406                         d_stdio_ptr_lval_sets_cnt="$define" ;;
407                 Pass_unchanged)
408                         echo "Increasing ptr in your stdio leaves cnt unchanged.  Good." >&4
409                         d_stdio_ptr_lval_nochange_cnt="$define" ;;
410                 Fail*)
411                         echo "Increasing ptr in your stdio didn't do exactly what I expected.  We'll not be doing that then." >&4 ;;
412                 *)
413                         echo "It appears attempting to set ptr in your stdio is a bad plan." >&4 ;;
414         esac
415         else
416                 echo "It seems we can't set ptr in your stdio.  Nevermind." >&4
417         fi
418         $rm -f try.c try
419         ;;
420 esac
421 @end
422
423 @if d_stdiobase || USE_STDIO_BASE || FILE_base || FILE_bufsiz
424 : see if _base is also standard
425 val="$undef"
426 case "$d_stdstdio" in
427 $define)
428         $cat >try.c <<EOP
429 #include <stdio.h>
430 #define FILE_base(fp)   $stdio_base
431 #define FILE_bufsiz(fp) $stdio_bufsiz
432 int main() {
433         FILE *fp = fopen("try.c", "r");
434         char c = getc(fp);
435         if (
436                 19 <= FILE_bufsiz(fp) &&
437                 strncmp(FILE_base(fp), "#include <stdio.h>\n", 19) == 0
438         )
439                 exit(0);
440         exit(1);
441 }
442 EOP
443         set try
444         if eval $compile; then
445                 if ./try; then
446                         echo "And its _base field acts std."
447                         val="$define"
448                 else
449                         echo "But its _base field isn't std."
450                 fi
451         else
452                 echo "However, it seems to be lacking the _base field."
453         fi
454         $rm -f try.c try
455         ;;
456 esac
457 set d_stdiobase
458 eval $setvar
459
460 @end