Graphviz  2.41.20170921.2350
agerror.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 #include <stdio.h>
15 #include <cghdr.h>
16 
17 #define MAX(a,b) ((a)>(b)?(a):(b))
18 static agerrlevel_t agerrno; /* Last error level */
19 static agerrlevel_t agerrlevel = AGWARN; /* Report errors >= agerrlevel */
20 static int agmaxerr;
21 
22 static long aglast; /* Last message */
23 static FILE *agerrout; /* Message file */
24 static agusererrf usererrf; /* User-set error function */
25 
28 {
29  agusererrf oldf = usererrf;
30  usererrf = newf;
31  return oldf;
32 }
33 
35 {
36  agerrlevel_t oldv = agerrlevel;
37  agerrlevel = lvl;
38  return oldv;
39 }
40 
41 char *aglasterr()
42 {
43  long endpos;
44  long len;
45  char *buf;
46 
47  if (!agerrout)
48  return 0;
49  fflush(agerrout);
50  endpos = ftell(agerrout);
51  len = endpos - aglast;
52  buf = (char*)malloc(len + 1);
53  fseek(agerrout, aglast, SEEK_SET);
54  fread(buf, sizeof(char), len, agerrout);
55  buf[len] = '\0';
56  fseek(agerrout, endpos, SEEK_SET);
57 
58  return buf;
59 }
60 
61 /* userout:
62  * Report messages using a user-supplied write function
63  */
64 static void
65 userout (agerrlevel_t level, const char *fmt, va_list args)
66 {
67  static char* buf;
68  static int bufsz = 1024;
69  char* np;
70  int n;
71 
72  if (!buf) {
73  buf = (char*)malloc(bufsz);
74  if (!buf) {
75  fputs("userout: could not allocate memory\n", stderr );
76  return;
77  }
78  }
79 
80  if (level != AGPREV) {
81  usererrf ((level == AGERR) ? "Error" : "Warning");
82  usererrf (": ");
83  }
84 
85  while (1) {
86  n = vsnprintf(buf, bufsz, fmt, args);
87  if ((n > -1) && (n < bufsz)) {
88  usererrf (buf);
89  break;
90  }
91  bufsz = MAX(bufsz*2,n+1);
92  if ((np = (char*)realloc(buf, bufsz)) == NULL) {
93  fputs("userout: could not allocate memory\n", stderr );
94  return;
95  }
96  }
97  va_end(args);
98 }
99 
100 static int agerr_va(agerrlevel_t level, const char *fmt, va_list args)
101 {
102  agerrlevel_t lvl;
103 
104  /* Use previous error level if continuation message;
105  * Convert AGMAX to AGERROR;
106  * else use input level
107  */
108  lvl = (level == AGPREV ? agerrno : (level == AGMAX) ? AGERR : level);
109 
110  /* store this error level */
111  agerrno = lvl;
112  agmaxerr = MAX(agmaxerr, agerrno);
113 
114  /* We report all messages whose level is bigger than the user set agerrlevel
115  * Setting agerrlevel to AGMAX turns off immediate error reporting.
116  */
117  if (lvl >= agerrlevel) {
118  if (usererrf)
119  userout (level, fmt, args);
120  else {
121  if (level != AGPREV)
122  fprintf(stderr, "%s: ", (level == AGERR) ? "Error" : "Warning");
123  vfprintf(stderr, fmt, args);
124  va_end(args);
125  }
126  return 0;
127  }
128 
129  if (!agerrout) {
130  agerrout = tmpfile();
131  if (!agerrout)
132  return 1;
133  }
134 
135  if (level != AGPREV)
136  aglast = ftell(agerrout);
137  vfprintf(agerrout, fmt, args);
138  return 0;
139 }
140 
141 int agerr(agerrlevel_t level, const char *fmt, ...)
142 {
143  va_list args;
144  int ret;
145 
146  va_start(args, fmt);
147  ret = agerr_va(level, fmt, args);
148  va_end(args);
149  return ret;
150 }
151 
152 void agerrorf(const char *fmt, ...)
153 {
154  va_list args;
155 
156  va_start(args, fmt);
157  agerr_va(AGERR, fmt, args);
158  va_end(args);
159 }
160 
161 void agwarningf(const char *fmt, ...)
162 {
163  va_list args;
164 
165  va_start(args, fmt);
166  agerr_va(AGWARN, fmt, args);
167  va_end(args);
168 }
169 
170 int agerrors() { return agmaxerr; }
171 
173 {
174  int rc = agmaxerr;
175  agmaxerr = 0;
176  return rc;
177 }
178 
#define MAX(a, b)
Definition: agerror.c:17
Definition: cgraph.h:388
int agreseterrors()
Definition: agerror.c:172
Definition: cgraph.h:388
agerrlevel_t agseterr(agerrlevel_t lvl)
Definition: agerror.c:34
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:141
Definition: cgraph.h:388
int(* agusererrf)(char *)
Definition: cgraph.h:389
agusererrf agseterrf(agusererrf newf)
Definition: agerror.c:27
#define NULL
Definition: logic.h:39
agerrlevel_t
Definition: cgraph.h:388
void agwarningf(const char *fmt,...)
Definition: agerror.c:161
int agerrors()
Definition: agerror.c:170
Definition: cgraph.h:388
char * aglasterr()
Definition: agerror.c:41
void agerrorf(const char *fmt,...)
Definition: agerror.c:152