Increase library version
[gedcom-parse.git] / gedcom / age.c
index 8518411252cd952b0e6ff6c221ca12fed190ee27..e4705029dfedc9cb63e2ad0d5143418bfaa1e5e3 100644 (file)
 #include <errno.h>
 #include <limits.h>
 #include "gedcom_internal.h"
+#include "buffer.h"
 #include "age.h"
 
 struct age_value age_s;
 struct age_value def_age_val;
 
+void cleanup_age_buffer();
+struct safe_buffer age_buffer = { NULL, 0, NULL, 0, cleanup_age_buffer };
+
+void cleanup_age_buffer()
+{
+  cleanup_buffer(&age_buffer);
+}
+
 void copy_age(struct age_value *to, struct age_value from)
 {
   memcpy(to, &from, sizeof(struct age_value));
@@ -94,6 +103,38 @@ int parse_numeric_age(struct age_value *age, const char *ptr)
   return 0;
 }
 
+/** This function creates a new age_value struct and initializes it properly,
+    or copies an existing age value.
+
+    \param copy_from  A given struct age_value to copy (or \c NULL).
+
+    \return If the parameter \c copy_from is NULL, a new value is created and
+    given initial values.  If it is non-NULL, the given value is copied into
+    a new age value.  In both cases, the new value is returned.
+*/
+struct age_value* gedcom_new_age_value(const struct age_value* copy_from)
+{
+  struct age_value* age_ptr;
+  age_ptr = (struct age_value*) malloc(sizeof(struct age_value));
+  if (! age_ptr)
+    MEMORY_ERROR;
+  else {
+    if (copy_from)
+      memcpy(age_ptr, copy_from, sizeof(struct age_value));
+    else 
+      init_age(age_ptr);
+  }
+  return age_ptr;
+}
+
+/** This function allows to convert the given \c line_value into a struct
+    age_value.
+    
+    \param line_value A string containing the age to parse
+
+    \return The parsed age; note that this return value is statically
+    allocated, and is thus overwritten on each call.
+*/
 struct age_value gedcom_parse_age(const char* line_value)
 {
   const char *ptr = line_value;
@@ -111,7 +152,7 @@ struct age_value gedcom_parse_age(const char* line_value)
     while (*ptr == ' ') ptr++;
   }
 
-  if (isdigit(*ptr)) {
+  if (isdigit((unsigned char)*ptr)) {
     int result = parse_numeric_age(&age_s, ptr);
     if (result == 0) {
       age_s.type = AGE_NUMERIC;
@@ -130,3 +171,59 @@ struct age_value gedcom_parse_age(const char* line_value)
   return age_s;
 }
 
+/** This function converts the given struct age_value into its string
+    representation.
+
+    \param val  The given parsed age
+
+    \return The string representation of the parsed age; note that this value
+    is statically allocated, and is thus overwritten on each call
+*/
+char* gedcom_age_to_string(const struct age_value* val)
+{
+  int num = 0;
+  reset_buffer(&age_buffer);
+
+  switch (val->mod) {
+    case AGE_LESS_THAN:
+      safe_buf_append(&age_buffer, "<"); break;
+    case AGE_GREATER_THAN:
+      safe_buf_append(&age_buffer, ">"); break;
+    default:
+      break;
+  }
+
+  switch (val->type) {
+    case AGE_UNRECOGNIZED:
+      reset_buffer(&age_buffer);
+      safe_buf_append(&age_buffer, val->phrase); break;
+    case AGE_CHILD:
+      safe_buf_append(&age_buffer, "CHILD"); break;
+    case AGE_INFANT:
+      safe_buf_append(&age_buffer, "INFANT"); break;
+    case AGE_STILLBORN:
+      safe_buf_append(&age_buffer, "STILLBORN"); break;
+    case AGE_NUMERIC:
+      if (val->years != -1) {
+       num = 1;
+       safe_buf_append(&age_buffer, "%dy", val->years);
+      }
+      if (val->months != -1) {
+       if (num)
+         safe_buf_append(&age_buffer, " ");
+       num = 1;
+       safe_buf_append(&age_buffer, "%dm", val->months);
+      }
+      if (val->days != -1) {
+       if (num)
+         safe_buf_append(&age_buffer, " ");
+       num = 1;
+       safe_buf_append(&age_buffer, "%dd", val->days);
+      }
+      break;
+    default:
+      break;
+  }
+  
+  return get_buf_string(&age_buffer);
+}