]> pd.if.org Git - pdclib/blob - functions/stdio/ftell.c
PDCLib includes with quotes, not <>.
[pdclib] / functions / stdio / ftell.c
1 /* ftell( FILE * )
2
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <limits.h>
10 #include <errno.h>
11
12 #ifndef REGTEST
13 #include "_PDCLIB_io.h"
14
15 long int _PDCLIB_ftell_unlocked( FILE * stream )
16 {
17     uint_fast64_t off64 = _PDCLIB_ftell64_unlocked( stream );
18
19     if ( off64 > LONG_MAX )
20     {
21         /* integer overflow */
22         errno = ERANGE;
23         return -1;
24     }
25     return off64;
26 }
27
28 long int ftell( FILE * stream )
29 {
30     _PDCLIB_flockfile( stream );
31     long int off = _PDCLIB_ftell_unlocked( stream );
32     _PDCLIB_funlockfile( stream );
33     return off;
34 }
35
36 #endif
37
38 #ifdef TEST
39 #include "_PDCLIB_test.h"
40 #include <stdlib.h>
41 #ifndef REGTEST
42 #include "_PDCLIB_io.h"
43 #endif
44
45 int main( void )
46 {
47     /* Testing all the basic I/O functions individually would result in lots
48        of duplicated code, so I took the liberty of lumping it all together
49        here.
50     */
51     /* The following functions delegate their tests to here:
52        fgetc fflush rewind fputc ungetc fseek
53        flushbuffer seek fillbuffer prepread prepwrite
54     */
55     char * buffer = (char*)malloc( 4 );
56     FILE * fh;
57     TESTCASE( ( fh = tmpfile() ) != NULL );
58     TESTCASE( setvbuf( fh, buffer, _IOLBF, 4 ) == 0 );
59     /* Testing ungetc() at offset 0 */
60     rewind( fh );
61     TESTCASE( ungetc( 'x', fh ) == 'x' );
62     TESTCASE( ftell( fh ) == -1l );
63     rewind( fh );
64     TESTCASE( ftell( fh ) == 0l );
65     /* Commence "normal" tests */
66     TESTCASE( fputc( '1', fh ) == '1' );
67     TESTCASE( fputc( '2', fh ) == '2' );
68     TESTCASE( fputc( '3', fh ) == '3' );
69     /* Positions incrementing as expected? */
70     TESTCASE( ftell( fh ) == 3l );
71     TESTCASE_NOREG( fh->pos.offset == 0l );
72     TESTCASE_NOREG( fh->bufidx == 3l );
73     /* Buffer properly flushed when full? */
74     TESTCASE( fputc( '4', fh ) == '4' );
75     TESTCASE_NOREG( fh->pos.offset == 4l );
76     TESTCASE_NOREG( fh->bufidx == 0 );
77     /* fflush() resetting positions as expected? */
78     TESTCASE( fputc( '5', fh ) == '5' );
79     TESTCASE( fflush( fh ) == 0 );
80     TESTCASE( ftell( fh ) == 5l );
81     TESTCASE_NOREG( fh->pos.offset == 5l );
82     TESTCASE_NOREG( fh->bufidx == 0l );
83     /* rewind() resetting positions as expected? */
84     rewind( fh );
85     TESTCASE( ftell( fh ) == 0l );
86     TESTCASE_NOREG( fh->pos.offset == 0 );
87     TESTCASE_NOREG( fh->bufidx == 0 );
88     /* Reading back first character after rewind for basic read check */
89     TESTCASE( fgetc( fh ) == '1' );
90     /* TODO: t.b.c. */
91     TESTCASE( fclose( fh ) == 0 );
92     return TEST_RESULTS;
93 }
94
95 #endif
96