1 /* grecs - Gray's Extensible Configuration System
2    Copyright (C) 2007-2016 Sergey Poznyakoff
3 
4    Grecs is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 3 of the License, or (at your
7    option) any later version.
8 
9    Grecs is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with Grecs. If not, see <http://www.gnu.org/licenses/>. */
16 
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <grecs.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <errno.h>
25 
26 static void
default_print_diag(grecs_locus_t const * locus,int err,int errcode,const char * msg)27 default_print_diag(grecs_locus_t const *locus, int err, int errcode,
28 		   const char *msg)
29 {
30 	fflush(stdout);
31 	if (locus) {
32 		YY_LOCATION_PRINT(stderr, *locus);
33 		fputc(':', stderr);
34 		fputc(' ', stderr);
35 	}
36 	if (!err)
37 		fprintf(stderr, "warning: ");
38 	fprintf(stderr, "%s", msg);
39 	if (errcode)
40 		fprintf(stderr, ": %s", strerror(errcode));
41 	fputc('\n', stderr);
42 }
43 
44 void (*grecs_print_diag_fun)(grecs_locus_t const *, int, int,
45 			     const char *msg) =
46 	default_print_diag;
47 
48 void
grecs_warning(grecs_locus_t const * locus,int errcode,const char * fmt,...)49 grecs_warning(grecs_locus_t const *locus, int errcode, const char *fmt, ...)
50 {
51 	va_list ap;
52 	char *buf = NULL;
53 	size_t size = 0;
54 
55 	va_start(ap, fmt);
56 	if (grecs_vasprintf(&buf, &size, fmt, ap))
57 		grecs_alloc_die();
58 	va_end(ap);
59 	grecs_print_diag_fun(locus, 0, errcode, buf);
60 	free(buf);
61 }
62 
63 void
grecs_error(grecs_locus_t const * locus,int errcode,const char * fmt,...)64 grecs_error(grecs_locus_t const *locus, int errcode, const char *fmt, ...)
65 {
66 	va_list ap;
67 	char *buf = NULL;
68 	size_t size = 0;
69 
70 	va_start(ap, fmt);
71 	if (grecs_vasprintf(&buf, &size, fmt, ap))
72 		grecs_alloc_die();
73 	va_end(ap);
74 	grecs_print_diag_fun(locus, 1, errcode, buf);
75 	free(buf);
76 	grecs_error_count++;
77 }
78 
79 int
grecs_asprint_locus(char ** locstr,size_t * size,grecs_locus_t const * locus)80 grecs_asprint_locus(char **locstr, size_t *size, grecs_locus_t const *locus)
81 {
82 	int rc;
83 
84 	if (locus->beg.col == 0)
85 		rc = grecs_asprintf(locstr, size, "%s:%u",
86 				    locus->beg.file,
87 				    locus->beg.line);
88 	else if (strcmp(locus->beg.file, locus->end.file))
89 		rc = grecs_asprintf(locstr, size, "%s:%u.%u-%s:%u.%u",
90 				    locus->beg.file,
91 				    locus->beg.line, locus->beg.col,
92 				    locus->end.file,
93 				    locus->end.line, locus->end.col);
94 	else if (locus->beg.line != locus->end.line)
95 		rc = grecs_asprintf(locstr, size, "%s:%u.%u-%u.%u",
96 				    locus->beg.file,
97 				    locus->beg.line, locus->beg.col,
98 				    locus->end.line, locus->end.col);
99 	else if (locus->beg.col != locus->end.col)
100 		rc = grecs_asprintf(locstr, size, "%s:%u.%u-%u",
101 				    locus->beg.file,
102 				    locus->beg.line, locus->beg.col,
103 				    locus->end.col);
104 	else
105 		rc = grecs_asprintf(locstr, size, "%s:%u.%u",
106 				    locus->beg.file,
107 				    locus->beg.line,
108 				    locus->beg.col);
109 
110 	return rc;
111 }
112 
113 
114