@@ -1057,10 +1057,18 @@ int unpack_if_alldigits(char *input) // returns 1 if unpacked, 0 if left unchang
10571057}
10581058
10591059
1060+ #define VERSION_1_32 // 1.32 true recursive processing
1061+ #ifdef VERSION_1_32 // 1.32 true recursive processing
1062+ int result_override = -1 ;
1063+ #endif
1064+ const char * makeiso (int cc ,int longcode ); // 0=short / 1=XX-YYY for states, XXX for country / 2=shortest unique
10601065
10611066void addresult (char * resultbuffer , char * result , long x ,long y , int ccode )
10621067{
10631068 // add to global array (if any)
1069+ #ifdef VERSION_1_32 // 1.32 true recursive processing
1070+ if (result_override >=0 ) ccode = result_override ; // 1.32 true recursive processing
1071+ #endif
10641072 if (* result && global_results && nr_global_results >=0 && nr_global_results + 1 < (2 * MAXGLOBALRESULTS )) {
10651073 global_results [nr_global_results ]= global_buffer [nr_global_results ];
10661074 strcpy (global_results [nr_global_results ++ ],result );
@@ -1355,8 +1363,7 @@ int master_decode( long *nx,long *ny, // <- store result in nx,ny
13551363 long minx ,miny ,maxx ,maxy ;
13561364 if (isuseless ((j ))) continue ;
13571365 getboundaries ((j ),minx ,miny ,maxx ,maxy );
1358- int xdiv8 = x_divider (miny ,maxy )/4 ;
1359- if ( miny - 45 <=* ny && * ny < maxy + 45 && isInRange (* nx ,minx - xdiv8 ,maxx + xdiv8 ) ) { fitssomewhere = 1 ; break ; }
1366+ if ( miny <=* ny && * ny < maxy && isInRange (* nx ,minx ,maxx ) ) { fitssomewhere = 1 ; break ; }
13601367 }
13611368 if (!fitssomewhere ) {
13621369 err = -1234 ;
@@ -1601,6 +1608,11 @@ void master_encode( char *resultbuffer, int the_ctry, long x, long y, int forcec
16011608 return ;
16021609 if (forcecoder >=0 ) // we would have found it the normal way!
16031610 return ;
1611+
1612+ #ifdef VERSION_1_32 // 1.32 true recursive processing
1613+ result_override = the_ctry ; // 1.32 true recursive processing
1614+ #endif
1615+
16041616 the_ctry =
16051617 mIsUsaState (the_ctry ) ? ccode_usa :
16061618 mIsCanadaState (the_ctry ) ? ccode_can :
@@ -1610,8 +1622,17 @@ void master_encode( char *resultbuffer, int the_ctry, long x, long y, int forcec
16101622 mIsChinaState (the_ctry ) ? ccode_chn :
16111623 mIsRussiaState (the_ctry ) ? ccode_rus :
16121624 ccode_aus ;
1625+
1626+
1627+ #ifdef VERSION_1_32 // 1.32 true recursive processing
1628+ if (!stop_with_one_result )
1629+ master_encode ( resultbuffer , the_ctry , x ,y , forcecoder , 0 ,0 ,1 );
1630+ result_override = -1 ;
1631+ return ; /**/
1632+ #else
16131633 setup_country ( the_ctry );
16141634 i = iso_start - 1 ; continue ;
1635+ #endif
16151636 }
16161637
16171638 if ( i > iso_end )
@@ -2163,84 +2184,77 @@ const UWORD* encode_utf16(const char *mapcode,int language) // convert mapcode t
21632184#define TOKENDOT 1
21642185#define TOKENCHR 2
21652186#define TOKENZERO 3
2187+ #define TOKENHYPH 4
21662188#define ERR -1
2189+ #define Prt -9 // partial
21672190#define GO 99
21682191
2169- int lookslike_mapcode (const char * s ) // return -999 if partial, 0 if ok, negative if not
2170- {
2171- static signed char statemachine [12 ][4 ] = {
2172- // SEP DOT CHR ZER
2173- { ERR ,ERR , 1 ,ERR }, // 0 start
2174- { ERR , 7 , 2 ,ERR }, // 1 L
2175- { 0 , 7 , 3 ,ERR }, // 2 LL
2176- { 0 , 7 , 4 ,ERR }, // 3 LLL
2177- { ERR , 7 , 5 ,ERR }, // 4 LLLL
2178- { ERR , 7 , 6 ,ERR }, // 5 LLLLL
2179- { ERR , 7 ,ERR ,ERR }, // 6 LLLLLL
2180- { ERR ,ERR , 8 ,ERR }, // 7 prefix. // decision: do NOT allow immediate decoding when the dot is typed
2181- { ERR ,ERR , 9 , GO }, // 8 prefix.L
2182- { ERR ,ERR ,10 , GO }, // 9 prefix.LL
2183- { ERR ,ERR ,11 , GO }, //10 prefix.LLL
2184- { ERR ,ERR ,ERR , GO } //11 prefix.LLLL
2185- };
2192+ static signed char fullmc_statemachine [23 ][5 ] = {
2193+ // WHI DOT DET ZER HYP
2194+ /* 0 start */ { 0 ,ERR , 1 ,ERR ,ERR }, // looking for very first detter
2195+ /* 1 gotL */ { ERR ,ERR , 2 ,ERR ,ERR }, // got one detter, MUST get another one
2196+ /* 2 gotLL */ { 18 , 6 , 3 ,ERR ,14 }, // GOT2: white: got territory + start prefix | dot: 2.X mapcode | det:3letter | hyphen: 2-state
2197+ /* 3 gotLLL */ { 18 , 6 , 4 ,ERR ,14 }, // white: got territory + start prefix | dot: 3.X mapcode | det:4letterprefix | hyphen: 3-state
2198+ /* 4 gotprefix4 */ { ERR , 6 , 5 ,ERR ,ERR }, // dot: 4.X mapcode | det: got 5th prefix letter
2199+ /* 5 gotprefix5 */ { ERR , 6 ,ERR ,ERR ,ERR }, // got 5char so MUST get dot!
2200+ /* 6 prefix. */ { ERR ,ERR , 7 ,Prt ,ERR }, // MUST get first letter after dot
2201+ /* 7 prefix.L */ { ERR ,ERR , 8 ,Prt ,ERR }, // MUST get second letter after dot
2202+ /* 8 prefix.LL */ { 22 ,ERR , 9 , GO ,11 }, // get 3d letter after dot | X.2- | X.2 done!
2203+ /* 9 prefix.LLL */ { 22 ,ERR ,10 , GO ,11 }, // get 4th letter after dot | X.3- | X.3 done!
2204+ /*10 prefix.LLLL */ { 22 ,ERR ,ERR , GO ,11 }, // X.4- | x.4 done!
2205+
2206+ /*11 mc- */ { ERR ,ERR ,12 ,Prt ,ERR }, // MUST get first precision letter
2207+ /*12 mc-L */ { 22 ,ERR ,13 , GO ,ERR }, // Get 2nd precision letter | done X.Y-1
2208+ /*13 mc-LL */ { 22 ,ERR ,ERR , GO ,ERR }, // done X.Y-2 (*or skip whitespace*)
2209+
2210+ /*14 ctry- */ { ERR ,ERR ,15 ,ERR ,ERR }, // MUST get first state letter
2211+ /*15 ctry-L */ { ERR ,ERR ,16 ,ERR ,ERR }, // MUST get 2nd state letter
2212+ /*16 ctry-LL */ { 18 ,ERR ,17 ,ERR ,ERR }, // white: got CCC-SS and get prefix | got 3d letter
2213+ /*17 ctry-LLL */ { 18 ,ERR ,ERR ,ERR ,ERR }, // got CCC-SSS so MUST get whitespace and then get prefix
2214+
2215+ /*18 startprefix */ { 18 ,ERR ,19 ,ERR ,ERR }, // skip more whitespace, MUST get 1st prefix letter
2216+ /*19 gotprefix1 */ { ERR ,ERR ,20 ,ERR ,ERR }, // MUST get second prefix letter
2217+ /*20 gotprefix2 */ { ERR , 6 ,21 ,ERR ,ERR }, // dot: 2.X mapcode | det: 3d perfix letter
2218+ /*21 gotprefix3 */ { ERR , 6 , 4 ,ERR ,ERR }, // dot: 3.x mapcode | det: got 4th prefix letter
2219+
2220+ /*22 whitespace */ { 22 ,ERR ,ERR , GO ,ERR } // whitespace until end of string
21862221
2187- int state = 0 ;
2188- int gothyphen = 0 ; // 1 hyphen at most
2189- int gotsep = 0 ; // 2 seps in toal at most (hyphen+space or space+space)
2190- int prefix = 0 ;
2191- int postfix = 0 ;
2222+ };
21922223
2193- for (;;)
2224+ // pass fullcode=1 to recognise territory and mapcode, pass fullcode=0 to only recognise proper mapcode (without optional territory)
2225+ // returns 0 if ok, negative in case of error (where -999 represents "may BECOME a valid mapcode if more characters are added)
2226+ int lookslikemapcode (const char * s ,int fullcode )
21942227 {
2195- // recognise token
2196- int token ,newstate ;
2197- if ( (* s >='a' && * s <='z' ) || (* s >='A' && * s <='Z' ) || (* s >='0' && * s <='9' )) // letter or digit
2198- {
2199- token = TOKENCHR ;
2200- if (state >=7 ) // got dot!
2201- postfix ++ ;
2202- else
2203- {
2204- if (prefix == 0 ) if (* s == 'a' || * s == 'A' ) prefix -- ; // dont count A as first letter
2205- prefix ++ ;
2206- }
2207- }
2208- else if (* s == ' ' )
2209- {
2210- prefix = 0 ; // start again with prefixing
2211- token = TOKENSEP ; if (gotsep ++ >=2 ) return -5 ; // err if already got 2 separators
2212- }
2213- else if (* s == '-' )
2214- {
2215- prefix = 0 ; // start again with prefixing
2216- token = TOKENSEP ; if (gothyphen ++ > 0 ) return -3 ; if (gotsep ++ > 0 ) return -5 ; // err if already got hyphen or space
2217- }
2218- else if (* s == '.' )
2219- {
2220- token = TOKENDOT ;
2221- }
2222- else if (* s == 0 )
2223- {
2224- token = TOKENZERO ;
2225- }
2226- else
2227- {
2228- return -4 ; // invalid char
2229- }
2230-
2231- newstate = statemachine [state ][token ];
2232- if (newstate == ERR ) return -100 - state ;
2233- if (newstate == GO )
2234- {
2235- if (prefix > 5 ) return -7 ; // prefix too long
2236- if (prefix < 2 ) return -999 ;
2237- if (postfix < 2 ) return -999 ;
2238- if (prefix == 5 && postfix < 4 ) return -999 ;
2239- return 0 ;
2240- }
2241- state = newstate ;
2242- s ++ ;
2228+ int nondigits = 0 ;
2229+ int state = (fullcode ? 0 : 18 ); // initial state
2230+ for (;;s ++ ) {
2231+ int newstate ,token ;
2232+ // recognise token
2233+ if (* s >='0' && * s <='9' ) token = TOKENCHR ;
2234+ else if ((* s >='a' && * s <='z' ) || (* s >='A' && * s <='Z' ))
2235+ { token = TOKENCHR ; if (state != 11 && state != 12 ) nondigits ++ ; }
2236+ else if (* s == '.' ) token = TOKENDOT ;
2237+ else if (* s == '-' ) token = TOKENHYPH ;
2238+ else if (* s == 0 ) token = TOKENZERO ;
2239+ else if (* s == ' ' || * s == '\t' ) token = TOKENSEP ;
2240+ else return -4 ; // invalid character
2241+ newstate = fullmc_statemachine [state ][token ];
2242+ if (newstate == ERR )
2243+ return - (1000 + 10 * state + token );
2244+ if (newstate == GO )
2245+ return (nondigits > 0 ? 0 : -5 );
2246+ if (newstate == Prt )
2247+ return -999 ;
2248+ state = newstate ;
2249+ if (state == 18 )
2250+ nondigits = 0 ;
2251+ }
22432252 }
2253+
2254+ int lookslike_mapcode (const char * s ) // return -999 if partial, 0 if ok, negative if not
2255+ {
2256+ // old-style recognizer, does not suport territory context
2257+ return lookslikemapcode (s ,0 );
22442258}
22452259
22462260
@@ -2469,7 +2483,7 @@ int text2tc(const char *string,int optional_tc) // optional_tc: pass 0 or negati
24692483
24702484// pass point to an array of pointers (at least 64), will be made to point to result strings...
24712485// returns nr of results;
2472- int coord2mc ( char * * v , double lat , double lon , int tc )
2486+ int coord2mc_full ( char * * v , double lat , double lon , int tc , int stop_with_one_result ) // 1.31 allow to stop after one result
24732487{
24742488 int ccode = tc - 1 ;
24752489 if (tc == 0 ) ccode = 0 ;
@@ -2483,12 +2497,13 @@ int coord2mc( char **v, double lat, double lon, int tc )
24832497 {
24842498 int i ;
24852499 for (i = 0 ;i < MAX_CCODE ;i ++ ) {
2486- master_encode (NULL ,i ,(long )lon ,(long )lat ,-1 ,0 ,0 ,0 ); // 1.29 - also add parents recursively
2500+ master_encode (NULL ,i ,(long )lon ,(long )lat ,-1 ,stop_with_one_result ,0 ,0 ); // 1.29 - also add parents recursively
2501+ if (stop_with_one_result && nr_global_results > 0 ) break ;
24872502 }
24882503 }
24892504 else
24902505 {
2491- master_encode (NULL ,ccode ,(long )lon ,(long )lat ,-1 ,0 ,0 ,0 ); // 1.29 - also add parents recursively
2506+ master_encode (NULL ,ccode ,(long )lon ,(long )lat ,-1 ,stop_with_one_result ,0 ,0 ); // 1.29 - also add parents recursively
24922507 }
24932508 global_results = NULL ;
24942509 return nr_global_results /2 ;
@@ -2526,5 +2541,26 @@ const UWORD* encode_to_alphabet(const char *mapcode,int alphabet) // 0=roman, 2=
25262541
25272542#endif
25282543
2544+ int coord2mc ( char * * v , double lat , double lon , int tc )
2545+ {
2546+ return coord2mc_full (v ,lat ,lon ,tc ,0 );
2547+ }
2548+
2549+ int coord2mc1 ( char * result , double lat , double lon , int tc )
2550+ {
2551+ char * v [2 ];
2552+ int ret = coord2mc_full (v ,lat ,lon ,tc ,1 );
2553+ * result = 0 ;
2554+ if (ret > 0 ) {
2555+ if (strcmp (v [1 ],"AAA" )!= 0 ) {
2556+ strcpy (result ,v [1 ]);
2557+ strcat (result ," " );
2558+ }
2559+ strcat (result ,v [0 ]);
2560+ }
2561+ return ret ;
2562+ }
2563+
2564+
25292565#endif // RELEASENEAT
25302566
0 commit comments