/src/gdal/netcdf-c-4.7.4/libdispatch/nclog.c
Line | Count | Source |
1 | | /********************************************************************* |
2 | | * Copyright 2018, UCAR/Unidata |
3 | | * See netcdf/COPYRIGHT file for copying and redistribution conditions. |
4 | | * $Header$ |
5 | | *********************************************************************/ |
6 | | |
7 | | #include "config.h" |
8 | | #ifdef _MSC_VER |
9 | | #include<io.h> |
10 | | #endif |
11 | | |
12 | | #include <stdlib.h> |
13 | | #include <stdio.h> |
14 | | #include <stdarg.h> |
15 | | #include <string.h> |
16 | | #ifdef HAVE_FCNTL_H |
17 | | #include <fcntl.h> |
18 | | #endif |
19 | | |
20 | | extern FILE* fdopen(int fd, const char *mode); |
21 | | |
22 | | #include "nclog.h" |
23 | | |
24 | | #define PREFIXLEN 8 |
25 | | #define MAXTAGS 256 |
26 | | #define NCTAGDFALT "Log"; |
27 | | |
28 | | |
29 | | static int nclogginginitialized = 0; |
30 | | |
31 | | static struct NCLOGGLOBAL { |
32 | | int nclogging; |
33 | | int ncsystemfile; /* 1 => we are logging to file we did not open */ |
34 | | char* nclogfile; |
35 | | FILE* nclogstream; |
36 | | } nclog_global = {0,0,NULL,NULL}; |
37 | | |
38 | | static const char* nctagset[] = {"Warning","Error","Note","Debug"}; |
39 | | static const int nctagsize = sizeof(nctagset)/sizeof(char*); |
40 | | |
41 | | /* Forward */ |
42 | | static const char* nctagname(int tag); |
43 | | |
44 | | /*!\defgroup NClog NClog Management |
45 | | @{*/ |
46 | | |
47 | | /*!\internal |
48 | | */ |
49 | | |
50 | | void |
51 | | ncloginit(void) |
52 | 18 | { |
53 | 18 | const char* file; |
54 | 18 | if(nclogginginitialized) |
55 | 9 | return; |
56 | 9 | nclogginginitialized = 1; |
57 | 9 | memset(&nclog_global,0,sizeof(nclog_global)); |
58 | 9 | ncsetlogging(0); |
59 | 9 | nclog_global.nclogfile = NULL; |
60 | 9 | nclog_global.nclogstream = NULL; |
61 | | /* Use environment variables to preset nclogging state*/ |
62 | | /* I hope this is portable*/ |
63 | 9 | file = getenv(NCENVFLAG); |
64 | 9 | if(file != NULL && strlen(file) > 0) { |
65 | 0 | if(nclogopen(file)) { |
66 | 0 | ncsetlogging(1); |
67 | 0 | } |
68 | 0 | } |
69 | 9 | } |
70 | | |
71 | | /*! |
72 | | Enable/Disable logging. |
73 | | |
74 | | \param[in] tf If 1, then turn on logging, if 0, then turn off logging. |
75 | | |
76 | | \return The previous value of the logging flag. |
77 | | */ |
78 | | |
79 | | int |
80 | | ncsetlogging(int tf) |
81 | 9 | { |
82 | 9 | int was; |
83 | 9 | if(!nclogginginitialized) ncloginit(); |
84 | 9 | was = nclog_global.nclogging; |
85 | 9 | nclog_global.nclogging = tf; |
86 | 9 | return was; |
87 | 9 | } |
88 | | |
89 | | /*! |
90 | | Specify a file into which to place logging output. |
91 | | |
92 | | \param[in] file The name of the file into which to place logging output. |
93 | | If the file has the value NULL, then send logging output to |
94 | | stderr. |
95 | | |
96 | | \return zero if the open failed, one otherwise. |
97 | | */ |
98 | | |
99 | | int |
100 | | nclogopen(const char* file) |
101 | 0 | { |
102 | 0 | if(!nclogginginitialized) ncloginit(); |
103 | 0 | nclogclose(); |
104 | 0 | if(file == NULL || strlen(file) == 0) { |
105 | | /* use stderr*/ |
106 | 0 | nclog_global.nclogstream = stderr; |
107 | 0 | nclog_global.nclogfile = NULL; |
108 | 0 | nclog_global.ncsystemfile = 1; |
109 | 0 | } else if(strcmp(file,"stdout") == 0) { |
110 | | /* use stdout*/ |
111 | 0 | nclog_global.nclogstream = stdout; |
112 | 0 | nclog_global.nclogfile = NULL; |
113 | 0 | nclog_global.ncsystemfile = 1; |
114 | 0 | } else if(strcmp(file,"stderr") == 0) { |
115 | | /* use stderr*/ |
116 | 0 | nclog_global.nclogstream = stderr; |
117 | 0 | nclog_global.nclogfile = NULL; |
118 | 0 | nclog_global.ncsystemfile = 1; |
119 | 0 | } else { |
120 | 0 | int fd; |
121 | 0 | nclog_global.nclogfile = strdup(file); |
122 | 0 | nclog_global.nclogstream = NULL; |
123 | | /* We need to deal with this file carefully |
124 | | to avoid unauthorized access*/ |
125 | 0 | fd = open(nclog_global.nclogfile,O_WRONLY|O_APPEND|O_CREAT,0600); |
126 | 0 | if(fd >= 0) { |
127 | 0 | nclog_global.nclogstream = fdopen(fd,"a"); |
128 | 0 | } else { |
129 | 0 | free(nclog_global.nclogfile); |
130 | 0 | nclog_global.nclogfile = NULL; |
131 | 0 | nclog_global.nclogstream = NULL; |
132 | 0 | ncsetlogging(0); |
133 | 0 | return 0; |
134 | 0 | } |
135 | 0 | nclog_global.ncsystemfile = 0; |
136 | 0 | } |
137 | 0 | return 1; |
138 | 0 | } |
139 | | |
140 | | void |
141 | | nclogclose(void) |
142 | 0 | { |
143 | 0 | if(!nclogginginitialized) ncloginit(); |
144 | 0 | if(nclog_global.nclogstream != NULL && !nclog_global.ncsystemfile) { |
145 | 0 | fclose(nclog_global.nclogstream); |
146 | 0 | } |
147 | 0 | if(nclog_global.nclogfile != NULL) free(nclog_global.nclogfile); |
148 | 0 | nclog_global.nclogstream = NULL; |
149 | 0 | nclog_global.nclogfile = NULL; |
150 | 0 | nclog_global.ncsystemfile = 0; |
151 | 0 | } |
152 | | |
153 | | /*! |
154 | | Send logging messages. This uses a variable |
155 | | number of arguments and operates like the stdio |
156 | | printf function. |
157 | | |
158 | | \param[in] tag Indicate the kind of this log message. |
159 | | \param[in] format Format specification as with printf. |
160 | | */ |
161 | | |
162 | | void |
163 | | nclog(int tag, const char* fmt, ...) |
164 | 9 | { |
165 | 9 | va_list args; |
166 | 9 | const char* prefix; |
167 | | |
168 | 9 | if(!nclogginginitialized) ncloginit(); |
169 | | |
170 | 9 | if(!nclog_global.nclogging || nclog_global.nclogstream == NULL) return; |
171 | | |
172 | 0 | prefix = nctagname(tag); |
173 | 0 | fprintf(nclog_global.nclogstream,"%s:",prefix); |
174 | |
|
175 | 0 | if(fmt != NULL) { |
176 | 0 | va_start(args, fmt); |
177 | 0 | vfprintf(nclog_global.nclogstream, fmt, args); |
178 | 0 | va_end( args ); |
179 | 0 | } |
180 | 0 | fprintf(nclog_global.nclogstream, "\n" ); |
181 | 0 | fflush(nclog_global.nclogstream); |
182 | 0 | } |
183 | | |
184 | | void |
185 | | ncvlog(int tag, const char* fmt, va_list ap) |
186 | 0 | { |
187 | 0 | const char* prefix; |
188 | |
|
189 | 0 | if(!nclogginginitialized) ncloginit(); |
190 | |
|
191 | 0 | if(!nclog_global.nclogging || nclog_global.nclogstream == NULL) return; |
192 | | |
193 | 0 | prefix = nctagname(tag); |
194 | 0 | fprintf(nclog_global.nclogstream,"%s:",prefix); |
195 | |
|
196 | 0 | if(fmt != NULL) { |
197 | 0 | vfprintf(nclog_global.nclogstream, fmt, ap); |
198 | 0 | } |
199 | 0 | fprintf(nclog_global.nclogstream, "\n" ); |
200 | 0 | fflush(nclog_global.nclogstream); |
201 | 0 | } |
202 | | |
203 | | void |
204 | | nclogtext(int tag, const char* text) |
205 | 0 | { |
206 | 0 | nclogtextn(tag,text,strlen(text)); |
207 | 0 | } |
208 | | |
209 | | /*! |
210 | | Send arbitrarily long text as a logging message. |
211 | | Each line will be sent using nclog with the specified tag. |
212 | | \param[in] tag Indicate the kind of this log message. |
213 | | \param[in] text Arbitrary text to send as a logging message. |
214 | | */ |
215 | | |
216 | | void |
217 | | nclogtextn(int tag, const char* text, size_t count) |
218 | 0 | { |
219 | 0 | NC_UNUSED(tag); |
220 | 0 | if(!nclog_global.nclogging || nclog_global.nclogstream == NULL) return; |
221 | 0 | fwrite(text,1,count,nclog_global.nclogstream); |
222 | 0 | fflush(nclog_global.nclogstream); |
223 | 0 | } |
224 | | |
225 | | static const char* |
226 | | nctagname(int tag) |
227 | 0 | { |
228 | 0 | if(tag < 0 || tag >= nctagsize) |
229 | 0 | return "unknown"; |
230 | 0 | return nctagset[tag]; |
231 | 0 | } |
232 | | |
233 | | /**@}*/ |