X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=gedcom%2Fdate.c;h=23a689e21abd7b02848a4c1a845397ac099161ab;hb=HEAD;hp=40cb18a7115eca0c5a86f2600e6c73b54b311dee;hpb=31fb8432ef01f9d5a08cc801a785a07b4e9d12bd;p=gedcom-parse.git diff --git a/gedcom/date.c b/gedcom/date.c index 40cb18a..23a689e 100644 --- a/gedcom/date.c +++ b/gedcom/date.c @@ -336,7 +336,7 @@ int numbers_to_strings(struct date *d) if (d->day != -1) sprintf(d->day_str, "%d", d->day); - if (d->month != -1) + if (d->month > 0 && d->month <= max_month[d->cal]) strcpy(d->month_str, month_name[d->cal][d->month - 1]); if (d->year_type == YEAR_SINGLE) @@ -347,11 +347,77 @@ int numbers_to_strings(struct date *d) return result; } -int gedcom_normalize_date(Date_input input, struct date_value *val) +/** This function can be called to ensure that an updated date_value is + consistent, i.e. all its struct fields are consistent with each other. + Depending on which fields you have updated, you should give the correct + \c compute_from field. + + The following table gives an overview of the input and output parameters + (the calendar type \c cal is always an input parameter, and should not be + \c CAL_UNKNOWN): + + + + + + + + + + + + + + + + + + + + + +
compute_frominput parametersoutput parameters
DI_FROM_STRINGSday_str, month_str, year_strday, month, year, year_type
+ type, sdn1, sdn2
DI_FROM_NUMBERSday, month, year, year_typeday_str, month_str, year_str
+ type, sdn1, sdn2
DI_FROM_SDNtype, sdn1, sdn2day, month, year
+ day_str, month_str, year_str
+ + If the type in the date_value is \c DV_PHRASE, no conversions take place, + otherwise one or both of the date structs are processed according to the + table above, depending on the type. + + This function could also be used to convert a date from one calendar to + another, because the serial day number is calendar independent (error + handling is ignored in this example): + + \code + struct date_value* dv = gedcom_new_date_value(NULL); + dv->date1.cal = CAL_GREGORIAN; + dv->date1.day = 4; + dv->date1.month = 2; + dv->date1.year = 1799; + dv->date1.year_type = YEAR_SINGLE; + gedcom_normalize_date(DI_FROM_NUMBERS, dv); + + dv->date1.cal = CAL_FRENCH_REV; + gedcom_normalize_date(DI_FROM_SDN, dv); + \endcode + + At the end of this piece of code, the day, month and year are filled in + according to the French Revolution calendar. + + \param compute_from Determines which fields will be taken as input to + compute the other fields. + + \param val The struct date_value to update (it will be updated in place) + + \retval 0 on success + \retval >0 on failure +*/ +int gedcom_normalize_date(Date_input compute_from, struct date_value *val) { int result = 0; if (val->type != DV_PHRASE) { - switch (input) { + switch (compute_from) { case DI_FROM_STRINGS: result |= strings_to_numbers(&val->date1); result |= numbers_to_sdn(&val->date1); @@ -383,6 +449,15 @@ int gedcom_normalize_date(Date_input input, struct date_value *val) return result; } +/** This function creates a new date_value struct and initializes it properly, + or copies an existing date value. + + \param copy_from A given struct date_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 date value. In both cases, the new value is returned. +*/ struct date_value* gedcom_new_date_value(const struct date_value* copy_from) { struct date_value* dv_ptr; @@ -402,29 +477,46 @@ struct date_value* gedcom_new_date_value(const struct date_value* copy_from) return dv_ptr; } +/** This function allows to convert the given \c line_value into a struct + date_value. + + \param line_value A string containing the date to parse + + \return The parsed date; note that this return value is statically + allocated, and is thus overwritten on each call. +*/ struct date_value gedcom_parse_date(const char* line_value) { int result = 0; + init_date(&dv_s.date1); + init_date(&dv_s.date2); init_date(&date_s); init_date(&def_date); curr_line_value = line_value; if (compat_mode(C_NO_REQUIRED_VALUES) - && !strncmp(curr_line_value, "-", 2)) { - gedcom_date_error(_("Empty value changed to '-'")); + && !strncmp(curr_line_value, VALUE_IF_MISSING, 2)) { + gedcom_date_error(_("Empty value changed to '%s'"), VALUE_IF_MISSING); result = 1; } else { + compat_date_start(); init_gedcom_date_lex(line_value); gedcom_date_parse(); close_gedcom_date_lex(); + if (compat_date_check(&dv_s, &curr_line_value)) { + init_gedcom_date_lex(curr_line_value); + gedcom_date_parse(); + close_gedcom_date_lex(); + } if (dv_s.date1.cal != CAL_UNKNOWN) result |= numbers_to_sdn(&dv_s.date1); if (dv_s.date2.cal != CAL_UNKNOWN) result |= numbers_to_sdn(&dv_s.date2); } if (result != 0) { - gedcom_date_error(_("Putting date in 'phrase' member")); - make_date_value(DV_PHRASE, &def_date, &def_date, curr_line_value); + gedcom_date_error(_("Putting date '%s' in 'phrase' member"), + curr_line_value); + make_date_value(DV_PHRASE, &dv_s.date1, &dv_s.date2, curr_line_value); } return dv_s; } @@ -455,6 +547,14 @@ void write_date(const struct date* d) } } +/** This function converts the given struct date_value into its string + representation. + + \param val The given parsed date + + \return The string representation of the parsed date; note that this value + is statically allocated, and is thus overwritten on each call +*/ char* gedcom_date_to_string(const struct date_value* val) { init_buffer(&date_buffer);