Copied from old documentation. Removed all Gedcom_val details.
[gedcom-parse.git] / gedcom / message.c
index 6d44530ace816e769ddbfc0593a8ee03d1e4e9ef..c756356eb1e852b249569e15e8f98220ed5f946c 100644 (file)
-/*  This program is free software; you can redistribute it and/or modify  *
- *  it under the terms of the GNU General Public License as published by  *
- *  the Free Software Foundation; either version 2 of the License, or     *
- *  (at your option) any later version.                                   *
-
- (C) 2001 by The Genes Development Team
- Original author: Peter Verthez (Peter.Verthez@advalvas.be)
-*/
+/* Implementation of the messaging API to applications.
+   Copyright (C) 2001 The Genes Development Team
+   This file is part of the Gedcom parser library.
+   Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
+
+   The Gedcom parser library is free software; you can redistribute it
+   and/or modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The Gedcom parser library is distributed in the hope that it will be
+   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the Gedcom parser library; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 /* $Id$ */
 /* $Name$ */
 
 #include "gedcom_internal.h"
 #include "gedcom.h"
+#include "buffer.h"
 
-#define INITIAL_BUF_SIZE 256
-char *mess_buffer = NULL;
-size_t bufsize;
+void cleanup_mess_buffer();
 
+struct safe_buffer mess_buffer = { NULL, 0, NULL, 0, cleanup_mess_buffer };
 Gedcom_msg_handler msg_handler = NULL;
 
+/** This function registers a callback that is called if there are errors,
+    warnings or just messages coming from the parser.  See
+    \ref Gedcom_msg_handler for the signature of the callback.
+
+    For errors, the \c msg passed to the callback will have the format:
+    \code
+      Error on line <lineno>: <actual_message>
+    \endcode
+    Note that the entire string will be properly internationalized, and
+    encoded in UTF-8 (<a href=encoding.html>Why UTF-8?</a>).
+    Also, no newline is appended, so that
+    the application program can use it in any way it wants.  Warnings are
+    similar, but use "Warning" instead of "Error".  Messages are plain
+    text, without any prefix.
+*/
 void gedcom_set_message_handler(Gedcom_msg_handler func)
 {
   msg_handler = func;
 }
 
-void reset_mess_buffer()
-{
-  if (mess_buffer != NULL)
-    mess_buffer[0] = '\0';
-}
-
-void init_mess_buffer()
+void cleanup_mess_buffer()
 {
-  if (mess_buffer == NULL) {
-    mess_buffer = (char *)malloc(INITIAL_BUF_SIZE);
-    mess_buffer[0] = '\0';
-    bufsize = INITIAL_BUF_SIZE;
-  }
+  cleanup_buffer(&mess_buffer);
 }
 
-int safe_buf_vappend(char *s, va_list ap)
-{
-  int res;
-  int len;
-  init_mess_buffer();
-  len = strlen(mess_buffer);
-  while (1) {
-    char *buf_ptr = mess_buffer + len;
-    int rest_size = bufsize - len;
-    
-    res = vsnprintf(buf_ptr, rest_size, s, ap);
-    
-    if (res > -1 && res < rest_size) {
-      break;
-    }
-    else  {
-      bufsize *= 2;
-      mess_buffer = realloc(mess_buffer, bufsize);
-    }
-  }
-  return res;  
-}
-
-int safe_buf_append(char *s, ...)
-{
-  int res;
-  va_list ap;
-  
-  va_start(ap, s);
-  res = safe_buf_vappend(s, ap);
-  va_end(ap);
-  
-  return res;
-}
-
-int gedcom_message(char* s, ...)
+int gedcom_message(const char* s, ...)
 {
   int res;
   va_list ap;
 
   va_start(ap, s);
-  reset_mess_buffer();
-  res = safe_buf_vappend(s, ap);
+  reset_buffer(&mess_buffer);
+  res = safe_buf_vappend(&mess_buffer, s, ap);
   va_end(ap);
-  safe_buf_append("\n");
   if (msg_handler)
-    (*msg_handler)(MESSAGE, mess_buffer);
+    (*msg_handler)(MESSAGE, get_buf_string(&mess_buffer));
   return res;
 }
 
-int gedcom_warning(char* s, ...)
+int gedcom_warning(const char* s, ...)
 {
   int res;
   va_list ap;
 
-  reset_mess_buffer();
-  safe_buf_append("Warning on line %d: ", line_no);
+  reset_buffer(&mess_buffer);
+  if (line_no != 0) 
+    safe_buf_append(&mess_buffer, _("Warning on line %d: "), line_no);
+  else
+    safe_buf_append(&mess_buffer, _("Warning: "));
   va_start(ap, s);
-  res = safe_buf_vappend(s, ap);
+  res = safe_buf_vappend(&mess_buffer, s, ap);
   va_end(ap);
-  safe_buf_append("\n");
   if (msg_handler)
-    (*msg_handler)(WARNING, mess_buffer);
+    (*msg_handler)(WARNING, get_buf_string(&mess_buffer));
   
   return res;
 }
 
-int gedcom_error(char* s, ...)
+int gedcom_error(const char* s, ...)
 {
   int res;
   va_list ap;
 
-  reset_mess_buffer();
-  safe_buf_append("Error on line %d: ", line_no);
+  reset_buffer(&mess_buffer);
+  if (line_no != 0)
+    safe_buf_append(&mess_buffer, _("Error on line %d: "), line_no);
+  else
+    safe_buf_append(&mess_buffer, _("Error: "));
   va_start(ap, s);
-  res = safe_buf_vappend(s, ap);
+  res = safe_buf_vappend(&mess_buffer, s, ap);
   va_end(ap);
-  safe_buf_append("\n");
   if (msg_handler)
-    (*msg_handler)(ERROR, mess_buffer);
+    (*msg_handler)(ERROR, get_buf_string(&mess_buffer));
   
   return res;
 }
+
+void gedcom_mem_error(const char *filename, int line)
+{
+  gedcom_error(_("Could not allocate memory at %s, %d"), filename, line);
+}