1 /* -- pagc_api.h
2 
3 This file is the common header file for PAGC internal routines
4 
5 Prototype 20H10 (This file was written by Walter Sinclair).
6 
7 Copyright (c) 2001-2012 Walter Bruce Sinclair
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12 
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14 
15 */
16 
17 /* For pagc-0.4.2 : last revised 2012-08-31 */
18 
19 #ifndef PGC_H
20 #define PGC_H
21 
22 #define BUILD_API
23 
24 #include <postgres.h>
25 
26 #ifdef DEBUG
27 #define DBG(format, arg...)                     \
28     elog(NOTICE, format , ## arg)
29 #else
30 #define DBG(format, arg...) do { ; } while (0)
31 #endif
32 
33 #include "pagc_tools.h"
34 
35 #ifndef BUILD_API
36 #include "pagc_common.h"
37 
38 #ifdef MINGW32
39 #include <windows.h>
40 #endif
41 
42 #ifdef ENABLE_THREADED
43 #ifdef HAVE_PTHREAD
44 #include <pthread.h>
45 #endif
46 #endif
47 
48 #else
49 
50 #define SENTINEL '\0'
51 #define BLANK_STRING(STR) *STR = SENTINEL
52 #define MAXSTRLEN 256
53 
54 /* -- boolean -- */
55 #ifndef TRUE
56 #define TRUE 1
57 #define FALSE 0
58 #endif
59 
60 #define ERR_FAIL -2
61 #define FAIL -1
62 #define BOTH 2
63 
64 typedef int SYMB ;
65 typedef double DS_Score_t ;
66 typedef void * DS_Handle ;
67 
68 #endif
69 
70 #include <math.h>
71 #ifndef BUILD_API
72 #include "ds.h"
73 
74 #define THREE_SOURCE_IDS
75 
76 //#define WITH_ALT_LEFT_RIGHT
77 
78 /* 2009-07-21 : keep track of version
79    2010-02-01 : increase to 0.3.0
80    2010-08-20 : increase to 0.4.0
81    2011-08-14 : increase to 0.4.1 */
82 
83 #ifdef WITH_ALT_LEFT_RIGHT
84 #define CUR_PAGC_VER 41
85 #else
86 #define CUR_PAGC_VER 40
87 #endif
88 #endif
89 /* -- uncomment to index soundex-zip combo keys
90 #define COMBINE_POSTAL_WITH_SOUNDEX
91 -- */
92 
93 
94 #define USE_METERS
95 #define MAX_ATT_FLDS 4
96 #define MAX_REDIRECTS 6
97 #define COMMA ','
98 #define NEITHER 0
99 #define LEFT -1
100 #define RIGHT 1
101 #define OCCUPANCY_MULTIPLE 16
102 #define EXACT_MICRO_MATCH 32
103 #define EXACT_MACRO_MATCH 64
104 #define MACRO_THRESHOLD_MATCH 128
105 #define EPSILON 0
106 /* 2009-10-16 : increase size of MAXPHRASE and LANDMARK_ARRAY_WIDTH */
107 #define MAXPHRASE 10
108 #define LANDMARK_ARRAY_WIDTH 10 + MAXPHRASE
109 #define MAXFLDLEN MAXSTRLEN
110 #define MAX_REC_SPACE 262144
111 #define MAX_SCHEMAS 6 /* 2008-07-28 increased from 3 */
112 #define MAX_ERRORS 512
113 
114 /* -- input symbols -- */
115 #define NUMBER 0
116 #define WORD 1
117 #define TYPE 2
118 
119 #define ROAD 6
120 #define STOPWORD 7
121 
122 #define DASH 9
123 
124 #define AMPERS 13
125 
126 #define ORD 15
127 
128 #define SINGLE 18
129 #define BUILDH 19
130 #define MILE 20
131 #define DOUBLE 21
132 #define DIRECT 22
133 #define MIXED 23
134 #define BUILDT 24
135 #define FRACT 25
136 #define PCT 26
137 #define PCH 27
138 #define QUINT 28
139 #define QUAD 29
140 #define MAXINSYM QUAD + 1
141 
142 /* -- output symbols -- */
143 #define BLDNG 0
144 #define HOUSE 1
145 #define PREDIR 2
146 #define QUALIF 3
147 #define PRETYP 4
148 #define STREET 5
149 #define SUFTYP 6
150 #define SUFDIR 7
151 #define RR 8
152 #define UNKNWN 9
153 #define CITY 10
154 #define PROV 11
155 #define NATION 12
156 #define POSTAL 13
157 #define BOXH 14
158 #define BOXT 15
159 #define UNITH 16
160 #define UNITT 17
161 #define MAXOUTSYM UNITT + 1
162 #define NEEDHEAD BOXH
163 
164 /* 2009-07-19 : redefinitions in a landmarks context :
165 needed to collect from standardization output. */
166 #define FEATNAME 0
167 #define FEATTYPE 8
168 #define FEATAREA 9
169 #define FEAT_L 7
170 #define FEAT_T 8
171 #define FEAT_A 9
172 
173 /* -- comparison types -- */
174 #define NO_COMPARISON 0
175 #define CHAR_SINGLE 1
176 #define POSTAL_SINGLE 2
177 #define NUMBER_SINGLE 3
178 #define CHAR_LEFT_RIGHT 4
179 #define POSTAL_LEFT_RIGHT 5
180 #define POSTAL_SPLIT 6
181 #define NUMBER_INTERVAL 7
182 #define NUMBER_INTERVAL_LEFT_RIGHT 8
183 #define POSTAL_LEFT_RIGHT_SPLIT 9
184 #define CHAR_ALT 10 /* 2008-07-30 : for alternate names */
185 #ifdef WITH_ALT_LEFT_RIGHT
186 #define CHAR_ALT_LEFT_RIGHT 11 /* 2008-07-30 : for alternate names */
187 #endif
188 
189 #define ERR_READ -1
190 #define OK_READ 0
191 #define GOOD_READ 1
192 #define MAX_EDIT_DIST 2
193 #define US_FULL_CODE_LEN 10
194 #define US_PART_CODE_LEN 5
195 #define SXCODELEN 4
196 #define DEGREES_TO_RADIANS .0174532925199432958
197 #define DOUBLE_PI 6.2831853071795864769
198 #define PI 3.14159265358979323846
199 #define HALF_PI 1.57079632679489661923
200 
201 #ifdef USE_METERS
202 #define EARTH_RADIUS 6378000.
203 #endif
204 
205 #ifndef BUILD_API
206 /* FLAGS : 2009-07-19 : express as hexadecimal */
207 
208 typedef unsigned int PAGC_FLAG_T ;
209 
210 #define REVERSE_GEO				0x00000001u /* reserved for future use*/
211 /* pagc_common.h : #define STATISTICS 2 */
212 /* ds.h : #define HAVE_DBF_POSITION	0x00000004u */
213 #define ENABLE_PSEUDO			0x00000008u /* -- allows pseudo edit of reference -- FLPSEUD in schema -- */
214 #define ENABLE_CROSS			0x00000010u /* schema : XSTREET with fields */
215 #define ENABLE_ALT				0x00000020u /* reserved for future use*/
216 #define ENABLE_LAND				0x00000040u /* 2009-07-19 : denote presence of Feature Name field */
217 /* pagc_common.h : #define PRINT_PROGRESS 128 */
218 #define APPEND					0x00000100u /* -- internal flag for APPEND builds -- */
219 /* pagc_common.h :#define ZERO_IS_BLANK 512 */
220 #define HAVE_OCCUPANCY			0x00000400u /* schema : OCCUP1 or OCCUP2 with fields */
221 /* pagc_common.h :#define LOG_COMPLETE 2048 */
222 /* pagc_common.h :#define RNF_PRETYPE_REDIRECT 4096 */
223 #define CONCURRENT_PRIVATE		0x00002000u /* schema: FLCONPR -- deprecating */
224 #define NO_STOP_ON_EXACT		0x00004000u /* schema: FLNOSEX */
225 #define CAN_THREAD				0x00008000u
226 /* ds.h #define READ_POINTS_SEQUENTIAL	0x00010000u */
227 #define HAVE_OFFICIAL_STREET	0x00020000u /* schema : FLOFFST -- 2008-07-28 : new */
228 #define HAVE_SOURCE_ID			0x00040000u /* schema : SOURCEID with field */
229 #define HAVE_FEAT_TYPE			0x00080000u /* 2009-07-19 : denote presence of Feature Type field */
230 #define HAVE_SUBDISTRICT		0x00100000u /* 2009-07-19 : denote presence of Feature Area field */
231 
232 #ifdef THREE_SOURCE_IDS
233 #define HAVE_SOURCE_ID_B			0x00200000u /* schema : SOURCEID_B with field */
234 #define HAVE_SOURCE_ID_C			0x00400000u /* schema : SOURCEID_C with field */
235 #endif
236 #endif
237 /* -- error records -- */
238 
239 typedef struct err_rec
240 {
241 	int is_fatal ; /* -- is this a fatal error ? -- */
242 	char content_buf[MAXSTRLEN] ; /* -- storage for message -- */
243 } ERR_REC ;
244 
245 typedef struct err_param
246 {
247 	int last_err ;
248 	int first_err ;
249 	int next_fatal ;
250 	ERR_REC err_array[MAX_ERRORS] ;
251 	char *error_buf ;
252 	FILE *stream ; /* -- stream for log file -- */
253 } ERR_PARAM ;
254 
255 /*===================================================================
256                           STANDARDIZATION
257 ===================================================================*/
258 typedef int NODE ;
259 typedef int DEFDEF ;
260 
261 #define MAXTEXT MAXSTRLEN
262 
263 #define FIRST_LEX_POS 0
264 #define RIGHT_COMPRESS STOPWORD
265 #define LEFT_COMPRESS WORD
266 
267 /* -- weight names -- */
268 #define LOW 3
269 #define LOW_MEDIUM 6
270 #define MEDIUM 9
271 #define HIGH_MEDIUM  12
272 #define HIGH 15
273 #define EXCELLENT 16
274 #define PERFECT 17
275 #define NUMBER_OF_WEIGHTS PERFECT + 1
276 
277 #define MAXDEF 8
278 #define MAX_STZ 6 /* <revision date='2012-06-03'>return to 6</revision> */
279 #define MAXMORPHS 64
280 #define MAXLEX 64
281 
282 /* -- options for SendFields -- */
283 #define PSEUDO_XML 0
284 #define PSEUDO_CSV 1
285 #define SCREEN 2
286 #define NO_FORMAT 3
287 
288 /* -- clause/class numbers -- */
289 #define MACRO_C 0
290 #define MICRO_C 1
291 #define ARC_C 2
292 #define CIVIC_C 3
293 #define EXTRA_C 4
294 #define MAX_CL 5
295 
296 #define EXTRA_STATE 6
297 
298 /* -- start_states -- */
299 #define MICRO_B 0
300 #define MICRO_M 1
301 #define MACRO   2
302 #define PREFIX  3
303 #define EXIT  4
304 
305 /* -- tokens --
306    used in tokenize.c -- */
307 #define DFRACT 0
308 #define DSINGLE 1
309 #define DDOUBLE 2
310 /* -- changed so not to conflict with Windows def --*/
311 #define DWORDT 3
312 #define DNUMBER 4
313 #define DMIXED 5
314 #define DPOSTH 6
315 #define DPOSTT 7
316 #define DZIPH 8
317 #define DZIPT 9
318 #define DDIRLET 10
319 #define DORD 11
320 #define DUNIT 12
321 
322 /* ================= standardization records ===================*/
323 
324 /* -- This structure stores a definition for a lexical entry -- */
325 typedef struct def
326 {
327 	int Order ; /* -- the order in the list -- */
328 	SYMB Type ; /* -- the Input symbol -- */
329 	int Protect ;
330 	char *Standard ; /* -- The standardization -- */
331 	struct def *Next ;
332 } DEF ;
333 
334 /* -- This stores the data for a lexical entry -- */
335 typedef struct entry
336 {
337 	char *Lookup ; /* -- To match against the input word -- */
338 	DEF *DefList ; /* -- list of definitions and outputs for this word -- */
339 	struct entry *Next ;
340 } ENTRY ;
341 
342 
343 /* -- storage for standardization rules -- */
344 typedef struct keyword
345 {
346 	SYMB *Input ; /* -- List of input symbols -- */
347 	SYMB *Output ; /* -- List of output symbols, 1-1 with input -- */
348 	SYMB Type ; /* -- The classification of the rule -- */
349 	SYMB Weight ;
350 	int Length ; /* -- The number of symbols -- */
351 	int hits ; /* -- if collecting statistics -- */
352 	int best ; /* -- if collecting statistics -- */
353 	struct keyword *OutputNext ;
354 } KW ;
355 
356 
357 typedef struct lexeme
358 {
359 	int StartMorph ;
360 	int EndMorph ;
361 	DEF *DefList ;
362 	char Text[MAXTEXT] ;
363 } LEXEME ;
364 
365 /* 2006-11-02 */
366 typedef struct rule_param
367 {
368 	int num_nodes ;
369 	int rules_read ;
370 	int collect_statistics ;
371 	int total_key_hits ;
372 	int total_best_keys ;
373 	NODE **gamma_matrix;
374 	SYMB *rule_space ;
375 	KW ***output_link ;
376 	KW *key_space ;
377 } RULE_PARAM ;
378 
379 /* -- structure used to assemble composite output -- */
380 typedef struct seg
381 {
382 	SYMB sub_sym ; /* -- Used in forced standardization -- */
383 	int Start ; /* -- the start target position -- */
384 	int End ; /* -- the end position -- */
385 	int State ; /* -- row number of the tran table, used in clausetree -- */
386 	DS_Score_t Value ; /* -- the calculated value of the target segment -- */
387 	SYMB *Output ; /* -- the output copied from the rule -- */
388 	KW *Key ; /* -- the rule itself, used in clausetree construction -- */
389 } SEG ;
390 
391 /* -- storage structure for standardization candidates -- */
392 typedef struct stz
393 {
394     DS_Score_t score ; /* -- standardization score -- */
395     DS_Score_t raw_score ;
396     KW *build_key ; /* -- use to collect statistics -- */
397     DEF *definitions[MAXLEX] ; /* -- lexical or input definitions -- */
398     SYMB output[MAXLEX] ; /* -- output tokens -- */
399 } STZ ;
400 
401 /* 2006-11-02 */
402 typedef struct stz_param
403 {
404 	int stz_list_size ;
405 	int last_stz_output ;
406 	double stz_list_cutoff ;
407 	SEG *segs ;
408 	STZ **stz_array ;
409 } STZ_PARAM ;
410 
411 /* 2006-11-14 */
412 struct morph
413 {
414 	int Term ;
415 	int TextLen ;
416 	char Text[MAXTEXT] ;
417 	DEFDEF Sym ;
418 } ;
419 
420 typedef struct stand_param
421 {
422 	int cur_morph ;
423 	int base_morph ;
424 	int LexNum ;
425 	int analyze_complete ;
426 	int *have_ref_att ; /* build.c (transform_rows) */
427 	RULE_PARAM *rules ;
428 	/*-- <remarks> 2009-08-13 : support multiple lexicons </remarks> --*/
429 	ENTRY **lexicon ;
430 	ENTRY **address_lexicon ;
431 	ENTRY **poi_lexicon ;
432 	/*-- <revision date='2012-06-01'> Add gaz_lexicon to be triggered on __start_state__ = MACRO </revision> --*/
433 	ENTRY **gaz_lexicon ;
434 	/*-- <revision date='2012-07-22'> Keep track of start_state </revision> --*/
435 	int start_state ;
436 	ERR_PARAM *errors ;
437 	STZ_PARAM *stz_info ; /* structure created by analyze.c (create_segments) */
438 	DEF **default_def ;
439 	char **standard_fields ;
440 	struct morph morph_array[MAXMORPHS] ;
441 	SYMB best_output[MAXLEX] ;
442 	SYMB target[MAXLEX] ; /* -- target for Aho-Corasick -- */
443 	LEXEME lex_vector[MAXLEX] ;
444 	int cur_sym_sel[MAXLEX] ; /* -- currently selected symbol
445                                   for each lexeme -- */
446 	int orig_str_pos[MAXLEX] ; /* -- compression buffer -- */
447 	int def_cnt[MAXLEX] ; /* -- number of symbols for each lexeme -- */
448 	NODE registry[MAXLEX + 1] ; /* -- Aho-Corasick : offsets to output
449                                          links -- */
450 	DEF *best_defs[MAXLEX] ;
451 	DEF *def_array[MAXLEX][MAXDEF] ; /* -- the definitions for each
452                                                lexeme -- */
453 	SYMB comp_lex_sym[MAXLEX][MAXDEF] ; /* -- symbols for each lexeme -- */
454 } STAND_PARAM ;
455 
456 
457 /* ================ NON-STANDARDIZATION RECORDS ================== */
458 
459 #ifndef BUILD_API
460 
461 /* -- The attribute structure is used to coordinate the schema in the
462    reference data with the postal attributes identified by the standardizer
463    and which may be used in the user's addresses. -- */
464 typedef struct attribute
465 {
466 	SYMB symbol ;
467 	int comp_type ; /* -- The comparision type used in matching -- */
468 	int check_dir ; /* -- TRUE if a non-blank reference field is read -- */
469 	int num_redirects ;
470 	DS_Score_t m_weight ; /* -- matching weights -- */
471 	DS_Score_t u_weight ;
472 	DS_Field_t ru_fld_idx[MAX_ATT_FLDS] ; /* -- field index for unstandardized
473                                      ref table -- */
474 	DS_Field_t rs_fld_idx[MAX_ATT_FLDS] ; /* -- field index for standardized
475                                      ref table -- */
476 	DS_Field_t rs_off_fld_idx[MAX_ATT_FLDS] ; /* field index for official names in
477 									standardized ref table -- 2009-11-21 */
478 	SYMB redirects[MAX_REDIRECTS] ; /* -- reference fields to which this
479                                         attribute should be redirected -- */
480 } ATTRIBUTE ;
481 
482 /* --------------------------------------------------------------
483 This structure is used to store the information on each reference
484 record with which we attempt to match the user record
485 ---------------------------------------------------------------- */
486 typedef struct candidate
487 {
488 	int score_card ; /*2008-12-15*/
489 	DS_Entity_t record ; /* -- reference database record number -- */
490 	int stz ; /* -- The standardization being used -- */
491 	int edit_distance ; /* -- for use in matching -- */
492 	DS_Score_t score ; /* -- score calculated in ReadScoreStandardized -- */
493 	PAGC_POINT position ;
494 	int block_face ;
495 	char data[BETA_BUF_SIZE] ; /* -- data for display to user - added in
496                    betaref.c (ReadScoreStandardized) -- */
497 } CANDIDATE ; /* -- structure initialized in Index/CreateCandidate --*/
498 
499 typedef struct int_candidate
500 {
501 	DS_Entity_t record_A ;
502 	DS_Entity_t record_B ;
503 	int edit_distance_A ;
504 	int edit_distance_B ;
505 	DS_Score_t score ;
506 	PAGC_POINT position ;
507 	int stz_A ;
508 	int stz_B ;
509 	char cur_cand_data_A[BETA_BUF_SIZE] ;
510 	char cur_cand_data_B[BETA_BUF_SIZE] ;
511 } INT_CANDIDATE ;
512 #endif
513 
514 /* ================== global record =================== */
515 
516 typedef struct pagc_global
517 {
518 	int log_init ;
519 	RULE_PARAM *rules ;
520 	DEF **default_def ;
521 	/*-- <revision date='2009-08-13'> Support multiple lexicons </revision> --*/
522 	ENTRY **addr_lexicon ; /*-- 2006-11-20 --*/
523 	ENTRY **poi_lexicon ;
524 	/*-- <revision date='2012-07-16'> gaz_lexicon </revision> --*/
525 	ENTRY **gaz_lexicon ;
526 	DS_Handle _file_sys ;
527 	ERR_PARAM *process_errors ;
528 } PAGC_GLOBAL ;
529 
530 #ifndef BUILD_API
531 /* <revision date='2012-04-26'>Divert approx functions to TRIE_ARRAY -- moved approx definitions to approx.c </revision>*/
532 typedef void * RECOGNIZER_HANDLE ;
533 
534 /* ============================ main schema record ========================== */
535 
536 typedef struct schema
537 {
538 	DS_Score_t match_weight[MAXOUTSYM] ; /* match weight for each token employed in the schema */
539 	DS_Score_t unmatch_weight[MAXOUTSYM] ; /* the non-match weight for each */
540 	DS_Score_t max_score ; /* the maximum score for address matching */
541 	DS_Score_t score_range ; /* used in normalizing scores for addresses */
542 	DS_Score_t starting_cutoff ; /* initial cutoff for candidate elimination */
543 	DS_Score_t user_cut ; /* client-supplied cutoff */
544 	/*-- intersection scoring --*/
545 	DS_Score_t max_x_score ; /* the maximum for intersection matching */
546 	DS_Score_t max_m_weight ; /* used in intersection scoring for the cross street */
547 	DS_Score_t max_u_weight ; /* used in intersection scoring for the cross street */
548 	DS_Score_t x_m_weight ; /* used in intersection scoring for the cross street */
549 	DS_Score_t x_u_weight ; /* used in intersection scoring for the cross street */
550 	DS_Score_t x_range ; /* used for normalizing intersection scores */
551 	/*-- <revision date='2009-08-20'> Landmark scoring. </revision> --*/
552 	DS_Score_t max_p_score ; /* the maximum for landmark matching */
553 	DS_Score_t land_words_m_weight ; /* for landmark fields */
554 	DS_Score_t land_words_u_weight ; /* for landmark fields */
555 	DS_Score_t land_type_m_weight ; /* for landmark fields */
556 	DS_Score_t land_type_u_weight ; /* for landmark fields */
557 	DS_Score_t land_area_m_weight ; /* for landmark fields */
558 	DS_Score_t land_area_u_weight ; /* for landmark fields */
559 	DS_Score_t score_p_range ; /* landmark score normalization */
560 	DS_Metric_t lat_units ; /* size in meters of a degree of latitude */
561 	DS_Metric_t lon_units ; /* size in meters of a degree of longitude */
562 	DS_Coord_t MBR_max_X ; /* Minimal Bounding Rectangle maximum point X coordinate */
563 	DS_Coord_t MBR_max_Y ; /* MBR maximum point Y coordinate */
564 	DS_Coord_t MBR_min_X ; /* Minimum point X */
565 	DS_Coord_t MBR_min_Y ; /* Minimum point Y */
566 	int pagc_ver ; /*-- <revision date='2009-07-21'> Tracking version. </revision> --*/
567 	DS_Dim_t shp_typ ; /* Shape type in shapefile - point, arc */
568 	int both_sides ; /* do arcs have both sides, ie both left and right? -- used for SITE_INTERPOLATE */
569 	DS_Field_t from_cross_col ; /* the from cross street in the reference shapeset (for intersections) */
570 	DS_Field_t to_cross_col ; /* the to cross street for intersections */
571 	DS_Field_t alt_street_col ;  /* alternate name column in reference shapeset - for future use */
572 	/*-- landmark columns --*/
573 	int total_landmark_words ; /*-- <revision date='2009-07-26'/> --*/
574 	DS_Field_t landmark_alpha ;    /*-- <revision date='2009-07-19-21'> landmark columns </revision> --*/
575 	DS_Field_t landmark_beta ;
576 	DS_Field_t landmark_beta_official ;
577 	DS_Field_t landmark_type_alpha ; /*-- <revision date='2009-07-19'> new </revision> --*/
578 	DS_Field_t landmark_type_beta ;
579 	DS_Field_t subdistrict_alpha ; /*-- <revision date='2009-07-19'> new </revision> --*/
580 	DS_Field_t subdistrict_beta ;
581 	DS_Field_t occ_field1 ; /* -- if HAVE_OCCUPANCY -- */
582 	DS_Field_t occ_field2 ; /* -- if HAVE_OCCUPANCY -- */
583 	/*-- <revision date='2010-09-27'> Eliminate X_field and Y_field for HAVE_DBF_POSITION
584 		and use following: </revision> --*/
585 	DS_Geo_t typ_geo_cols ;
586 	DS_Field_t num_geo_cols ;
587 	DS_Field_t geo_cols[3] ;
588 	/*-- DS_Field_t X_field ; DS_Field_t Y_field ; --*/
589 	DS_Field_t num_official_fields ; /*  if HAVE_OFFICIAL_STREET, state the number of fields */
590 	DS_Field_t source_id_alpha ; /* if HAVE_SOURCE_ID, dbf field 2008-17-17 */
591 	DS_Field_t source_id_beta ; /* if HAVE_SOURCE_ID, standard field 2008-17-17 */
592 #ifdef THREE_SOURCE_IDS
593 	DS_Field_t source_id_alpha_b ; /* if HAVE_SOURCE_ID_B, dbf field 2008-17-17 */
594 	DS_Field_t source_id_beta_b ; /* if HAVE_SOURCE_ID_B, standard field 2008-17-17 */
595 	DS_Field_t source_id_alpha_c ; /* if HAVE_SOURCE_ID_C, dbf field 2008-17-17 */
596 	DS_Field_t source_id_beta_c ; /* if HAVE_SOURCE_ID_C, standard field 2008-17-17 */
597 #endif
598 	int num_atts ;  /* how many address attributes */
599 	int have_micros ;
600 	int have_macros ; /* does schema have place state zip attributes? */
601 	int have_postal ; /* does it have, specifically, a postal attribute ? */
602 	DS_Entity_t last_number ;  /* last record number for beta reference */
603 	int RedirectDir ;  /* determine if a redirect of directional attribute is required */
604 	int RedirectTyp ;  /* determine if a redirect of a street type attribute is required */
605 	int RedirectQual ; /* determine if a redirect of a qualifier attribute is required */
606 	DS_Field_t number_of_beta_fields ;
607 	int variants ; /* how many appends have been made */
608 	int beta_insert ; /* are we in read or write mode */
609 	int little_endian ; /* is it little or big? */
610 	int q_depth ; /* granularity for reverse geocoding */
611 	PAGC_FLAG_T flags ; /* bit flags indicating what features are enabled for this schema */
612 	ATTRIBUTE attributes[MAXOUTSYM] ; /* array for address attributes */
613 	ATTRIBUTE *last_att ;  /* address of the last attribute */
614 	ATTRIBUTE *attribute_index[MAXOUTSYM] ; /* an index into the attributes by token */
615 #ifdef USE_DITTO_FIELD
616 	/*-- <revision date='2008-05-08'> Allocated field to store last postal code read. </revision> --*/
617 	char *ditto_field ;
618 #endif
619 	char *idx_nam[ MAX_INDICES ] ; /* pointers to allocated index names */
620 	char *beta_table_name ;
621 	DS_Handle _beta_factory ;
622 	/*-- <revision date='2012-03-27'> Remove pool handles and replace with RECOGNIZER_HANDLES </revision> --*/
623 	RECOGNIZER_HANDLE street_postal_trie ; /*-- <revision date='2012-03-27'>change type</revision> --*/
624 	RECOGNIZER_HANDLE concat_trie ;
625 	RECOGNIZER_HANDLE landmark_name_trie ;
626 } SCHEMA ;
627 
628 /* ===================== build database control record ============= */
629 
630 typedef struct bdb_build_param
631 {
632 	ERR_PARAM *errors ;
633 	SCHEMA *schema ;
634 	DS_Handle _beta_attribute_interface ;
635 	DS_Handle _idx_db[MAX_INDICES] ;
636 	DS_Byte_t *shape_buf ;
637 } BDB_BUILD_PARAM ;
638 
639 
640 /* ============ structures for intersection search =========== */
641 
642 typedef struct x_cand
643 {
644 	DS_Entity_t beta_rec ;
645 	int reversed ;
646 	int strategy ;
647 	int stz_num ;
648 	int distance ;
649 	DS_Coord_t X ;
650 	DS_Coord_t Y ;
651 	struct x_cand *cluster ;
652 } X_CAND ;
653 
654 typedef struct pair_read
655 {
656 	DS_Entity_t record_1 ;
657 	DS_Entity_t record_2 ;
658 	struct pair_read *next ;
659 } PAIR_READ ;
660 
661 typedef struct box_cell
662 {
663 	X_CAND *splitter ;
664 	PAIR_READ *pair_list ;
665 	struct box_cell *cell_list[4] ;
666 } BOX_CELL ;
667 
668 
669 /* ============== structure for recording beta records read ======== */
670 
671 typedef struct record_read
672 {
673 	DS_Entity_t row_no ;
674 	int stz ;
675 	struct record_read * left ;
676 	struct record_read * right ;
677 } RECORD_READ ;
678 
679 typedef struct r_r_mgr
680 {
681 	int current_offset ;
682 	void *base ; /* 2010-06-24 : change to void * for flexibility */
683 	struct r_r_mgr *prev_block ;
684 	struct r_r_mgr *next_block ;
685 } R_R_MGR ;
686 
687 /* 2011-01-24 : keep schema linkages on hand until closure */
688 typedef struct schema_db_linkage
689 {
690 	SCHEMA * linked_schema ;
691 	DS_Handle _linked_beta ;
692 	DS_Handle _linked_idx[MAX_INDICES] ;
693 } SCHEMA_DB_LINKAGE ;
694 
695 /* ============ main matching context record ========== */
696 
697 typedef struct pagc_context
698 {
699 	SCHEMA *schema ;
700 	ERR_PARAM *errors ;
701 	int num_backlinks ; /* 2011-01-24 : keep schema linkages on hand until closure */
702 	SCHEMA_DB_LINKAGE * schema_backlinks[MAX_SCHEMAS] ; /* 2011-01-24 */
703 	DS_Handle _beta_attribute_interface ;
704 	DS_Handle _idx_db[MAX_INDICES] ; /* reader handles */
705 	int private_errs ;
706 	int numb_cands ;
707 	DS_Entity_t matched_ref_row ;
708 	DS_Entity_t matched_ref_row_B ;
709 	int strategy ;
710 	int next_free ;
711 	int query_begin ;
712 	int concat_reverse ; /* use for intersection concat keys */
713 	int collect_all ;
714 	INT_CANDIDATE ** int_cand_list ;
715 	char **street_words ;
716 	char **landmark_words ; /* 2009-09-17 */
717 	CANDIDATE **cand_list ;
718 /*   int numb_x_cands ;  2010-06-26, no longer needed */
719 /*   X_CAND *x_cand_list ;  2010-06-26, no longer needed */
720 	STAND_PARAM *standard_p ;
721 	STAND_PARAM *standard_p_B ;
722 	double seg_length[DS_MAX_VERTICES] ;
723 	DS_Score_t cand_list_cutoff ;
724 	DS_Score_t intersection_cutoff ;
725 	R_R_MGR *r_r ; /* -- allocated memory -- */
726 	R_R_MGR *pair_r_r ; /* 2010-06-26 new structure */
727 	R_R_MGR *box_r_r ; /* 2010-06-26 new structure */
728 	R_R_MGR *x_cand_r_r ; /* 2010-06-26 new structure */
729 	RECORD_READ **rec_hash_tab ; /* -- allocated memory -- */
730 	DS_Byte_t *shape_buf ;
731 	char transfer_buf[MAX_TRANSFER_BUF_SIZE] ;
732 /*   PAIR_READ *pair_buf ;  2010-06-26, no longer needed */
733 	BOX_CELL **overlap_buf ; /* -- allocated memory -- */
734 	BOX_CELL *box_root ;
735 /*   BOX_CELL *box_cell_array ;   2010-06-26, no longer needed */
736 /*   int num_box_cells ;  2010-06-26, no longer needed */
737 } PAGC_CONTEXT ;
738 
739 
740 /* =============== client interface record (not exposed) =========== */
741 
742 typedef struct client_handle
743 {
744 	int handle_check ;
745 	int num_contexts ;
746 	int num_schemas ;
747 	PAGC_GLOBAL *global_record ;
748 	FILE *misc_aux_stream ;
749 	STAND_PARAM *misc_stand ;
750 	PAGC_CONTEXT *context_records[MAX_CONTEXTS] ;
751 	SCHEMA *schema_records[MAX_SCHEMAS] ;
752 } CLIENT_HANDLE ;
753 
754 /* 2009-07-27 : structure for landmark scoring */
755 typedef struct cand_score_params
756 {
757 	int target_word_cnt ;
758 	int postal_idx ; /* which requester field has the postal */
759 	int city_idx ;
760 	int prov_idx ;
761 	int type_idx ;
762 	int subdistrict_idx ;
763 	int soundex_approx ;
764 	char **words_buf ;
765 	DS_Score_t *word_weights ; /* 2009-11-20 */
766 } CAND_SCORE_PARAMS ;
767 
768 /*-- <revision date='2012-08-20'> New definition </revision> --*/
769 typedef struct check_macro
770 {
771 	int in_line_string ;
772 	SYMB last_checked ;
773 	int __primary_in_reference__[4] ; // Each reference present marks this
774 	int __secondary_in_reference__[4] ;
775 	int action_alt_left ;
776 #ifdef WITH_ALT_LEFT_RIGHT
777 	int action_alt_right ;
778 #endif
779 	char __field_primary__[4][MAXSTRLEN] ;
780 	char __field_secondary__[4][MAXSTRLEN];
781 	char __field_alternate_primary__[4][MAXSTRLEN];
782 	char __field_alternate_secondary__[4][MAXSTRLEN];
783 	char __unstandard_left__[MAXSTRLEN] ;
784 	char __unstandard_right__[MAXSTRLEN] ;
785 	char __unstandard_alt_left__[MAXSTRLEN] ;
786 	char __unstandard_alt_right__[MAXSTRLEN] ;
787 	/*-- <remarks> These should be in the lexicon consulted for MACRO </remarks> --*/
788 	const char __dummies__[4][6] ;
789 } CHECK_MACRO ;
790 
791 /* ===================== prototypes for functions ================ */
792 
793 /* -- approx.c -- */
794 /*-- <revision date='2012-04-26'>Divert approx functions to TRIE_ARRAY</revision> --*/
795 RECOGNIZER_HANDLE _new_recognizer_(DS_Handle, DS_Index_Link , int, int, const char *, int, ERR_PARAM *);
796 void _free_recognizer_(RECOGNIZER_HANDLE);
797 int _insert_recognizer_key_(RECOGNIZER_HANDLE, char *, char *) ;
798 int _recognize_approx_(RECOGNIZER_HANDLE, PAGC_CONTEXT *, char *, char *, int, char **, int , int , CAND_SCORE_PARAMS *) ;
799 
800 #endif
801 
802 /* -- standard.c -- */
803 int standardize_field(STAND_PARAM *, char *, int) ;
804 void close_stand_context(STAND_PARAM *) ;
805 STAND_PARAM *init_stand_context(PAGC_GLOBAL *, ERR_PARAM *, int) ;
806 void close_stand_process(PAGC_GLOBAL *) ;
807 /* 2009-08-13 : support multiple lexicons */
808 int init_stand_process(PAGC_GLOBAL *, const char *, const char *, const char *, const char *) ;
809 
810 /* -- tokenize.c -- */
811 void initialize_morphs(STAND_PARAM *) ;
812 int setup_default_defs(PAGC_GLOBAL *) ;
813 void remove_default_defs(PAGC_GLOBAL *) ;
814 int process_input(STAND_PARAM *) ;
815 int new_morph(STAND_PARAM *, DEFDEF, const char *, int) ;
816 void set_term(STAND_PARAM *, int, const char *);
817 
818 int is_symb_on_list(SYMB, SYMB *) ;
819 int find_def_type(DEF *, SYMB *) ;
820 
821 /* -- export.c -- */
822 void stuff_fields(STAND_PARAM *) ;
823 void init_output_fields(STAND_PARAM *, int) ;
824 int sym_to_field(SYMB) ;
825 void send_fields_to_stream(char **, FILE *, int, int) ;
826 
827 /* -- analyze.c -- */
828 int install_def_block_table(ENTRY **, ERR_PARAM *) ;
829 STZ_PARAM *create_segments(ERR_PARAM *) ;
830 void destroy_segments(STZ_PARAM *) ;
831 int get_next_stz(STAND_PARAM *, int) ;
832 double get_stz_downgrade(STAND_PARAM *, int) ;
833 /*-- <revision date='2012-07-22'> Keep track of start_state </revision> --*/
834 int evaluator(STAND_PARAM *) ;
835 void output_raw_elements(STAND_PARAM *,ERR_PARAM *) ;
836 
837 /* -- gamma.c -- */
838 void refresh_transducer(NODE *, SYMB *, NODE **) ;
839 int is_input_symbol(SYMB) ;
840 int is_output_symbol(SYMB) ;
841 RULE_PARAM *create_rules(const char *, PAGC_GLOBAL *) ;
842 void destroy_rules(RULE_PARAM *) ;
843 #ifdef BUILD_API
844 int output_rule_statistics(RULE_PARAM *, ERR_PARAM *) ;
845 #else
846 int output_rule_statistics(RULE_PARAM *, ERR_PARAM *, char *, DS_Handle) ;
847 #endif
848 
849 /* -- lexicon.c -- */
850 ENTRY **create_lexicon(PAGC_GLOBAL *, const char *, const char *) ;
851 void destroy_lexicon(ENTRY **) ;
852 void destroy_def_list(DEF *) ;
853 ENTRY *find_entry(ENTRY **, char *) ;
854 DEF *create_def (SYMB, char *, int, int, ERR_PARAM *) ;
855 
856 /* -- err_param.c -- */
857 ERR_PARAM *init_errors(PAGC_GLOBAL *, const char *) ;
858 void close_errors(ERR_PARAM *) ;
859 int empty_errors(ERR_PARAM *, int *, char *) ;
860 void register_error(ERR_PARAM *) ;
861 void send_fields_to_error(ERR_PARAM *, char **) ;
862 
863 /* -- util.c -- */
864 
865 FILE *open_aux_file(PAGC_GLOBAL *, const char *) ;
866 
867 #ifndef BUILD_API
868 
869 /* -- candform.c -- */
870 int sads_format_standard_fields(STAND_PARAM *, int, char *) ;
871 void fetch_standard_headers(char *) ;
872 /* 2008-07-21 sads_format_candidate : add is_parity_mismatch argument,
873    add source_identifier argument */
874 #ifdef THREE_SOURCE_IDS
875 int sads_format_candidate(PAGC_CONTEXT *, DS_Entity_t, int, char *, int, int, int, int *, char *, char *, char *) ;
876 #else
877 int sads_format_candidate(PAGC_CONTEXT *, DS_Entity_t, int, char *, int, int, int, int *, char *) ;
878 #endif
879 void cand_header_list(PAGC_CONTEXT *, int, char * ) ;
880 /* 2008-07-28 ols_format_candidate : new routine */
881 int ols_format_candidate(PAGC_CONTEXT *, DS_Entity_t, int, char *, char *, int, int, int *) ;
882 
883 
884 /* -- init.c -- */
885 /* 2009-08-13 : support multiple lexicons */
886 PAGC_GLOBAL *init_global(int, const char *, const char *, const char *, const char *, const char *, const char *) ;
887 void close_global(PAGC_GLOBAL *) ;
888 SCHEMA *init_schema(ERR_PARAM *) ;
889 int close_schema(SCHEMA *, ERR_PARAM *) ; /* 2011-01-22 : return error code */
890 PAGC_CONTEXT *init_context(PAGC_GLOBAL *, SCHEMA *, ERR_PARAM *, int, const char *) ;
891 void close_context(PAGC_CONTEXT *) ;
892 
893 
894 /* -- build.c -- */
895 int build_beta(PAGC_GLOBAL *, SCHEMA *, ERR_PARAM *, DS_Handle, DS_Handle, BDB_BUILD_PARAM *, char *, char *, DS_Entity_t, DS_Entity_t) ;
896 
897 /* -- collect.c -- */
898 int match_address(PAGC_CONTEXT *, char *, char *, int, int) ;
899 int match_landmark(PAGC_CONTEXT *, char *, char *, char *, char *, int) ;
900 /* 2008-12-15 : add int arg to save_candidate */
901 int save_candidate(PAGC_CONTEXT *, DS_Entity_t, int, DS_Score_t, int, int,  char *) ;
902 int match_intersection( PAGC_CONTEXT *, char *, char *, char *,  char *, int) ;
903 int save_intersection_candidate(PAGC_CONTEXT *, DS_Entity_t, DS_Entity_t, int, int, int, int, DS_Score_t, DS_Coord_t, DS_Coord_t) ;
904 
905 
906 /* -- geocode.c -- */
907 DS_Entity_t locate_incident_arcs(PAGC_CONTEXT *, DS_Entity_t, int, int) ;
908 DS_Score_t score_arc_direction(PAGC_CONTEXT *, DS_Entity_t, PAGC_POINT *, DS_Angular_t) ;
909 int geocode_address_candidate(PAGC_CONTEXT *, PAGC_POINT *, int, int *, DS_Metric_t) ;
910 int geocode_intersection_candidate(PAGC_CONTEXT *, PAGC_POINT *, int) ;
911 int geocode_landmark_candidate(PAGC_CONTEXT *, PAGC_POINT *, int) ;
912 DS_Metric_t pyth_dist2(SCHEMA *, DS_Coord_t *, DS_Coord_t *, DS_Coord_t *, DS_Coord_t *) ;
913 DS_Metric_t degree_dist(DS_Metric_t, DS_Coord_t,  DS_Coord_t) ;
914 int collect_incident_arcs(PAGC_CONTEXT *, int, int, int) ;
915 
916 /* -- score.c -- */
917 int read_score_stand(PAGC_CONTEXT *, DS_Score_t *, char **, DS_Entity_t, int, int *) ;
918 int read_score_stand_land( PAGC_CONTEXT *, DS_Score_t *, char **, DS_Entity_t, int *, CAND_SCORE_PARAMS *) ;
919 int resolve_range_direction(int *, int *, int, int, int, int) ;
920 DS_Score_t interpolate_weight(DS_Score_t, DS_Score_t, DS_Score_t) ;
921 int match_number_interval_left_right(int, int, int, int, int, int) ;
922 DS_Score_t normalize_score(SCHEMA *, DS_Score_t) ;
923 DS_Score_t normalize_landmark_score(SCHEMA *, DS_Score_t) ;
924 DS_Score_t max_context_score(PAGC_CONTEXT *) ;
925 
926 /* -- make_sch.c -- */
927 void get_weight_pair(SCHEMA *, ATTRIBUTE *) ;
928 int build_ref_schema(SCHEMA * , DS_Handle, ERR_PARAM *, DS_Handle, const char *,  PAGC_FLAG_T) ;
929 ATTRIBUTE *get_att_by_symbol(SCHEMA *, SYMB) ;
930 int is_official(SCHEMA *, SYMB) ; /* 2009-11-23 : new function */
931 
932 /* -- restore.c -- */
933 int restore_build_state(PAGC_GLOBAL *, SCHEMA *, const char *, int) ;
934 int save_build_state(SCHEMA * , const char *, ERR_PARAM *, DS_Handle) ;
935 
936 /* -- shapeset.c -- */
937 int open_alpha_for_build(DS_Handle *, DS_Handle *, DS_Handle *,  DS_Handle , const char *, const char *, char **, ERR_PARAM *) ;
938 void close_alpha(DS_Handle *, DS_Handle *, DS_Handle *, ERR_PARAM *) ;
939 int open_positioning(SCHEMA *, DS_Handle *, char *, DS_Handle, ERR_PARAM *) ;
940 void set_feature_shape_type(SCHEMA *) ;
941 int set_matching_units(SCHEMA *) ;
942 void update_mbr(SCHEMA *, DS_Handle) ;
943 
944 /* -- index.c -- */
945 BDB_BUILD_PARAM * open_build_db(SCHEMA *, ERR_PARAM *) ;
946 void close_build_db(BDB_BUILD_PARAM *) ;
947 int open_context_db(PAGC_CONTEXT *, SCHEMA *, ERR_PARAM *) ;
948 void close_context_db(PAGC_CONTEXT *) ;
949 int open_schema_db(SCHEMA *, ERR_PARAM *, DS_Handle, const char *, int) ;
950 int close_schema_db(SCHEMA *, ERR_PARAM *) ;
951 int create_schema_indices(SCHEMA *, ERR_PARAM *) ;
952 int open_index(SCHEMA *, ERR_PARAM *, DS_Index_Link, int) ;
953 
954 /* -- indexput.c -- */
955 /*	<revision date='2012-03-27'>new args for insert_key and insert_concat_key */
956 int insert_key(BDB_BUILD_PARAM *, DS_Index_Link, char *, DS_Entity_t, char *) ;
957 int insert_concat_key(BDB_BUILD_PARAM *, DS_Index_Link,char *, DS_Entity_t, int, PAGC_POINT *, char *) ;
958 int insert_attribute_point(SCHEMA *, BDB_BUILD_PARAM *, DS_Handle, DS_Entity_t, DS_Entity_t, ERR_PARAM *) ;
959 int insert_shape(SCHEMA *, BDB_BUILD_PARAM *, DS_Handle, DS_Entity_t, DS_Entity_t, ERR_PARAM *err_p, PAGC_POINT *, PAGC_POINT * ) ;
960 
961 
962 /* -- indexget.c -- */
963 int fetch_shape(PAGC_CONTEXT *, DS_Entity_t, int *, DS_Coord_t **, DS_Coord_t **) ;
964 int register_candidate(PAGC_CONTEXT *, char **, DS_Index_Link, int, char *, int, CAND_SCORE_PARAMS *) ;
965 int read_arc_endpoints(PAGC_CONTEXT *, DS_Entity_t, PAGC_POINT *, PAGC_POINT *) ;
966 DS_Entity_t find_arcs_by_point(PAGC_CONTEXT *, DS_Entity_t, PAGC_POINT *, DS_Angular_t) ;
967 int print_beta_text(PAGC_CONTEXT *) ;
968 int print_index_text(PAGC_CONTEXT *, DS_Index_Link) ;
969 int print_shape_index(PAGC_CONTEXT *, DS_Index_Link) ;
970 int calc_landmark_word_weights(PAGC_CONTEXT *, int, int *, DS_Score_t *) ;
971 
972 /* -- alpharef.c -- */
973 int read_alpha_house(DS_Handle, DS_Entity_t, DS_Field_t, int) ;
974 int extract_house(const char *, int) ;
975 /* 2008-07-30 : add unstandard_mac_alternate arg and flag for alternate city names
976    2009-11-23 : add arrays for official name fields */
977 /*-- <revision date='2012-08-30'> Use check_macro </revision> --*/
978 int read_unstandardized(SCHEMA *, DS_Handle, DS_Entity_t, int *, int *, int *, char *, CHECK_MACRO* , char *, char **, DS_Field_t *, int *, ERR_PARAM *) ;
979 
980 /* -- makebeta.c -- */
981 int init_standardized_table(SCHEMA *, ERR_PARAM *) ;
982 int soundex_street_words(char *, char **) ;
983 /* 2008-08-01 : add stand_alt_macro flag for alternate city names */
984 /*-- <revision date='2012-08-30'> Use check_macro </revision> --*/
985 int write_standardized(SCHEMA *, BDB_BUILD_PARAM *, char **, char **, CHECK_MACRO *, int, int *, char *, char *, char *, DS_Entity_t, int) ;
986 void do_left_saves(char **, char *, char *, char *, int) ;
987 int index_cross_streets(SCHEMA *, BDB_BUILD_PARAM *, char **, char **, DS_Handle, DS_Entity_t, DS_Entity_t, STAND_PARAM *, PAGC_POINT *, PAGC_POINT *, ERR_PARAM *) ;
988 int write_occupancy_only(SCHEMA *, DS_Handle, char **, DS_Entity_t) ;
989 /* 2008-08-01 : new routine to standardize alternate city names */
990 #ifdef WITH_ALT_LEFT_RIGHT
991 int write_alt_macro_only(SCHEMA *, DS_Handle, char **, int, DS_Entity_t) ;
992 #else
993 int write_alt_macro_only(SCHEMA *, DS_Handle , char **, DS_Entity_t) ;
994 #endif
995 /* 2009-07-22 : new routines to standardize and write landmark names */
996 int write_landmark_name_only(SCHEMA *, BDB_BUILD_PARAM *, char **, char **, char **,  DS_Entity_t, ERR_PARAM *) ;
997 int tokenize_landmark_words(char *, char **) ;
998 
999 #endif
1000 
1001 /* ============================ MACROS ========================== */
1002 
1003 #define IS_BLANK( STR ) *STR == SENTINEL
1004 #define SPACE 0x20
1005 
1006 /* ================ ERROR MACROS ==================== */
1007 
1008 #define LOG_DS_ERR( INTF, WHERE ) \
1009 	ds_copy_error( INTF , WHERE -> error_buf ) ; \
1010 	register_error( WHERE )
1011 
1012 #define TERMINATE_INTERFACE( STATUS_REG_V , INTF , WHERE ) \
1013 	STATUS_REG_V = ds_terminate( INTF ) ; \
1014 	if ( STATUS_REG_V != DS_OK ) { \
1015 		LOG_DS_ERR( INTF, WHERE ) ; \
1016 	} \
1017 	ds_dispose_interface( INTF )
1018 
1019 #define LOG_MESS(STR,WHERE) \
1020    sprintf( WHERE -> error_buf , \
1021             STR ) ; \
1022    register_error( WHERE )
1023 
1024 #define LOG_MESS1( TEMP,INSERT,WHERE) \
1025    sprintf( WHERE -> error_buf , \
1026             TEMP, \
1027             INSERT ) ; \
1028    register_error( WHERE )
1029 
1030 #define LOG_MESS2( TEMP,INSERT1,INSERT2,WHERE ) \
1031    sprintf( WHERE -> error_buf , \
1032             TEMP, \
1033             INSERT1, \
1034             INSERT2 ) ; \
1035    register_error( WHERE )
1036 
1037 #define LOG_MESS3( TEMP,INSERT1,INSERT2,INSERT3,WHERE ) \
1038    sprintf( WHERE -> error_buf , \
1039             TEMP, \
1040             INSERT1, \
1041             INSERT2 , \
1042             INSERT3 ) ; \
1043    register_error( WHERE  )
1044 
1045 
1046 #define RET_ERR(STR,WHERE,RET) \
1047    LOG_MESS(STR,WHERE) ; \
1048    return RET
1049 
1050 #define RET_ERR1(TEMP,INSERT,WHERE,RET) \
1051    LOG_MESS1(TEMP,INSERT,WHERE) ; \
1052    return RET
1053 
1054 #define RET_ERR2(TEMP,INSERT1,INSERT2,WHERE,RET) \
1055    LOG_MESS2(TEMP,INSERT1,INSERT2,WHERE) ; \
1056    return RET
1057 
1058 #define RET_ERR3(TEMP,INSERT1,INSERT2,INSERT3,WHERE,RET) \
1059    LOG_MESS3(TEMP,INSERT1,INSERT2,INSERT3,WHERE) ; \
1060    return RET
1061 
1062 #define FATAL_EXIT exit(1)
1063 
1064 #define FATAL_ERR( MSG ) \
1065    fprintf( stderr , MSG ) ; \
1066    FATAL_EXIT
1067 
1068 #define CLIENT_ERR( PTR ) PTR -> next_fatal = FALSE
1069 
1070 #define MEM_ERR(PTR,WHERE,RET) \
1071    if ( PTR == NULL ) {\
1072       RET_ERR("Insufficient Memory",WHERE,RET) ; \
1073    }
1074 
1075 /* ----------- ALLOCATION MACROS ----------- */
1076 
1077 #define PAGC_STORE_STR(DEST,SRC,WHERE,RET_VAL) \
1078    DEST = (char * ) malloc( sizeof( char ) * ( strlen( SRC ) + 1 ) ) ; \
1079    MEM_ERR(DEST,WHERE,RET_VAL) ; \
1080    BLANK_STRING(DEST) ; \
1081    strcpy(DEST,SRC)
1082 
1083 
1084 #define PAGC_ALLOC_STRUC(LOC,TYP,WHERE,EXIT_TYPE) \
1085    LOC = ( TYP * ) malloc( sizeof( TYP ) ) ; \
1086    MEM_ERR(LOC,WHERE,EXIT_TYPE)
1087 
1088 #define PAGC_CALLOC_STRUC(LOC,TYP,NUM,WHERE,EXIT_TYPE) \
1089    LOC = ( TYP* ) calloc( (NUM) , sizeof( TYP ) ) ; \
1090    MEM_ERR(LOC,WHERE,EXIT_TYPE)
1091 
1092 #define PAGC_CALLOC_2D_ARRAY(PTR,TYP,ROWS,COLS,WHERE,EXIT_TYPE) \
1093    { \
1094       TYP **temp_ptr ; \
1095       int row_num ; \
1096       PAGC_CALLOC_STRUC(temp_ptr,TYP*,ROWS,WHERE,EXIT_TYPE) ; \
1097       for ( row_num = 0 ; row_num < ROWS ; row_num++ ) { \
1098         PAGC_CALLOC_STRUC(temp_ptr[row_num],TYP,COLS,WHERE,EXIT_TYPE) ; \
1099       } \
1100       PTR = temp_ptr ; \
1101    }
1102 
1103 #define FREE_AND_NULL(PTR) \
1104 	if (PTR !=NULL)\
1105 	{\
1106 		free (PTR) ; \
1107 		PTR = NULL ; \
1108 	}
1109 
1110 #define PAGC_DESTROY_2D_ARRAY(PTR,TYP,ROWS) \
1111 	{ \
1112 		int row_num ; \
1113 		TYP *row_val ; \
1114 		for (row_num = 0;row_num < ROWS;row_num++)\
1115 		{\
1116 			if ((row_val = PTR[row_num]) != NULL) \
1117 			{\
1118 				FREE_AND_NULL(row_val);\
1119 			}\
1120 		}\
1121 		FREE_AND_NULL(PTR) ; \
1122 	}
1123 
1124 
1125 
1126 
1127 /* ================ FILE OPEN MACROS ==================== */
1128 
1129 /* -- changed so not to conflict with Windows def --*/
1130 #define PAGC_FILE_OPEN(HANDLE,FNAME,MODE,WHERE,RET) \
1131    if ( ( HANDLE = fopen( FNAME , \
1132                           MODE ) ) == NULL ) { \
1133       RET_ERR1( "\nCan't open: %s\n" ,FNAME,WHERE,RET) ; \
1134    }
1135 
1136 #define OPEN_ALLOCATED_NAME(ALLOC_NAME,EXT,HANDLE,NAME,MODE,DS_SYS,WHERE,RET) \
1137    if ( ( ALLOC_NAME = ds_alloc_file_name(DS_SYS,NAME,EXT) ) == NULL ) { \
1138       return RET ; \
1139    } \
1140    PAGC_FILE_OPEN(HANDLE,ALLOC_NAME,MODE,WHERE,RET)
1141 
1142 
1143 
1144 #define SPACE_APPEND_WITH_LEN( D, S , L ) \
1145    char_append( " " , D , S , L )
1146 
1147 /* ================ SOUNDEX MACROS ==================== */
1148 
1149 #define MAKE_SOUNDEX_KEY(DEST,CNT,SW) \
1150   BLANK_STRING(DEST); \
1151   for ( CNT = 0 ; CNT < MAXPHRASE ; CNT++ ) { \
1152      if ( SW[ CNT ][ 0 ] == SENTINEL ) break ; \
1153      COMMA_APPEND_WITH_LEN( DEST , SW[ CNT ] , MAXSTRLEN ) ; \
1154   }
1155 
1156 /* construct concatenated keys for the concat index */
1157 #define MAKE_CONCAT_KEY(TARGET,SOURCE_A,SOURCE_B) \
1158    BLANK_STRING(TARGET) ; \
1159    strcpy( TARGET , SOURCE_A ) ; \
1160    COMMA_APPEND_WITH_LEN( TARGET , SOURCE_B , MAXSTRLEN )
1161 
1162 #define MAKE_CONCAT_SOUNDEX_KEY(SOURCE_A,SOURCE_B,DEST,HOLD,CNT,SW) \
1163    soundex_street_words( SOURCE_A, SW) ; \
1164    MAKE_SOUNDEX_KEY(DEST,CNT,SW) ; \
1165    soundex_street_words( SOURCE_B, SW) ; \
1166    MAKE_SOUNDEX_KEY(HOLD,CNT,SW) ; \
1167    COMMA_APPEND_WITH_LEN(DEST,HOLD,MAXSTRLEN)
1168 
1169 
1170 #define RNF_SENTINEL '_'
1171 /* 2011-01-14 : interpret initial space in a field to indicate a blank field */
1172 #define IS_ALPHA_STR_SENTINEL(V) ( ( *V == SENTINEL ) || ( *V == RNF_SENTINEL ) || ( *V == SPACE ) )
1173 
1174 /* --------------------------------------------------
1175 macros for converting and verifying pagc_client args
1176 -----------------------------------------------------*/
1177 
1178 #define HANDLE_CHECK 1014
1179 
1180 #define CONVERT_HANDLE( NATIVE_PTR , CLIENT_PTR ) \
1181    if ( CLIENT_PTR == NULL ) return FALSE ; \
1182    NATIVE_PTR = ( CLIENT_HANDLE * ) CLIENT_PTR ; \
1183    if ( NATIVE_PTR -> handle_check != HANDLE_CHECK ) return 0
1184 
1185 #define CHECK_BOUNDS( ARRAY_SIZE , ARRAY_IDX ) \
1186    if ( ( ARRAY_IDX > ARRAY_SIZE ) || (ARRAY_IDX < 1 ) ) { \
1187       CLIENT_ERR( pagc_p -> global_record -> process_errors ) ; \
1188       RET_ERR1( "No such entity such as %d" , \
1189                 ARRAY_IDX , \
1190                 pagc_p -> global_record -> process_errors , \
1191                 0 ) ; \
1192    }
1193 
1194 #define CHECK_BOUNDS_ABSOLUTE( ARRAY_SIZE , ARRAY_IDX ) \
1195    if ( ( ARRAY_IDX >= ARRAY_SIZE ) || (ARRAY_IDX < 0 ) ) { \
1196       CLIENT_ERR( pagc_p -> global_record -> process_errors ) ; \
1197       RET_ERR1( "No such entity such as %d" , \
1198                 ARRAY_IDX , \
1199                 pagc_p -> global_record -> process_errors , \
1200                 0 ) ; \
1201    }
1202 
1203 
1204 #define UPDATE_SCHEMA_BOUNDS( PTR ) \
1205    pagc_p -> schema_records[ pagc_p -> num_schemas ] = PTR ; \
1206    pagc_p -> num_schemas++ ; \
1207    return( pagc_p -> num_schemas )
1208 
1209 #define UPDATE_CONTEXT_BOUNDS( PTR ) \
1210    pagc_p -> context_records[ pagc_p -> num_contexts ] = PTR ; \
1211    pagc_p -> num_contexts++ ; \
1212    return( pagc_p -> num_contexts )
1213 
1214 #define SCHEMA_INDEX_TO_POINTER( IDX , PTR ) \
1215    PTR = pagc_p -> schema_records[ IDX - 1 ]
1216 
1217 #define CONTEXT_INDEX_TO_POINTER( IDX , PTR ) \
1218    PTR = pagc_p -> context_records[ IDX - 1 ]
1219 
1220 #define LIMIT_BOUNDS( CNT, MAX ) \
1221    if ( CNT == MAX ) { \
1222       RET_ERR1( "%d exceeds maximum allowed" , \
1223                 CNT , \
1224                 pagc_p -> global_record -> process_errors , \
1225                 0 ) ; \
1226    }
1227 
1228 
1229 
1230 
1231 /* ================== BETA READ MACROS ================ */
1232 
1233 #define READ_BETA_STRING(DEST,NUM) \
1234    DEST = ds_attribute_read_string_field( ctx_p -> _beta_attribute_interface , row_num , att -> rs_fld_idx[ NUM ] ) ; \
1235    if ( DEST == NULL ) return FALSE
1236 
1237 #define READ_BETA_INT(DEST,NUM) \
1238    DEST = ds_attribute_read_integer_field( ctx_p -> _beta_attribute_interface , row_num , att -> rs_fld_idx[ NUM ] ) ; \
1239    if ( DEST == ERR_FAIL ) return FALSE
1240 
1241 #define INT32_AS_BYTES( PTR_VAL ) \
1242 	* ( ( int32_t * ) ( PTR_VAL ) )
1243 
1244 #define INTEGER_AS_BYTES( PTR_VAL ) \
1245 	* ( ( int * ) ( PTR_VAL ) )
1246 
1247 #define DOUBLE_AS_BYTES( PTR_VAL ) \
1248 	*( ( double * ) ( PTR_VAL ) )
1249 
1250 
1251 /* ================= floating point comparison macros ======== */
1252 #define R_ERR .00001
1253 #define IS_DOUBLE_EQUAL( FX, FY ) ( ( fabs( FX - FY ) <= R_ERR )? TRUE : FALSE )
1254 #define IS_DOUBLE_NOT_EQUAL(FX,FY) ( ( fabs( FX - FY ) > R_ERR )? TRUE : FALSE )
1255 #define IS_DOUBLE_LESS(FX,FY) ( ( ( FX - FY ) < R_ERR )? TRUE : FALSE )
1256 #define IS_DOUBLE_GREATER(FX,FY) ( ( ( FX - FY ) > R_ERR )? TRUE : FALSE )
1257 #define IS_DOUBLE_LESS_OR_EQUAL(FX,FY) ( ( ( FX - FY ) <= R_ERR )? TRUE : FALSE )
1258 #define IS_DOUBLE_GREATER_OR_EQUAL(FX,FY) ( ( ( FX - FY ) >= R_ERR )? TRUE : FALSE )
1259 
1260 #endif
1261