2
Copyright (c) 1991-2005 Thomas T. Wetmore IV
4
Permission is hereby granted, free of charge, to any person
5
obtaining a copy of this software and associated documentation
6
files (the "Software"), to deal in the Software without
7
restriction, including without limitation the rights to use, copy,
8
modify, merge, publish, distribute, sublicense, and/or sell copies
9
of the Software, and to permit persons to whom the Software is
10
furnished to do so, subject to the following conditions:
12
The above copyright notice and this permission notice shall be
13
included in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
/*==============================================================
25
* datei.c -- Internal date code for structured shared betweeen date modules
26
* Copyright(c) 1992-2005 by T. T. Wetmore IV; all rights reserved
27
*============================================================*/
36
/*********************************************
37
* external/imported variables
38
*********************************************/
40
extern STRING qSdatea_abtA,qSdatea_abtB,qSdatea_estA,qSdatea_estB,qSdatea_calA;
41
extern STRING qSdatea_calB,qSdatep_fromA,qSdatep_fromB,qSdatep_toA,qSdatep_toB;
42
extern STRING qSdatep_frtoA,qSdatep_frtoB,qSdater_befA,qSdater_befB,qSdater_aftA;
43
extern STRING qSdater_aftB,qSdater_betA,qSdater_betB;
44
extern STRING qScaljul,qScalheb,qScalfr,qScalrom;
45
extern STRING qSmon_gj1A,qSmon_gj1B,qSmon_gj2A,qSmon_gj2B,qSmon_gj3A,qSmon_gj3B;
46
extern STRING qSmon_gj4A,qSmon_gj4B,qSmon_gj5A,qSmon_gj5B,qSmon_gj6A,qSmon_gj6B;
47
extern STRING qSmon_gj7A,qSmon_gj7B,qSmon_gj8A,qSmon_gj8B,qSmon_gj9A,qSmon_gj9B;
48
extern STRING qSmon_gj10A,qSmon_gj10B,qSmon_gj11A,qSmon_gj11B,qSmon_gj12A,qSmon_gj12B;
49
extern STRING qSmon_heb1A,qSmon_heb1B,qSmon_heb2A,qSmon_heb2B,qSmon_heb3A,qSmon_heb3B;
50
extern STRING qSmon_heb4A,qSmon_heb4B,qSmon_heb5A,qSmon_heb5B,qSmon_heb6A,qSmon_heb6B;
51
extern STRING qSmon_heb7A,qSmon_heb7B,qSmon_heb8A,qSmon_heb8B,qSmon_heb9A,qSmon_heb9B;
52
extern STRING qSmon_heb10A,qSmon_heb10B,qSmon_heb11A,qSmon_heb11B;
53
extern STRING qSmon_heb12A,qSmon_heb12B,qSmon_heb13A,qSmon_heb13B;
54
extern STRING qSmon_fr1A,qSmon_fr1B,qSmon_fr2A,qSmon_fr2B,qSmon_fr3A,qSmon_fr3B;
55
extern STRING qSmon_fr4A,qSmon_fr4B,qSmon_fr5A,qSmon_fr5B,qSmon_fr6A,qSmon_fr6B;
56
extern STRING qSmon_fr7A,qSmon_fr7B,qSmon_fr8A,qSmon_fr8B,qSmon_fr9A,qSmon_fr9B;
57
extern STRING qSmon_fr10A,qSmon_fr10B,qSmon_fr11A,qSmon_fr11B;
58
extern STRING qSmon_fr12A,qSmon_fr12B,qSmon_fr13A,qSmon_fr13B;
60
/*********************************************
61
* local function prototypes
62
*********************************************/
65
static void init_keywordtbl(void);
66
static void load_lang(void);
67
static STRING lower_dup(STRING s);
68
static STRING title_dup(STRING s);
69
static STRING upper_dup(STRING s);
71
/*********************************************
73
*********************************************/
75
STRING cmplx_custom[ECMPLX_END];
76
STRING cmplx_pics[ECMPLX_END][6];
80
/* generated month names (for Gregorian/Julian months) */
81
STRING calendar_pics[GDV_CALENDARS_IX];
83
STRING roman_lower[] = { "i","ii","iii","iv","v","vi","vii","viii"
84
,"ix","x","xi","xii","xiii" };
85
STRING roman_upper[] = { "I","II","III","IV","V","VI","VII","VIII"
86
,"IX","X","XI","XII","XIII" };
88
MONTH_NAMES months_gj[12];
89
MONTH_NAMES months_fr[13];
90
MONTH_NAMES months_heb[13];
92
/* GEDCOM keywords (fixed, not language dependent) */
93
struct gedcom_keywords_s gedkeys[] = {
94
/* Gregorian/Julian months are values 1 to 12 */
107
/* Hebew months are values 301 to 313 */
121
/* French Republic months are values 401 to 413 */
135
/* modifiers are values 1001 to 1000+GD_END2 */
136
,{ "ABT", 1000+GD_ABT }
137
,{ "EST", 1000+GD_EST }
138
,{ "CAL", 1000+GD_CAL }
139
,{ "BEF", 1000+GD_BEF }
140
,{ "AFT", 1000+GD_AFT }
141
,{ "BET", 1000+GD_BET }
142
,{ "AND", 1000+GD_AND }
143
,{ "FROM", 1000+GD_FROM }
144
,{ "TO", 1000+GD_TO }
145
/* calendars are values 2001 to 2000+GDV_CALENDARS_IX */
146
,{ "@#DGREGORIAN@", 2000+GDV_GREGORIAN }
147
,{ "@#DJULIAN@", 2000+GDV_JULIAN }
148
,{ "@#DHEBREW@", 2000+GDV_HEBREW }
149
,{ "@#DFRENCH R@", 2000+GDV_FRENCH }
150
,{ "@#DROMAN@", 2000+GDV_ROMAN }
152
/* parentheses are handled by lexical tokenizer */
153
,{ "B.C.", 1000+GD_BC }
154
/* Some liberal (non-GEDCOM) entries */
155
,{ "BC", 1000+GD_BC }
156
,{ "B.C.E.", 1000+GD_BC }
157
,{ "BCE", 1000+GD_BC }
158
,{ "A.D.", 1000+GD_AD }
159
,{ "AD", 1000+GD_AD }
160
,{ "C.E.", 1000+GD_AD }
161
,{ "CE", 1000+GD_AD }
162
/* Some liberal (non-GEDCOM) but English-biased entries */
175
,{ "ABOUT", 1000+GD_ABT }
176
,{ "ESTIMATED", 1000+GD_EST }
177
,{ "CALCULATED", 1000+GD_CAL }
178
,{ "BEFORE", 1000+GD_BEF }
179
,{ "AFTER", 1000+GD_AFT }
180
,{ "BETWEEN", 1000+GD_BET }
184
TABLE keywordtbl = NULL;
185
BOOLEAN lang_changed=FALSE;
188
/*=============================
189
* initialize_if_needed -- init module or reload language
190
*===========================*/
192
initialize_if_needed (void)
197
} else if (lang_changed) {
199
lang_changed = FALSE;
202
/*=========================================
203
* init_keywordtbl -- Set up table of known
204
* keywords which we recognize in parsing dates
205
*=======================================*/
207
init_keywordtbl (void)
210
keywordtbl = create_table_int();
211
/* Load GEDCOM keywords & values into keyword table */
212
for (i=0; i<ARRSIZE(gedkeys); ++i) {
213
j = gedkeys[i].value;
214
insert_table_int(keywordtbl, gedkeys[i].keyword, j);
216
/* TODO: We need to load months of other calendars here */
219
/*=============================
220
* load_one_cmplx_pic -- Generate case variations
221
* of one complex picture string.
222
* Created: 2001/12/30 (Perry Rapp)
223
*===========================*/
225
load_one_cmplx_pic (INT ecmplx, STRING abbrev, STRING full)
227
STRING loc_abbrev = strsave(abbrev);
228
STRING loc_full = strsave(full);
229
ASSERT(ecmplx>=0 && ecmplx <ECMPLX_END);
230
/* 0=ABT (cmplx=3) */
231
cmplx_pics[ecmplx][0] = upper_dup(loc_abbrev);
232
/* 1=Abt (cmplx=4) */
233
cmplx_pics[ecmplx][1] = title_dup(loc_abbrev);
234
/* 2=ABOUT (cmplx=5) */
235
cmplx_pics[ecmplx][2] = upper_dup(loc_full);
236
/* 3=About (cmplx=6) */
237
cmplx_pics[ecmplx][3] = title_dup(loc_full);
238
/* 4=abt (cmplx=7) */
239
cmplx_pics[ecmplx][4] = lower_dup(loc_abbrev);
240
/* 5=about (cmplx=8) */
241
cmplx_pics[ecmplx][5] = lower_dup(loc_full);
246
/*=============================
247
* load_one_month -- Generate case variations
249
* @monum: [IN] month num (0-based)
250
* @monarr: [I/O] month array
251
* @abbrev: [IN] eg, "jan"
252
* @full: [IN] eg, "january"
253
*===========================*/
255
load_one_month (INT monum, MONTH_NAMES * monarr, STRING abbrev, STRING full)
257
/* 0-5 codes as in load_cmplx_pic(...) above */
258
STRING locx_abbrev = strsave(abbrev);
259
STRING loc_full = strsave(full);
260
STRING loc_abbrev = locx_abbrev;
261
/* special handling for **may, to differentiate from may */
262
if (loc_abbrev[0]=='*' && loc_abbrev[1]=='*')
264
monarr[monum][0] = upper_dup(loc_abbrev);
265
monarr[monum][1] = title_dup(loc_abbrev);
266
monarr[monum][2] = upper_dup(loc_full);
267
monarr[monum][3] = title_dup(loc_full);
268
monarr[monum][4] = lower_dup(loc_abbrev);
269
monarr[monum][5] = lower_dup(loc_full);
270
stdfree(locx_abbrev);
273
/*=============================
274
* clear_lang -- Free all generated picture strings
275
* This is used both changing languages, and at cleanup time
276
*===========================*/
281
/* clear complex pics */
282
for (i=0; i<ECMPLX_END; ++i) {
283
for (j=0; j<6; ++j) {
284
strfree(&cmplx_pics[i][j]);
287
/* clear calendar pics */
288
for (i=0; i<ARRSIZE(calendar_pics); ++i) {
289
strfree(&calendar_pics[i]);
291
/* clear Gregorian/Julian month names */
292
for (i=0; i<ARRSIZE(months_gj); ++i) {
293
for (j=0; j<ARRSIZE(months_gj[0]); ++j) {
294
strfree(&months_gj[i][j]);
297
/* clear Hebrew month names */
298
for (i=0; i<ARRSIZE(months_heb); ++i) {
299
for (j=0; j<ARRSIZE(months_heb[0]); ++j) {
300
strfree(&months_heb[i][j]);
303
/* clear French Republic month names */
304
for (i=0; i<ARRSIZE(months_fr); ++i) {
305
for (j=0; j<ARRSIZE(months_fr[0]); ++j) {
306
strfree(&months_fr[i][j]);
310
/*=============================
311
* load_lang -- Load generated picture strings
312
* based on current language
313
* This must be called if current language changes.
314
*===========================*/
320
/* TODO: if we have language-specific cmplx_custom, deal with
323
/* free all pictures */
326
/* load complex pics */
327
load_one_cmplx_pic(ECMPLX_ABT, _(qSdatea_abtA), _(qSdatea_abtB));
328
load_one_cmplx_pic(ECMPLX_EST, _(qSdatea_estA), _(qSdatea_estB));
329
load_one_cmplx_pic(ECMPLX_CAL, _(qSdatea_calA), _(qSdatea_calB));
330
load_one_cmplx_pic(ECMPLX_FROM, _(qSdatep_fromA), _(qSdatep_fromB));
331
load_one_cmplx_pic(ECMPLX_TO, _(qSdatep_toA), _(qSdatep_toB));
332
load_one_cmplx_pic(ECMPLX_FROM_TO, _(qSdatep_frtoA), _(qSdatep_frtoB));
333
load_one_cmplx_pic(ECMPLX_BEF, _(qSdater_befA), _(qSdater_befB));
334
load_one_cmplx_pic(ECMPLX_AFT, _(qSdater_aftA), _(qSdater_aftB));
335
load_one_cmplx_pic(ECMPLX_BET_AND, _(qSdater_betA), _(qSdater_betB));
336
/* test that all were loaded */
337
for (i=0; i<ECMPLX_END; ++i) {
338
for (j=0; j<6; ++j) {
339
ASSERT(cmplx_pics[i][j]);
344
calendar_pics[GDV_JULIAN] = strsave(_(qScaljul));
345
calendar_pics[GDV_HEBREW] = strsave(_(qScalheb));
346
calendar_pics[GDV_FRENCH] = strsave(_(qScalfr));
347
calendar_pics[GDV_ROMAN] = strsave(_(qScalrom));
348
/* not all slots in calendar_pics are used */
350
/* load Gregorian/Julian month names */
351
load_one_month(0, months_gj, _(qSmon_gj1A), _(qSmon_gj1B));
352
load_one_month(1, months_gj, _(qSmon_gj2A), _(qSmon_gj2B));
353
load_one_month(2, months_gj, _(qSmon_gj3A), _(qSmon_gj3B));
354
load_one_month(3, months_gj, _(qSmon_gj4A), _(qSmon_gj4B));
355
load_one_month(4, months_gj, _(qSmon_gj5A), _(qSmon_gj5B));
356
load_one_month(5, months_gj, _(qSmon_gj6A), _(qSmon_gj6B));
357
load_one_month(6, months_gj, _(qSmon_gj7A), _(qSmon_gj7B));
358
load_one_month(7, months_gj, _(qSmon_gj8A), _(qSmon_gj8B));
359
load_one_month(8, months_gj, _(qSmon_gj9A), _(qSmon_gj9B));
360
load_one_month(9, months_gj, _(qSmon_gj10A), _(qSmon_gj10B));
361
load_one_month(10, months_gj, _(qSmon_gj11A), _(qSmon_gj11B));
362
load_one_month(11, months_gj, _(qSmon_gj12A), _(qSmon_gj12B));
363
/* test that all were loaded */
364
for (i=0; i<ARRSIZE(months_gj); ++i) {
365
for (j=0; j<ARRSIZE(months_gj[0]); ++j) {
366
ASSERT(months_gj[i][j]);
370
/* load Hebrew month names */
371
load_one_month(0, months_heb, _(qSmon_heb1A), _(qSmon_heb1B));
372
load_one_month(1, months_heb, _(qSmon_heb2A), _(qSmon_heb2B));
373
load_one_month(2, months_heb, _(qSmon_heb3A), _(qSmon_heb3B));
374
load_one_month(3, months_heb, _(qSmon_heb4A), _(qSmon_heb4B));
375
load_one_month(4, months_heb, _(qSmon_heb5A), _(qSmon_heb5B));
376
load_one_month(5, months_heb, _(qSmon_heb6A), _(qSmon_heb6B));
377
load_one_month(6, months_heb, _(qSmon_heb7A), _(qSmon_heb7B));
378
load_one_month(7, months_heb, _(qSmon_heb8A), _(qSmon_heb8B));
379
load_one_month(8, months_heb, _(qSmon_heb9A), _(qSmon_heb9B));
380
load_one_month(9, months_heb, _(qSmon_heb10A), _(qSmon_heb10B));
381
load_one_month(10, months_heb, _(qSmon_heb11A), _(qSmon_heb11B));
382
load_one_month(11, months_heb, _(qSmon_heb12A), _(qSmon_heb12B));
383
load_one_month(12, months_heb, _(qSmon_heb13A), _(qSmon_heb13B));
384
/* test that all were loaded */
385
for (i=0; i<ARRSIZE(months_heb); ++i) {
386
for (j=0; j<ARRSIZE(months_heb[0]); ++j) {
387
ASSERT(months_heb[i][j]);
391
/* load French Republic month names */
392
load_one_month(0, months_fr, _(qSmon_fr1A), _(qSmon_fr1B));
393
load_one_month(1, months_fr, _(qSmon_fr2A), _(qSmon_fr2B));
394
load_one_month(2, months_fr, _(qSmon_fr3A), _(qSmon_fr3B));
395
load_one_month(3, months_fr, _(qSmon_fr4A), _(qSmon_fr4B));
396
load_one_month(4, months_fr, _(qSmon_fr5A), _(qSmon_fr5B));
397
load_one_month(5, months_fr, _(qSmon_fr6A), _(qSmon_fr6B));
398
load_one_month(6, months_fr, _(qSmon_fr7A), _(qSmon_fr7B));
399
load_one_month(7, months_fr, _(qSmon_fr8A), _(qSmon_fr8B));
400
load_one_month(8, months_fr, _(qSmon_fr9A), _(qSmon_fr9B));
401
load_one_month(9, months_fr, _(qSmon_fr10A), _(qSmon_fr10B));
402
load_one_month(10, months_fr, _(qSmon_fr11A), _(qSmon_fr11B));
403
load_one_month(11, months_fr, _(qSmon_fr12A), _(qSmon_fr12B));
404
load_one_month(12, months_fr, _(qSmon_fr13A), _(qSmon_fr13B));
405
/* test that all were loaded */
406
for (i=0; i<ARRSIZE(months_fr); ++i) {
407
for (j=0; j<ARRSIZE(months_fr[0]); ++j) {
408
ASSERT(months_fr[i][j]);
412
/*=============================
413
* term_date -- Cleanup for finishing program
414
* Created: 2003-02-02 (Perry Rapp)
415
*===========================*/
421
destroy_table(keywordtbl);
425
/*=============================
426
* upper_dup -- Get uppercase & strdup it
427
*===========================*/
431
ZSTR zstr = ll_toupperz(s, uu8);
432
STRING str = strdup(zs_str(zstr));
436
/*=============================
437
* lower_dup -- Get lowercase & strdup it
438
*===========================*/
442
ZSTR zstr = ll_tolowerz(s, uu8);
443
STRING str = strdup(zs_str(zstr));
447
/*=============================
448
* title_dup -- Get titlecase & strdup it
449
*===========================*/
453
ZSTR zstr = ll_totitlecasez(s, uu8);
454
STRING str = strdup(zs_str(zstr));
458
/*=============================
459
* date_get_day -- Day number of first date
460
*===========================*/
462
date_get_day (GDATEVAL gdv)
465
return gdv->date1.day.val;
467
/*=============================
468
* date_get_month -- Month number of first date
469
*===========================*/
471
date_get_month (GDATEVAL gdv)
474
return gdv->date1.month.val;
476
/*=============================
477
* date_get_year -- Year number of first date
478
*===========================*/
480
date_get_year (GDATEVAL gdv)
483
return gdv->date1.year.val;
485
/*=============================
486
* date_get_year_string -- Raw year string of first date
487
*===========================*/
489
date_get_year_string (GDATEVAL gdv)
492
return gdv->date1.year.str;
494
/*=============================
495
* date_get_mod -- Mod value of first date
496
* Perry, 2005-09-25, I don't think this is ever populated
497
*===========================*/
499
date_get_mod (GDATEVAL gdv)
502
return gdv->date1.mod;