-
Notifications
You must be signed in to change notification settings - Fork 703
/
clog.c
159 lines (134 loc) · 4.13 KB
/
clog.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
static void clog_init();
static void clog_finalize();
void clog_set_buffer_len(int *wantlenp);
void clog_write(int*len,char*c);
void clog_flush(int*flag);
static const size_t default_len=100;
static FILE *stream=NULL;
static char *buffer=NULL;
static size_t len=0,used=0;
static int inited=0;
static void clog_init(void) {
if(!inited) {
atexit(clog_finalize);
inited=1;
}
}
static void clog_finalize(void) {
int i=1;
if(buffer)
clog_flush(&i);
free(buffer);
}
void clog_set_buffer_len(int *wantlenp) {
/* Initialize or re-initialize the output buffer with size *wantlenp */
int dummy;
size_t wantlen=*wantlenp;
if(buffer) {
/* Already had a buffer */
if(len!=wantlen) {
/* User is requesting a change in the buffer size, so flush first */
clog_flush(NULL);
free(buffer);
buffer=NULL;
len=used=0;
} else {
/* Buffer size is not changing, so nothing to do. */
return;
}
}
/* We now need to allocate a new buffer and initialize the state */
if(!(buffer=(char*)malloc(sizeof(char)*len)))
len=0;
len=wantlen;
used=0;
clog_init();
if(!stream)
stream=stdout;
if(buffer)
fprintf(stream,"Clog: buffering rsl.out with a %llu byte buffer...\n",
(unsigned long long)len);
}
void clog_write(int *clen,char *c) {
size_t slen=(size_t)*clen;
size_t nlen=slen;
if(c[slen-1]!='\n' && c[slen-1]!='\r')
/* String is missing an end-of-line, so we need to add one. */
nlen++;
if(!stream)
stream=stdout;
if(!buffer) {
/* Buffer is not allocated yet, so allocate it. */
if(!(buffer=(char*)malloc(sizeof(char)*default_len))) {
/* Failed to allocate the buffer, so write the string directly. */
fwrite(c,slen,1,stream);
if(nlen>slen) fputc('\n',stream);
return;
}
len=default_len;
used=0;
clog_init();
if(buffer)
fprintf(stream,"Clog: buffering rsl.out with a %llu byte buffer...\n",
(unsigned long long)len);
}
if(nlen>len) {
/* Cannot fit the string in the buffer, so we'll have to write the
string directly. */
if(used>0)
clog_flush(NULL);
fwrite(c,slen,1,stream);
if(nlen>slen) fputc('\n',stream);
return;
} else if(nlen+used>len) {
/* String is smaller than the buffer, but the buffer is filled enough
so that the string cannot fit */
clog_flush(NULL);
}
if(slen>0)
memcpy(buffer+used,c,slen);
if(nlen>slen)
buffer[used+slen]='\n';
used+=nlen;
}
void clog_flush(int *flag) {
if(!stream)
stream=stdout;
if(buffer) {
fwrite(buffer,used,1,stream);
used=0;
}
if(flag && *flag) {
fflush(stream);
}
}
/* Lookalike functions for all common fortran name mangling schemes */
void clog_init_(void) { clog_init(); }
void clog_init__(void) { clog_init(); }
void CLOG_INIT(void) { clog_init(); }
void CLOG_INIT_(void) { clog_init(); }
void CLOG_INIT__(void) { clog_init(); }
void clog_set_buffer_len_(int *w) { clog_set_buffer_len(w); }
void clog_set_buffer_len__(int *w) { clog_set_buffer_len(w); }
void CLOG_SET_BUFFER_LEN(int *w) { clog_set_buffer_len(w); }
void CLOG_SET_BUFFER_LEN_(int *w) { clog_set_buffer_len(w); }
void CLOG_SET_BUFFER_LEN__(int *w) { clog_set_buffer_len(w); }
void clog_write_(int *clen,char *c) { clog_write(clen,c); }
void clog_write__(int *clen,char *c) { clog_write(clen,c); }
void CLOG_WRITE(int *clen,char *c) { clog_write(clen,c); }
void CLOG_WRITE_(int *clen,char *c) { clog_write(clen,c); }
void CLOG_WRITE__(int *clen,char *c) { clog_write(clen,c); }
void clog_flush_(int *flag) { clog_flush(flag); }
void clog_flush__(int *flag) { clog_flush(flag); }
void CLOG_FLUSH(int *flag) { clog_flush(flag); }
void CLOG_FLUSH_(int *flag) { clog_flush(flag); }
void CLOG_FLUSH__(int *flag) { clog_flush(flag); }
#ifdef __cplusplus
}
#endif