source: libcfa/src/strstream.cfa@ 6fafda8

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 6fafda8 was 321a1b15, checked in by Peter A. Buhr <pabuhr@…>, 4 years ago

change getANL to getANL$ (private), change eof to return bool versus int, add hack to make istrstream.fmt work except with wdi manipulators

  • Property mode set to 100644
File size: 5.4 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// strstream.cfa --
8//
9// Author : Peter A. Buhr
10// Created On : Thu Apr 22 22:24:35 2021
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sun Oct 10 16:13:20 2021
13// Update Count : 101
14//
15
16#include "strstream.hfa"
17#include "fstream.hfa" // abort
18
19#include <stdio.h> // vsnprintf
20#include <stdarg.h> // varargs
21#include <string.h> // strncpy, strerror
22#include <assert.h>
23#include <errno.h> // errno
24#include <unistd.h> // sbrk, sysconf
25
26
27// *********************************** strstream ***********************************
28
29
30#define IO_MSG "I/O error: "
31
32// private
33inline bool sepPrt$( ostrstream & os ) { setNL$( os, false ); return os.sepOnOff$; }
34inline void sepReset$( ostrstream & os ) { os.sepOnOff$ = os.sepDefault$; }
35inline void sepReset$( ostrstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }
36inline const char * sepGetCur$( ostrstream & os ) { return os.sepCur$; }
37inline void sepSetCur$( ostrstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }
38inline bool getNL$( ostrstream & os ) { return os.sawNL$; }
39inline void setNL$( ostrstream & os, bool state ) { os.sawNL$ = state; }
40inline bool getANL$( ostrstream & os ) { return os.nlOnOff$; }
41inline bool getPrt$( ostrstream & os ) { return os.prt$; }
42inline void setPrt$( ostrstream & os, bool state ) { os.prt$ = state; }
43
44// public
45void ?{}( ostrstream & os, char buf[], size_t size ) {
46 os.buf$ = buf;
47 os.size$ = size;
48 os.cursor$ = 0;
49 os.sepDefault$ = true;
50 os.sepOnOff$ = false;
51 os.nlOnOff$ = true;
52 os.prt$ = false;
53 os.sawNL$ = false;
54 sepSetCur$( os, sepGet( os ) );
55 sepSet( os, " " );
56 sepSetTuple( os, ", " );
57} // ?{}
58
59void sepOn( ostrstream & os ) { os.sepOnOff$ = ! getNL$( os ); }
60void sepOff( ostrstream & os ) { os.sepOnOff$ = false; }
61
62bool sepDisable( ostrstream & os ) {
63 bool temp = os.sepDefault$;
64 os.sepDefault$ = false;
65 sepReset$( os );
66 return temp;
67} // sepDisable
68
69bool sepEnable( ostrstream & os ) {
70 bool temp = os.sepDefault$;
71 os.sepDefault$ = true;
72 if ( os.sepOnOff$ ) sepReset$( os ); // start of line ?
73 return temp;
74} // sepEnable
75
76void nlOn( ostrstream & os ) { os.nlOnOff$ = true; }
77void nlOff( ostrstream & os ) { os.nlOnOff$ = false; }
78
79const char * sepGet( ostrstream & os ) { return os.separator$; }
80void sepSet( ostrstream & os, const char s[] ) {
81 assert( s );
82 strncpy( os.separator$, s, ostrstream_sepSize - 1 );
83 os.separator$[ostrstream_sepSize - 1] = '\0';
84} // sepSet
85
86const char * sepGetTuple( ostrstream & os ) { return os.tupleSeparator$; }
87void sepSetTuple( ostrstream & os, const char s[] ) {
88 assert( s );
89 strncpy( os.tupleSeparator$, s, ostrstream_sepSize - 1 );
90 os.tupleSeparator$[ostrstream_sepSize - 1] = '\0';
91} // sepSet
92
93void ends( ostrstream & os ) {
94 if ( getANL$( os ) ) nl( os );
95 else setPrt$( os, false ); // turn off
96} // ends
97
98int fmt( ostrstream & os, const char format[], ... ) {
99 va_list args;
100 va_start( args, format );
101 int len = vsnprintf( os.buf$ + os.cursor$, os.size$ - os.cursor$, format, args );
102 va_end( args );
103 os.cursor$ += len;
104 if ( os.cursor$ >= os.size$ ) { // cursor exceeded buffer size?
105 #define fmtmsg IO_MSG "ostrstream truncated write, buffer too small.\n"
106 write( STDERR_FILENO, fmtmsg, sizeof(fmtmsg) - 1 );
107 abort();
108 } // if
109
110 setPrt$( os, true ); // called in output cascade
111 sepReset$( os ); // reset separator
112 return len;
113} // fmt
114
115ostrstream & write( ostrstream & os, FILE * stream ) {
116 if ( fwrite( os.buf$, 1, os.cursor$, stream ) != os.cursor$ ) {
117 #define ostrwritemsg IO_MSG "ostrstream write error.\n"
118 write( STDERR_FILENO, ostrwritemsg, sizeof(ostrwritemsg) - 1 );
119 abort();
120 } // if
121 return os;
122} // write
123
124ostrstream & write( ostrstream & os ) {
125 return write( os, stdout );
126} // write
127
128
129// *********************************** istrstream ***********************************
130
131// private
132bool getANL$( istrstream & is ) { return is.nlOnOff$; }
133
134// public
135void ?{}( istrstream & is, char buf[] ) {
136 is.buf$ = buf;
137 is.cursor$ = 0;
138 is.nlOnOff$ = false;
139} // ?{}
140
141void nlOn( istrstream & is ) { is.nlOnOff$ = true; }
142void nlOff( istrstream & is ) { is.nlOnOff$ = false; }
143
144void ends( istrstream & is ) {}
145bool eof( istrstream & is ) { return false; }
146
147int fmt( istrstream & is, const char format[], ... ) with(is) {
148 va_list args;
149 va_start( args, format );
150 // THIS DOES NOT WORK BECAUSE VSSCANF RETURNS NUMBER OF VALUES READ VERSUS BUFFER POSITION SCANNED.
151 int len = vsscanf( buf$ + cursor$, format, args );
152 va_end( args );
153 if ( len == EOF ) {
154 abort | IO_MSG "invalid read";
155 } // if
156 // SKULLDUGGERY: This hack skips over characters read by vsscanf by moving to the next whitespace but it does not
157 // handle C reads with wdi manipulators that leave the cursor at a non-whitespace character.
158 for ( ; buf$[cursor$] != ' ' && buf$[cursor$] != '\t' && buf$[cursor$] != '\0'; cursor$ += 1 ) {
159 //printf( "X \'%c\'\n", buf$[cursor$] );
160 } // for
161 if ( buf$[cursor$] != '\0' ) cursor$ += 1; // advance to whitespace
162 return len;
163} // fmt
164
165istrstream &ungetc( istrstream & is, char c ) {
166 // if ( ungetc( c, (FILE *)(is.file$) ) == EOF ) {
167 // abort | IO_MSG "ungetc" | nl | strerror( errno );
168 // } // if
169 return is;
170} // ungetc
171
172// Local Variables: //
173// tab-width: 4 //
174// End: //
Note: See TracBrowser for help on using the repository browser.