Skip to content

Commit b65e2fc

Browse files
committed
New version of C code delivered by PG.
1 parent a25d88a commit b65e2fc

File tree

3 files changed

+132
-242
lines changed

3 files changed

+132
-242
lines changed

mapcoder/basics.h

100644100755
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define UWORD unsigned short int // 2-byte unsigned integer
22

3-
#define mapcode_cversion "1.3"
3+
#define mapcode_cversion "1.32"
44
#define MAXWIDE 10
55
#define BASEX 31
66
#define MAXFITLONG 6

mapcoder/mapcoder.c

100644100755
Lines changed: 112 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -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

10611066
void 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

Comments
 (0)