Coverage Report

Created: 2026-03-30 09:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
/**@}*/