New files: specifying the callback interface.
[gedcom-parse.git] / message.c
1 /*  This program is free software; you can redistribute it and/or modify  *
2  *  it under the terms of the GNU General Public License as published by  *
3  *  the Free Software Foundation; either version 2 of the License, or     *
4  *  (at your option) any later version.                                   *
5
6  (C) 2001 by The Genes Development Team
7  Original author: Peter Verthez (Peter.Verthez@advalvas.be)
8 */
9
10 /* $Id$ */
11 /* $Name$ */
12
13 #include "gedcom.h"
14 #include "external.h"
15
16 #define INITIAL_BUF_SIZE 256
17 char *mess_buffer = NULL;
18 size_t bufsize;
19
20 Gedcom_msg_handler msg_handler = NULL;
21
22 void gedcom_set_message_handler(Gedcom_msg_handler func)
23 {
24   msg_handler = func;
25 }
26
27 void reset_mess_buffer()
28 {
29   if (mess_buffer != NULL)
30     mess_buffer[0] = '\0';
31 }
32
33 void init_mess_buffer()
34 {
35   if (mess_buffer == NULL) {
36     mess_buffer = (char *)malloc(INITIAL_BUF_SIZE);
37     mess_buffer[0] = '\0';
38     bufsize = INITIAL_BUF_SIZE;
39   }
40 }
41
42 int safe_buf_vappend(char *s, va_list ap)
43 {
44   int res;
45   int len;
46   init_mess_buffer();
47   len = strlen(mess_buffer);
48   while (1) {
49     char *buf_ptr = mess_buffer + len;
50     int rest_size = bufsize - len;
51     
52     res = vsnprintf(buf_ptr, rest_size, s, ap);
53     
54     if (res > -1 && res < rest_size) {
55       break;
56     }
57     else  {
58       bufsize *= 2;
59       mess_buffer = realloc(mess_buffer, bufsize);
60     }
61   }
62   return res;  
63 }
64
65 int safe_buf_append(char *s, ...)
66 {
67   int res;
68   va_list ap;
69   
70   va_start(ap, s);
71   res = safe_buf_vappend(s, ap);
72   va_end(ap);
73   
74   return res;
75 }
76
77 int gedcom_message(char* s, ...)
78 {
79   int res;
80   va_list ap;
81
82   va_start(ap, s);
83   reset_mess_buffer();
84   res = safe_buf_vappend(s, ap);
85   va_end(ap);
86   safe_buf_append("\n");
87   if (msg_handler)
88     (*msg_handler)(MESSAGE, mess_buffer);
89   return res;
90 }
91
92 int gedcom_warning(char* s, ...)
93 {
94   int res;
95   va_list ap;
96
97   reset_mess_buffer();
98   safe_buf_append("Warning on line %d: ", line_no);
99   va_start(ap, s);
100   res = safe_buf_vappend(s, ap);
101   va_end(ap);
102   safe_buf_append("\n");
103   if (msg_handler)
104     (*msg_handler)(WARNING, mess_buffer);
105   
106   return res;
107 }
108
109 int gedcom_error(char* s, ...)
110 {
111   int res;
112   va_list ap;
113
114   reset_mess_buffer();
115   safe_buf_append("Error on line %d: ", line_no);
116   va_start(ap, s);
117   res = safe_buf_vappend(s, ap);
118   va_end(ap);
119   safe_buf_append("\n");
120   if (msg_handler)
121     (*msg_handler)(ERROR, mess_buffer);
122   
123   return res;
124 }