1 /* Age manipulation routines.
2 Copyright (C) 2001,2002 The Genes Development Team
3 This file is part of the Gedcom parser library.
4 Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
6 The Gedcom parser library is free software; you can redistribute it
7 and/or modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The Gedcom parser library is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the Gedcom parser library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 #include "gedcom_internal.h"
33 struct age_value age_s;
34 struct age_value def_age_val;
36 void cleanup_age_buffer();
37 struct safe_buffer age_buffer = { NULL, 0, NULL, 0, cleanup_age_buffer };
39 void cleanup_age_buffer()
41 cleanup_buffer(&age_buffer);
44 void copy_age(struct age_value *to, struct age_value from)
46 memcpy(to, &from, sizeof(struct age_value));
49 void init_age(struct age_value *age)
51 age->type = AGE_UNRECOGNIZED;
52 age->mod = AGE_NO_MODIFIER;
58 int parse_numeric_age(struct age_value *age, const char *ptr)
62 long int number = strtol(ptr, &endptr, 10);
63 if (errno == ERANGE || number < 0 || number > INT_MAX) {
64 gedcom_error(_("Number out of range in age"));
71 else if (*ptr == 'Y' || *ptr == 'y') {
75 gedcom_error(_("Duplicate year indication in age"));
79 else if (*ptr == 'M' || *ptr == 'm') {
80 if (age->months == -1)
83 gedcom_error(_("Duplicate month indication in age"));
87 else if (*ptr == 'D' || *ptr == 'd') {
91 gedcom_error(_("Duplicate day indication in age"));
96 gedcom_error(_("Unrecognized indication in age: '%s'"), ptr);
100 while (*ptr == ' ') ptr++;
106 /** This function creates a new age_value struct and initializes it properly,
107 or copies an existing age value.
109 \param copy_from A given struct age_value to copy (or \c NULL).
111 \return If the parameter \c copy_from is NULL, a new value is created and
112 given initial values. If it is non-NULL, the given value is copied into
113 a new age value. In both cases, the new value is returned.
115 struct age_value* gedcom_new_age_value(const struct age_value* copy_from)
117 struct age_value* age_ptr;
118 age_ptr = (struct age_value*) malloc(sizeof(struct age_value));
123 memcpy(age_ptr, copy_from, sizeof(struct age_value));
130 /** This function allows to convert the given \c line_value into a struct
133 \param line_value A string containing the age to parse
135 \return The parsed age; note that this return value is statically
136 allocated, and is thus overwritten on each call.
138 struct age_value gedcom_parse_age(const char* line_value)
140 const char *ptr = line_value;
142 init_age(&def_age_val);
145 age_s.mod = AGE_LESS_THAN;
147 while (*ptr == ' ') ptr++;
149 else if (*ptr == '>') {
150 age_s.mod = AGE_GREATER_THAN;
152 while (*ptr == ' ') ptr++;
155 if (isdigit((unsigned char)*ptr)) {
156 int result = parse_numeric_age(&age_s, ptr);
158 age_s.type = AGE_NUMERIC;
161 else if (!strcasecmp(line_value, "CHILD"))
162 age_s.type = AGE_CHILD;
163 else if (!strcasecmp(line_value, "INFANT"))
164 age_s.type = AGE_INFANT;
165 else if (!strcasecmp(line_value, "STILLBORN"))
166 age_s.type = AGE_STILLBORN;
168 gedcom_error(_("Unrecognized age format"));
169 if (age_s.type == AGE_UNRECOGNIZED)
170 strncpy(age_s.phrase, line_value, MAX_PHRASE_LEN + 1);
174 /** This function converts the given struct age_value into its string
177 \param val The given parsed age
179 \return The string representation of the parsed age; note that this value
180 is statically allocated, and is thus overwritten on each call
182 char* gedcom_age_to_string(const struct age_value* val)
185 reset_buffer(&age_buffer);
189 safe_buf_append(&age_buffer, "<"); break;
190 case AGE_GREATER_THAN:
191 safe_buf_append(&age_buffer, ">"); break;
197 case AGE_UNRECOGNIZED:
198 reset_buffer(&age_buffer);
199 safe_buf_append(&age_buffer, val->phrase); break;
201 safe_buf_append(&age_buffer, "CHILD"); break;
203 safe_buf_append(&age_buffer, "INFANT"); break;
205 safe_buf_append(&age_buffer, "STILLBORN"); break;
207 if (val->years != -1) {
209 safe_buf_append(&age_buffer, "%dy", val->years);
211 if (val->months != -1) {
213 safe_buf_append(&age_buffer, " ");
215 safe_buf_append(&age_buffer, "%dm", val->months);
217 if (val->days != -1) {
219 safe_buf_append(&age_buffer, " ");
221 safe_buf_append(&age_buffer, "%dd", val->days);
228 return get_buf_string(&age_buffer);