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


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed