Skip to content

Commit ad3e165

Browse files
authored
Merge pull request #28 from mapcode-foundation/dev
Release 2.5.1
2 parents f32f39e + b506dd0 commit ad3e165

16 files changed

+249
-140
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
unittest/gmon.out
22
unittest/_*.txt
3+
unittest/*.gcov
4+
unittest/*.gcda
5+
unittest/*.gcno
6+
mapcodelib/*.gcov
7+
mapcodelib/*.gcda
8+
mapcodelib/*.gcno
39

410
# -----------------------------------------------------------------------------
511
# Compiled sources

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ decode Mapcodes.
6161

6262
This produces the following help text:
6363

64-
MAPCODE (version 2.4.1)
64+
MAPCODE (version 2.5.1)
6565
Copyright (C) 2014-2016 Stichting Mapcode Foundation
6666

6767
Usage:
@@ -137,6 +137,10 @@ footprint, for example for embedded applications.
137137

138138
## Release Notes
139139

140+
### 2.5.1
141+
142+
* Updated unit test to compile with plain C and added some test cases.
143+
140144
### 2.5.0
141145

142146
* Added support for getting territory names in English and local alphabets.

mapcodelib/internal_alphabet_recognizer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static const signed char ALPHABET_OF[] = {
288288
#define ROMAN_VERSION_MAX_CHAR 0x3129
289289
static const char *ROMAN_VERSION_OF[] = {
290290
/* 0000 */ "\0 !?#$%&'()*+,-./0123456789:;<=>?",
291-
/* 0040 */ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[?]^_`abcdefghijklmnopqrstuvwxyz{|}~?",
291+
/* 0040 */ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[?]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~?",
292292
/* 0080 */ NULL,
293293
/* 00c0 */ NULL,
294294
/* 0100 */ NULL,

mapcodelib/mapcoder.c

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ void _TestAssert(int iCondition, const char *cstrFile, int iLine) {
6868
#define REC_TYPE(m) ((TERRITORY_BOUNDARIES[m].flags >> 7) & 3)
6969
#define SMART_DIV(m) (TERRITORY_BOUNDARIES[m].flags >> 16)
7070
#define HEADER_LETTER(m) (ENCODE_CHARS[(TERRITORY_BOUNDARIES[m].flags >> 11) & 31])
71-
#define BOUNDARY_PTR(m) (&TERRITORY_BOUNDARIES[m])
7271

7372
#define TOKENSEP 0
7473
#define TOKENDOT 1
@@ -90,6 +89,12 @@ void _TestAssert(int iCondition, const char *cstrFile, int iLine) {
9089
#define EARTH_CIRCUMFERENCE_X (EARTH_RADIUS_X_METERS * 2 * MATH_PI)
9190
#define EARTH_CIRCUMFERENCE_Y (EARTH_RADIUS_Y_METERS * 2 * MATH_PI)
9291

92+
#define MICROLAT_TO_FRACTIONS_FACTOR ((double) MAX_PRECISION_FACTOR)
93+
#define MICROLON_TO_FRACTIONS_FACTOR (4.0 * MAX_PRECISION_FACTOR)
94+
95+
#define FLAG_UTF8_STRING 0 // interpret pointer a utf8 characters
96+
#define FLAG_UTF16_STRING 1 // interpret pointer a UWORD* to utf16 characters
97+
9398
// Meters per degree latitude is fixed. For longitude: use factor * cos(midpoint of two degree latitudes).
9499
static const double METERS_PER_DEGREE_LAT = EARTH_CIRCUMFERENCE_Y / 360.0;
95100
static const double METERS_PER_DEGREE_LON = EARTH_CIRCUMFERENCE_X / 360.0;
@@ -330,8 +335,7 @@ static TerritoryBoundary *getExtendedBoundaries(TerritoryBoundary *target, const
330335
//
331336
///////////////////////////////////////////////////////////////////////////////////////////////
332337

333-
#define MICROLAT_TO_FRACTIONS_FACTOR ((double)MAX_PRECISION_FACTOR)
334-
#define MICROLON_TO_FRACTIONS_FACTOR (4.0 * MAX_PRECISION_FACTOR)
338+
335339
typedef struct {
336340
// latitudes in "810 billionths", range [-729 E11 .. +720 E11), is well within (-2^47 ... +2^47)
337341
double fminy;
@@ -822,7 +826,7 @@ static const int NC[6] = {1, 31, 961, 29791, 923521, 28629151};
822826
// returns *result==0 in case of error
823827
static void encodeGrid(char *result, const EncodeRec *enc, const int m, const int extraDigits,
824828
const char headerLetter) {
825-
const TerritoryBoundary *b = BOUNDARY_PTR(m);
829+
const TerritoryBoundary *b = TERRITORY_BOUNDARY(m);
826830
const int orgcodex = coDex(m);
827831
int codexm;
828832
ASSERT(result);
@@ -999,7 +1003,7 @@ static void encodeNameless(char *result, const EncodeRec *enc, const enum Territ
9991003

10001004
SIDE = SMART_DIV(m);
10011005

1002-
b = BOUNDARY_PTR(m);
1006+
b = TERRITORY_BOUNDARY(m);
10031007
orgSIDE = SIDE;
10041008

10051009
{
@@ -1075,7 +1079,7 @@ static void encodeAutoHeader(char *result, const EncodeRec *enc, const int m, co
10751079

10761080
i = firstindex;
10771081
for (;;) {
1078-
b = BOUNDARY_PTR(i);
1082+
b = TERRITORY_BOUNDARY(i);
10791083
// determine how many cells
10801084
H = (b->maxy - b->miny + 89) / 90; // multiple of 10m
10811085
xdiv = xDivider4(b->miny, b->maxy);
@@ -1137,7 +1141,7 @@ static void encoderEngine(const enum Territory ccode, const EncodeRec *enc, cons
11371141
from = firstRec(ccode);
11381142
upto = lastRec(ccode);
11391143

1140-
if (!fitsInsideBoundaries(&enc->coord32, BOUNDARY_PTR(upto))) {
1144+
if (!fitsInsideBoundaries(&enc->coord32, TERRITORY_BOUNDARY(upto))) {
11411145
return;
11421146
}
11431147

@@ -1151,7 +1155,7 @@ static void encoderEngine(const enum Territory ccode, const EncodeRec *enc, cons
11511155

11521156
*result = 0;
11531157
for (i = from; i <= upto; i++) {
1154-
if (fitsInsideBoundaries(&enc->coord32, BOUNDARY_PTR(i))) {
1158+
if (fitsInsideBoundaries(&enc->coord32, TERRITORY_BOUNDARY(i))) {
11551159
if (IS_NAMELESS(i)) {
11561160
encodeNameless(result, enc, ccode, extraDigits, i);
11571161
} else if (REC_TYPE(i) > 1) {
@@ -1478,7 +1482,7 @@ static enum MapcodeError decodeGrid(DecodeRec *dec, const int m, const int hasHe
14781482

14791483

14801484
{
1481-
const TerritoryBoundary *b = BOUNDARY_PTR(m);
1485+
const TerritoryBoundary *b = TERRITORY_BOUNDARY(m);
14821486
const int ygridsize = (b->maxy - b->miny + divy - 1) / divy; // microdegrees per cell
14831487
const int xgridsize = (b->maxx - b->minx + divx - 1) / divx; // microdegrees per cell
14841488

@@ -1521,7 +1525,7 @@ static enum MapcodeError decodeGrid(DecodeRec *dec, const int m, const int hasHe
15211525

15221526
dec->coord32.lonMicroDeg = relx + (difx * dividerx);
15231527
dec->coord32.latMicroDeg = rely + (dify * dividery);
1524-
if (!fitsInsideBoundaries(&dec->coord32, BOUNDARY_PTR(m))) {
1528+
if (!fitsInsideBoundaries(&dec->coord32, TERRITORY_BOUNDARY(m))) {
15251529
return ERR_MAPCODE_UNDECODABLE; // type 2 "NLD Q000.000"
15261530
}
15271531

@@ -1637,7 +1641,7 @@ static enum MapcodeError decodeNameless(DecodeRec *dec, int m) {
16371641

16381642
xSIDE = SIDE = SMART_DIV(m);
16391643

1640-
b = BOUNDARY_PTR(m);
1644+
b = TERRITORY_BOUNDARY(m);
16411645

16421646
// decode
16431647
{
@@ -1692,7 +1696,7 @@ static enum MapcodeError decodeAutoHeader(DecodeRec *dec, int m) {
16921696
value *= (961 * 31);
16931697

16941698
for (; coDex(m) == codexm && REC_TYPE(m) > 1; m++) {
1695-
const TerritoryBoundary *b = BOUNDARY_PTR(m);
1699+
const TerritoryBoundary *b = TERRITORY_BOUNDARY(m);
16961700
// determine how many cells
16971701
int H = (b->maxy - b->miny + 89) / 90; // multiple of 10m
16981702
const int xdiv = xDivider4(b->miny, b->maxy);
@@ -2020,12 +2024,8 @@ static const int STATE_MACHINE[27][6] = {
20202024

20212025

20222026
// Returns 0 if ok, negative in case of error (where -999 represents "may BECOME a valid mapcode if more characters are added)
2023-
#define FLAG_UTF8_STRING 0 // interpret pointer a utf8 characters
2024-
#define FLAG_UTF16_STRING 1 // interpret pointer a UWORD* to utf16 characters
2025-
2026-
20272027
static enum MapcodeError parseMapcodeString(MapcodeElements *mapcodeElements, const char *string, int interpretAsUtf16,
2028-
enum Territory territory) {
2028+
enum Territory territory) {
20292029
const UWORD *utf16 = (const UWORD *) string;
20302030
int isAbjad = 0;
20312031
const unsigned char *utf8 = (unsigned char *) string;
@@ -2168,7 +2168,8 @@ static enum MapcodeError parseMapcodeString(MapcodeElements *mapcodeElements, co
21682168
}
21692169
if (isAbjad) {
21702170
convertFromAbjad(mapcodeElements->properMapcode);
2171-
mapcodeElements->indexOfDot = (int) (strchr(mapcodeElements->properMapcode, '.') - mapcodeElements->properMapcode);
2171+
mapcodeElements->indexOfDot = (int) (strchr(mapcodeElements->properMapcode, '.') -
2172+
mapcodeElements->properMapcode);
21722173
}
21732174
if (*mapcodeElements->territoryISO) {
21742175
mapcodeElements->territoryCode = getTerritoryCode(mapcodeElements->territoryISO, territory);
@@ -2270,7 +2271,7 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) {
22702271
err = decodeGrid(dec, i, 0);
22712272

22722273
// first of all, make sure the zone fits the country
2273-
restrictZoneTo(&dec->zone, &dec->zone, BOUNDARY_PTR(upto));
2274+
restrictZoneTo(&dec->zone, &dec->zone, TERRITORY_BOUNDARY(upto));
22742275

22752276
if ((err == ERR_OK) && IS_RESTRICTED(i)) {
22762277
int nrZoneOverlaps = 0;
@@ -2281,7 +2282,7 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) {
22812282
dec->coord32 = convertFractionsToCoord32(&dec->result);
22822283
for (j = i - 1; j >= from; j--) { // look in previous rects
22832284
if (!IS_RESTRICTED(j)) {
2284-
if (fitsInsideBoundaries(&dec->coord32, BOUNDARY_PTR(j))) {
2285+
if (fitsInsideBoundaries(&dec->coord32, TERRITORY_BOUNDARY(j))) {
22852286
nrZoneOverlaps = 1;
22862287
break;
22872288
}
@@ -2294,13 +2295,13 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) {
22942295
for (j = from; j < i; j++) { // try all smaller rectangles j
22952296
if (!IS_RESTRICTED(j)) {
22962297
MapcodeZone z;
2297-
if (restrictZoneTo(&z, &dec->zone, BOUNDARY_PTR(j))) {
2298+
if (restrictZoneTo(&z, &dec->zone, TERRITORY_BOUNDARY(j))) {
22982299
nrZoneOverlaps++;
22992300
if (nrZoneOverlaps == 1) {
23002301
// first fit! remember...
23012302
zoneCopyFrom(&zfound, &z);
23022303
ASSERT(j <= MAPCODE_BOUNDARY_MAX);
2303-
memcpy(&prevu, BOUNDARY_PTR(j), sizeof(TerritoryBoundary));
2304+
memcpy(&prevu, TERRITORY_BOUNDARY(j), sizeof(TerritoryBoundary));
23042305
} else { // nrZoneOverlaps >= 2
23052306
// more than one hit
23062307
break; // give up
@@ -2338,7 +2339,7 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) {
23382339
} // for
23392340

23402341
if (!err) {
2341-
restrictZoneTo(&dec->zone, &dec->zone, BOUNDARY_PTR(lastRec(ccode)));
2342+
restrictZoneTo(&dec->zone, &dec->zone, TERRITORY_BOUNDARY(lastRec(ccode)));
23422343

23432344
if (isEmpty(&dec->zone)) {
23442345
err = ERR_MAPCODE_UNDECODABLE; // type 0 "BRA xx.xx"
@@ -2794,7 +2795,7 @@ int multipleBordersNearby(double latDeg, double lonDeg, enum Territory territory
27942795
convertCoordsToMicrosAndFractions(&coord32, NULL, NULL, latDeg, lonDeg);
27952796
for (m = upto; m >= from; m--) {
27962797
if (!IS_RESTRICTED(m)) {
2797-
if (isNearBorderOf(&coord32, BOUNDARY_PTR(m))) {
2798+
if (isNearBorderOf(&coord32, TERRITORY_BOUNDARY(m))) {
27982799
nrFound++;
27992800
if (nrFound > 1) {
28002801
return 1;
@@ -2924,8 +2925,9 @@ decodeMapcodeToLatLonUtf8(double *latDeg, double *lonDeg, const char *mapcode, e
29242925

29252926

29262927
// PUBLIC - decode string into lat,lon; returns negative in case of error
2927-
enum MapcodeError decodeMapcodeToLatLonUtf16(double *latDeg, double *lonDeg, const UWORD *mapcode, enum Territory territory,
2928-
MapcodeElements *mapcodeElements) {
2928+
enum MapcodeError
2929+
decodeMapcodeToLatLonUtf16(double *latDeg, double *lonDeg, const UWORD *mapcode, enum Territory territory,
2930+
MapcodeElements *mapcodeElements) {
29292931
if ((latDeg == NULL) || (lonDeg == NULL) || (mapcode == NULL)) {
29302932
return ERR_BAD_ARGUMENTS;
29312933
} else {
@@ -3093,7 +3095,8 @@ int getFullTerritoryNameLocalInAlphabet(char *territoryName, enum Territory terr
30933095
*territoryName = 0;
30943096
return 0;
30953097
}
3096-
return getFullTerritoryName_internal(territoryName, territory, alternative, (int) alphabet, TERRITORY_LOCAL_NAME_UTF8);
3098+
return getFullTerritoryName_internal(territoryName, territory, alternative, (int) alphabet,
3099+
TERRITORY_LOCAL_NAME_UTF8);
30973100
}
30983101

30993102

mapcodelib/mapcoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ extern "C" {
2525
#include "mapcode_alphabets.h"
2626

2727

28-
#define MAPCODE_C_VERSION "2.5.0"
28+
#define MAPCODE_C_VERSION "2.5.1"
2929
#define UWORD unsigned short int // 2-byte unsigned integer.
3030
#define MAX_NR_OF_MAPCODE_RESULTS 22 // Max. number of results ever returned by encoder (e.g. for 26.904899, 95.138515).
3131
#define MAX_PROPER_MAPCODE_LEN 11 // Max. number of characters in a proper mapcode (including the dot, excl. precision extension).

unittest/README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Or, add `-fsanitize=address` to run the address sanitizer:
2828
cd ../mapcodelib
2929
gcc -O -c mapcoder.c
3030
cd ../unittest
31-
gcc -O unittest.c -lm -lpthread -fsanitize=address -o unittest
31+
gcc -O unittest.c -lm -lpthread -fsanitize=address -o unittest ../mapcodelib/mapcoder.o
3232

3333
And add the environment variable `ASAN_OPTIONS` to your shell:
3434

@@ -45,6 +45,22 @@ Compile and run as follows to use `gprof` to profile the library:
4545
cd ../unittest
4646
gcc -g -O0 unittest.c -lm -lpthread -o unittest ../mapcodelib/mapcoder.o -pg
4747

48+
## Using `gcov` to Show Test Coverage
49+
50+
Compile and run as follows to use `gcov` to show test coverage for the libray:
51+
52+
cd ../mapcodelib
53+
gcc -fprofile-arcs -ftest-coverage -O0 -c mapcoder.c
54+
cd ../unittest
55+
gcc -fprofile-arcs -ftest-coverage -O0 unittest.c -lm -lpthread -o unittest ../mapcodelib/mapcoder.o -pg
56+
./unittest
57+
cd ../mapcodelib
58+
gcov mapcoder.c
59+
cd ../unittest
60+
gcov unittest.c
61+
62+
The test coverage reports are the `*.gcov` text files.
63+
4864
## Using Microsoft Visual C++
4965

5066
If you use **Microsoft Visual C++**, you may need to add the following defines to your preprocessor

unittest/clean.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/bin/sh
2+
echo "Clean test files..."
23
if [ -f unittest.c ]
34
then
4-
rm -f _*.txt gmon.out
5+
rm -f _*.txt gmon.out *.gcda *.gcno *.gcov ../mapcodelib/*.gcda ../mapcodelib/*.gcno ../mapcodelib/*.gcov
56
fi

unittest/run_all.sh

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#!/bin/sh
2-
echo "Run all tests..."
3-
date
4-
echo ""
5-
./run_normal.sh
6-
./run_sanitizer.sh
7-
./run_gprof.sh
8-
./run_valgrind.sh
9-
./run_compare.sh
10-
echo ""
11-
echo "Done"
2+
OUT=_report.txt
3+
echo "Run all tests..." | tee $OUT
4+
date | tee -a $OUT
5+
echo "" | tee -a $OUT
6+
./run_normal.sh | tee -a $OUT
7+
./run_sanitizer.sh | tee -a $OUT
8+
./run_gcov.h | tee -a $OUT
9+
./run_gprof.sh | tee -a $OUT
10+
./run_valgrind.sh | tee -a $OUT
11+
./run_compare.sh | tee -a $OUT
12+
echo "" | tee -a $OUT
13+
echo "Done" | tee -a $OUT

0 commit comments

Comments
 (0)