diff --git a/.gitignore b/.gitignore index 4d67d74..0f8d2b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,11 @@ unittest/gmon.out unittest/_*.txt +unittest/*.gcov +unittest/*.gcda +unittest/*.gcno +mapcodelib/*.gcov +mapcodelib/*.gcda +mapcodelib/*.gcno # ----------------------------------------------------------------------------- # Compiled sources diff --git a/README.md b/README.md index bbacf46..678314f 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ decode Mapcodes. This produces the following help text: - MAPCODE (version 2.4.1) + MAPCODE (version 2.5.1) Copyright (C) 2014-2016 Stichting Mapcode Foundation Usage: @@ -137,6 +137,10 @@ footprint, for example for embedded applications. ## Release Notes +### 2.5.1 + +* Updated unit test to compile with plain C and added some test cases. + ### 2.5.0 * Added support for getting territory names in English and local alphabets. diff --git a/mapcodelib/internal_alphabet_recognizer.h b/mapcodelib/internal_alphabet_recognizer.h index 2af0caa..91c1b00 100644 --- a/mapcodelib/internal_alphabet_recognizer.h +++ b/mapcodelib/internal_alphabet_recognizer.h @@ -288,7 +288,7 @@ static const signed char ALPHABET_OF[] = { #define ROMAN_VERSION_MAX_CHAR 0x3129 static const char *ROMAN_VERSION_OF[] = { /* 0000 */ "\0 !?#$%&'()*+,-./0123456789:;<=>?", - /* 0040 */ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[?]^_`abcdefghijklmnopqrstuvwxyz{|}~?", + /* 0040 */ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[?]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~?", /* 0080 */ NULL, /* 00c0 */ NULL, /* 0100 */ NULL, diff --git a/mapcodelib/mapcoder.c b/mapcodelib/mapcoder.c index 90d31fd..39acb87 100644 --- a/mapcodelib/mapcoder.c +++ b/mapcodelib/mapcoder.c @@ -68,7 +68,6 @@ void _TestAssert(int iCondition, const char *cstrFile, int iLine) { #define REC_TYPE(m) ((TERRITORY_BOUNDARIES[m].flags >> 7) & 3) #define SMART_DIV(m) (TERRITORY_BOUNDARIES[m].flags >> 16) #define HEADER_LETTER(m) (ENCODE_CHARS[(TERRITORY_BOUNDARIES[m].flags >> 11) & 31]) -#define BOUNDARY_PTR(m) (&TERRITORY_BOUNDARIES[m]) #define TOKENSEP 0 #define TOKENDOT 1 @@ -90,6 +89,12 @@ void _TestAssert(int iCondition, const char *cstrFile, int iLine) { #define EARTH_CIRCUMFERENCE_X (EARTH_RADIUS_X_METERS * 2 * MATH_PI) #define EARTH_CIRCUMFERENCE_Y (EARTH_RADIUS_Y_METERS * 2 * MATH_PI) +#define MICROLAT_TO_FRACTIONS_FACTOR ((double) MAX_PRECISION_FACTOR) +#define MICROLON_TO_FRACTIONS_FACTOR (4.0 * MAX_PRECISION_FACTOR) + +#define FLAG_UTF8_STRING 0 // interpret pointer a utf8 characters +#define FLAG_UTF16_STRING 1 // interpret pointer a UWORD* to utf16 characters + // Meters per degree latitude is fixed. For longitude: use factor * cos(midpoint of two degree latitudes). static const double METERS_PER_DEGREE_LAT = EARTH_CIRCUMFERENCE_Y / 360.0; static const double METERS_PER_DEGREE_LON = EARTH_CIRCUMFERENCE_X / 360.0; @@ -330,8 +335,7 @@ static TerritoryBoundary *getExtendedBoundaries(TerritoryBoundary *target, const // /////////////////////////////////////////////////////////////////////////////////////////////// -#define MICROLAT_TO_FRACTIONS_FACTOR ((double)MAX_PRECISION_FACTOR) -#define MICROLON_TO_FRACTIONS_FACTOR (4.0 * MAX_PRECISION_FACTOR) + typedef struct { // latitudes in "810 billionths", range [-729 E11 .. +720 E11), is well within (-2^47 ... +2^47) double fminy; @@ -822,7 +826,7 @@ static const int NC[6] = {1, 31, 961, 29791, 923521, 28629151}; // returns *result==0 in case of error static void encodeGrid(char *result, const EncodeRec *enc, const int m, const int extraDigits, const char headerLetter) { - const TerritoryBoundary *b = BOUNDARY_PTR(m); + const TerritoryBoundary *b = TERRITORY_BOUNDARY(m); const int orgcodex = coDex(m); int codexm; ASSERT(result); @@ -999,7 +1003,7 @@ static void encodeNameless(char *result, const EncodeRec *enc, const enum Territ SIDE = SMART_DIV(m); - b = BOUNDARY_PTR(m); + b = TERRITORY_BOUNDARY(m); orgSIDE = SIDE; { @@ -1075,7 +1079,7 @@ static void encodeAutoHeader(char *result, const EncodeRec *enc, const int m, co i = firstindex; for (;;) { - b = BOUNDARY_PTR(i); + b = TERRITORY_BOUNDARY(i); // determine how many cells H = (b->maxy - b->miny + 89) / 90; // multiple of 10m xdiv = xDivider4(b->miny, b->maxy); @@ -1137,7 +1141,7 @@ static void encoderEngine(const enum Territory ccode, const EncodeRec *enc, cons from = firstRec(ccode); upto = lastRec(ccode); - if (!fitsInsideBoundaries(&enc->coord32, BOUNDARY_PTR(upto))) { + if (!fitsInsideBoundaries(&enc->coord32, TERRITORY_BOUNDARY(upto))) { return; } @@ -1151,7 +1155,7 @@ static void encoderEngine(const enum Territory ccode, const EncodeRec *enc, cons *result = 0; for (i = from; i <= upto; i++) { - if (fitsInsideBoundaries(&enc->coord32, BOUNDARY_PTR(i))) { + if (fitsInsideBoundaries(&enc->coord32, TERRITORY_BOUNDARY(i))) { if (IS_NAMELESS(i)) { encodeNameless(result, enc, ccode, extraDigits, i); } else if (REC_TYPE(i) > 1) { @@ -1478,7 +1482,7 @@ static enum MapcodeError decodeGrid(DecodeRec *dec, const int m, const int hasHe { - const TerritoryBoundary *b = BOUNDARY_PTR(m); + const TerritoryBoundary *b = TERRITORY_BOUNDARY(m); const int ygridsize = (b->maxy - b->miny + divy - 1) / divy; // microdegrees per cell const int xgridsize = (b->maxx - b->minx + divx - 1) / divx; // microdegrees per cell @@ -1521,7 +1525,7 @@ static enum MapcodeError decodeGrid(DecodeRec *dec, const int m, const int hasHe dec->coord32.lonMicroDeg = relx + (difx * dividerx); dec->coord32.latMicroDeg = rely + (dify * dividery); - if (!fitsInsideBoundaries(&dec->coord32, BOUNDARY_PTR(m))) { + if (!fitsInsideBoundaries(&dec->coord32, TERRITORY_BOUNDARY(m))) { return ERR_MAPCODE_UNDECODABLE; // type 2 "NLD Q000.000" } @@ -1637,7 +1641,7 @@ static enum MapcodeError decodeNameless(DecodeRec *dec, int m) { xSIDE = SIDE = SMART_DIV(m); - b = BOUNDARY_PTR(m); + b = TERRITORY_BOUNDARY(m); // decode { @@ -1692,7 +1696,7 @@ static enum MapcodeError decodeAutoHeader(DecodeRec *dec, int m) { value *= (961 * 31); for (; coDex(m) == codexm && REC_TYPE(m) > 1; m++) { - const TerritoryBoundary *b = BOUNDARY_PTR(m); + const TerritoryBoundary *b = TERRITORY_BOUNDARY(m); // determine how many cells int H = (b->maxy - b->miny + 89) / 90; // multiple of 10m const int xdiv = xDivider4(b->miny, b->maxy); @@ -2020,12 +2024,8 @@ static const int STATE_MACHINE[27][6] = { // Returns 0 if ok, negative in case of error (where -999 represents "may BECOME a valid mapcode if more characters are added) -#define FLAG_UTF8_STRING 0 // interpret pointer a utf8 characters -#define FLAG_UTF16_STRING 1 // interpret pointer a UWORD* to utf16 characters - - static enum MapcodeError parseMapcodeString(MapcodeElements *mapcodeElements, const char *string, int interpretAsUtf16, - enum Territory territory) { + enum Territory territory) { const UWORD *utf16 = (const UWORD *) string; int isAbjad = 0; const unsigned char *utf8 = (unsigned char *) string; @@ -2168,7 +2168,8 @@ static enum MapcodeError parseMapcodeString(MapcodeElements *mapcodeElements, co } if (isAbjad) { convertFromAbjad(mapcodeElements->properMapcode); - mapcodeElements->indexOfDot = (int) (strchr(mapcodeElements->properMapcode, '.') - mapcodeElements->properMapcode); + mapcodeElements->indexOfDot = (int) (strchr(mapcodeElements->properMapcode, '.') - + mapcodeElements->properMapcode); } if (*mapcodeElements->territoryISO) { mapcodeElements->territoryCode = getTerritoryCode(mapcodeElements->territoryISO, territory); @@ -2270,7 +2271,7 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) { err = decodeGrid(dec, i, 0); // first of all, make sure the zone fits the country - restrictZoneTo(&dec->zone, &dec->zone, BOUNDARY_PTR(upto)); + restrictZoneTo(&dec->zone, &dec->zone, TERRITORY_BOUNDARY(upto)); if ((err == ERR_OK) && IS_RESTRICTED(i)) { int nrZoneOverlaps = 0; @@ -2281,7 +2282,7 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) { dec->coord32 = convertFractionsToCoord32(&dec->result); for (j = i - 1; j >= from; j--) { // look in previous rects if (!IS_RESTRICTED(j)) { - if (fitsInsideBoundaries(&dec->coord32, BOUNDARY_PTR(j))) { + if (fitsInsideBoundaries(&dec->coord32, TERRITORY_BOUNDARY(j))) { nrZoneOverlaps = 1; break; } @@ -2294,13 +2295,13 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) { for (j = from; j < i; j++) { // try all smaller rectangles j if (!IS_RESTRICTED(j)) { MapcodeZone z; - if (restrictZoneTo(&z, &dec->zone, BOUNDARY_PTR(j))) { + if (restrictZoneTo(&z, &dec->zone, TERRITORY_BOUNDARY(j))) { nrZoneOverlaps++; if (nrZoneOverlaps == 1) { // first fit! remember... zoneCopyFrom(&zfound, &z); ASSERT(j <= MAPCODE_BOUNDARY_MAX); - memcpy(&prevu, BOUNDARY_PTR(j), sizeof(TerritoryBoundary)); + memcpy(&prevu, TERRITORY_BOUNDARY(j), sizeof(TerritoryBoundary)); } else { // nrZoneOverlaps >= 2 // more than one hit break; // give up @@ -2338,7 +2339,7 @@ static enum MapcodeError decoderEngine(DecodeRec *dec, int parseFlags) { } // for if (!err) { - restrictZoneTo(&dec->zone, &dec->zone, BOUNDARY_PTR(lastRec(ccode))); + restrictZoneTo(&dec->zone, &dec->zone, TERRITORY_BOUNDARY(lastRec(ccode))); if (isEmpty(&dec->zone)) { err = ERR_MAPCODE_UNDECODABLE; // type 0 "BRA xx.xx" @@ -2794,7 +2795,7 @@ int multipleBordersNearby(double latDeg, double lonDeg, enum Territory territory convertCoordsToMicrosAndFractions(&coord32, NULL, NULL, latDeg, lonDeg); for (m = upto; m >= from; m--) { if (!IS_RESTRICTED(m)) { - if (isNearBorderOf(&coord32, BOUNDARY_PTR(m))) { + if (isNearBorderOf(&coord32, TERRITORY_BOUNDARY(m))) { nrFound++; if (nrFound > 1) { return 1; @@ -2924,8 +2925,9 @@ decodeMapcodeToLatLonUtf8(double *latDeg, double *lonDeg, const char *mapcode, e // PUBLIC - decode string into lat,lon; returns negative in case of error -enum MapcodeError decodeMapcodeToLatLonUtf16(double *latDeg, double *lonDeg, const UWORD *mapcode, enum Territory territory, - MapcodeElements *mapcodeElements) { +enum MapcodeError +decodeMapcodeToLatLonUtf16(double *latDeg, double *lonDeg, const UWORD *mapcode, enum Territory territory, + MapcodeElements *mapcodeElements) { if ((latDeg == NULL) || (lonDeg == NULL) || (mapcode == NULL)) { return ERR_BAD_ARGUMENTS; } else { @@ -3093,7 +3095,8 @@ int getFullTerritoryNameLocalInAlphabet(char *territoryName, enum Territory terr *territoryName = 0; return 0; } - return getFullTerritoryName_internal(territoryName, territory, alternative, (int) alphabet, TERRITORY_LOCAL_NAME_UTF8); + return getFullTerritoryName_internal(territoryName, territory, alternative, (int) alphabet, + TERRITORY_LOCAL_NAME_UTF8); } diff --git a/mapcodelib/mapcoder.h b/mapcodelib/mapcoder.h index adbf1a2..66ef75c 100644 --- a/mapcodelib/mapcoder.h +++ b/mapcodelib/mapcoder.h @@ -25,7 +25,7 @@ extern "C" { #include "mapcode_alphabets.h" -#define MAPCODE_C_VERSION "2.5.0" +#define MAPCODE_C_VERSION "2.5.1" #define UWORD unsigned short int // 2-byte unsigned integer. #define MAX_NR_OF_MAPCODE_RESULTS 22 // Max. number of results ever returned by encoder (e.g. for 26.904899, 95.138515). #define MAX_PROPER_MAPCODE_LEN 11 // Max. number of characters in a proper mapcode (including the dot, excl. precision extension). diff --git a/unittest/README.md b/unittest/README.md index efbcbd9..fca55d3 100644 --- a/unittest/README.md +++ b/unittest/README.md @@ -28,7 +28,7 @@ Or, add `-fsanitize=address` to run the address sanitizer: cd ../mapcodelib gcc -O -c mapcoder.c cd ../unittest - gcc -O unittest.c -lm -lpthread -fsanitize=address -o unittest + gcc -O unittest.c -lm -lpthread -fsanitize=address -o unittest ../mapcodelib/mapcoder.o And add the environment variable `ASAN_OPTIONS` to your shell: @@ -45,6 +45,22 @@ Compile and run as follows to use `gprof` to profile the library: cd ../unittest gcc -g -O0 unittest.c -lm -lpthread -o unittest ../mapcodelib/mapcoder.o -pg +## Using `gcov` to Show Test Coverage + +Compile and run as follows to use `gcov` to show test coverage for the libray: + + cd ../mapcodelib + gcc -fprofile-arcs -ftest-coverage -O0 -c mapcoder.c + cd ../unittest + gcc -fprofile-arcs -ftest-coverage -O0 unittest.c -lm -lpthread -o unittest ../mapcodelib/mapcoder.o -pg + ./unittest + cd ../mapcodelib + gcov mapcoder.c + cd ../unittest + gcov unittest.c + +The test coverage reports are the `*.gcov` text files. + ## Using Microsoft Visual C++ If you use **Microsoft Visual C++**, you may need to add the following defines to your preprocessor diff --git a/unittest/clean.sh b/unittest/clean.sh index f3835b7..4651ad2 100755 --- a/unittest/clean.sh +++ b/unittest/clean.sh @@ -1,5 +1,6 @@ #!/bin/sh +echo "Clean test files..." if [ -f unittest.c ] then - rm -f _*.txt gmon.out + rm -f _*.txt gmon.out *.gcda *.gcno *.gcov ../mapcodelib/*.gcda ../mapcodelib/*.gcno ../mapcodelib/*.gcov fi diff --git a/unittest/run_all.sh b/unittest/run_all.sh index 2784ae0..306c5d8 100755 --- a/unittest/run_all.sh +++ b/unittest/run_all.sh @@ -1,11 +1,13 @@ #!/bin/sh -echo "Run all tests..." -date -echo "" -./run_normal.sh -./run_sanitizer.sh -./run_gprof.sh -./run_valgrind.sh -./run_compare.sh -echo "" -echo "Done" +OUT=_report.txt +echo "Run all tests..." | tee $OUT +date | tee -a $OUT +echo "" | tee -a $OUT +./run_normal.sh | tee -a $OUT +./run_sanitizer.sh | tee -a $OUT +./run_gcov.h | tee -a $OUT +./run_gprof.sh | tee -a $OUT +./run_valgrind.sh | tee -a $OUT +./run_compare.sh | tee -a $OUT +echo "" | tee -a $OUT +echo "Done" | tee -a $OUT diff --git a/unittest/run_compare.sh b/unittest/run_compare.sh index f0f359a..591ceaa 100755 --- a/unittest/run_compare.sh +++ b/unittest/run_compare.sh @@ -1,9 +1,10 @@ #!/bin/sh -REPORT=_report_compare.txt OPTS="-Wall -Werror -Wno-pointer-to-int-cast" NEW=../utility/mapcode OLD=$HOME/bin/mapcode-2.3.1 +NEWFILE=_new.txt +OLDFILE=_old.txt OPTS1="--grid 1000000 8" OPTS2="--random 1000000 8 1234" @@ -16,13 +17,13 @@ then exit 1 fi -echo "!! -------------------------------------------------------------" | tee -a $REPORT -echo "Run compare with previous output..." | tee $REPORT -date | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +echo "!! -------------------------------------------------------------" +echo "Run compare with previous output..." +date +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT -echo "Run with: -O3" | tee -a $REPORT +echo "" +echo "Run compare with: -O3" cd ../mapcodelib gcc $OPTS -O3 -c mapcoder.c cd ../utility @@ -37,51 +38,59 @@ then fi echo "" -echo "Execute: $NEW $OPTS1" | tee -a $REPORT -$NEW | grep version | tee -a $REPORT -$NEW $OPTS1 > _new_1.txt | tee -a $REPORT +echo "Execute: $NEW $OPTS1" +$NEW | grep version +$NEW $OPTS1 > $NEWFILE echo "" -echo "Execute: $OLD $OPTS1" | tee -a $REPORT -$OLD | grep version | tee -a $REPORT -$OLD $OPTS1 > _old_1.txt | tee -a $REPORT -diff _new_1.txt _old_1.txt | tee -a $REPORT +echo "Execute: $OLD $OPTS1" +$OLD | grep version +$OLD $OPTS1 > $OLDFILE +diff $NEWFILE $OLDFILE if [ $? -ne 0 ] then - echo "ERROR: Diffs found with: " $OPTS1 | tee -a $REPORT + echo "ERROR: Diffs found with:" $OPTS1 + exit 1 +else + rm -f $NEWFILE $OLDFILE fi echo "" -echo "Execute: $NEW $OPTS2" | tee -a $REPORT -$NEW | grep version | tee -a $REPORT -$NEW $OPTS2 > _new_2.txt | tee -a $REPORT +echo "Execute: $NEW $OPTS2" +$NEW | grep version +$NEW $OPTS2 > $NEWFILE echo "" -echo "Execute: $OLD $OPTS2" | tee -a $REPORT -$OLD | grep version | tee -a $REPORT -$OLD $OPTS2 > _old_2.txt | tee -a $REPORT -diff _new_2.txt _old_2.txt | tee -a $REPORT +echo "Execute: $OLD $OPTS2" +$OLD | grep version +$OLD $OPTS2 > $OLDFILE +diff $NEWFILE $OLDFILE if [ $? -ne 0 ] then - echo "ERROR: Diffs found with: " $OPTS2 | tee -a $REPORT + echo "ERROR: Diffs found with:" $OPTS2 + exit 1 +else + rm -f $NEWFILE $OLDFILE fi echo "" -echo "Execute: $NEW $OPTS3" | tee -a $REPORT -$NEW | grep version | tee -a $REPORT -$NEW $OPTS3 > _new_3.txt | tee -a $REPORT +echo "Execute: $NEW $OPTS3" +$NEW | grep version +$NEW $OPTS3 > $NEWFILE echo "" -echo "Execute: $OLD $OPTS3" | tee -a $REPORT -$OLD | grep version | tee -a $REPORT -$OLD $OPTS3 > _old_3.txt | tee -a $REPORT -diff _new_3.txt _old_3.txt | tee -a $REPORT +echo "Execute: $OLD $OPTS3" +$OLD | grep version +$OLD $OPTS3 > $OLDFILE +diff $NEWFILE $OLDFILE if [ $? -ne 0 ] then - echo "ERROR: Diffs found with: " $OPTS3 | tee -a $REPORT + echo "ERROR: Diffs found with:" $OPTS3 + exit 1 +else + rm -f $NEWFILE $OLDFILE fi +echo "!! -------------------------------------------------------------" -echo "!! -------------------------------------------------------------" | tee -a $REPORT - -echo "" | tee -a $REPORT +echo "" echo "Report in: $REPORT" diff --git a/unittest/run_gcov.sh b/unittest/run_gcov.sh new file mode 100755 index 0000000..9c79ebd --- /dev/null +++ b/unittest/run_gcov.sh @@ -0,0 +1,33 @@ +#!/bin/sh +OPTS="-Wall -Werror -Wno-pointer-to-int-cast -fprofile-arcs -ftest-coverage" +LIB="../mapcodelib/mapcoder.o" + +TEST=`which gcov` +if [ "$TEST" = "" ] +then + echo "No gcov found on this machine - skipping script..." + exit 1 +fi + +echo "!! -------------------------------------------------------------" +echo "Run gcov test coverage..." +date +echo "!! -------------------------------------------------------------" + +echo "" +echo "Run gcov with: -O0" +cd ../mapcodelib +gcc $OPTS -O0 -c mapcoder.c +cd ../unittest +gcc $OPTS -O0 unittest.c -lm -lpthread -o unittest $LIB +./unittest +cd ../mapcodelib +gcov mapcoder.c +cd ../unittest +gcov unittest.c +echo "!! -------------------------------------------------------------" +echo "!! Coverage reports in: *.gcov files" +echo "!! -------------------------------------------------------------" + +echo "" +echo "Report in: $REPORT" diff --git a/unittest/run_gprof.sh b/unittest/run_gprof.sh index a52a091..665a4cc 100755 --- a/unittest/run_gprof.sh +++ b/unittest/run_gprof.sh @@ -1,5 +1,4 @@ #!/bin/sh -REPORT=_report_gprof.txt OPTS="-Wall -Werror -Wno-pointer-to-int-cast" LIB="../mapcodelib/mapcoder.o" @@ -10,30 +9,30 @@ then exit 1 fi -echo "!! -------------------------------------------------------------" | tee -a $REPORT -echo "Run gprof profiler..." | tee $REPORT -date | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +echo "!! -------------------------------------------------------------" +echo "Run gprof profiler..." +date +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT -echo "Run with: -O0" | tee -a $REPORT +echo "" +echo "Run gprof with: -O0" cd ../mapcodelib gcc $OPTS -g -O0 -c mapcoder.c -pg cd ../unittest gcc $OPTS -g -O0 unittest.c -lm -lpthread -o unittest $LIB -pg -./unittest | tee -a $REPORT -gprof ./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +./unittest +gprof ./unittest +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT -echo "Run with: -O3" | tee -a $REPORT +echo "" +echo "Run gprof with: -O3" cd ../mapcodelib gcc $OPTS -g -O3 -c mapcoder.c -pg cd ../unittest gcc $OPTS -g -O3 unittest.c -lm -lpthread -o unittest $LIB -pg -./unittest | tee -a $REPORT -gprof ./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +./unittest +gprof ./unittest +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT +echo "" echo "Report in: $REPORT" diff --git a/unittest/run_normal.sh b/unittest/run_normal.sh index dbd81d4..d378710 100755 --- a/unittest/run_normal.sh +++ b/unittest/run_normal.sh @@ -1,29 +1,28 @@ #!/bin/sh -REPORT=_report_normal.txt OPTS="-Wall -Werror -Wno-pointer-to-int-cast" -echo "!! -------------------------------------------------------------" | tee -a $REPORT -echo "Run normal..." | tee $REPORT -date | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +echo "!! -------------------------------------------------------------" +echo "Run normal..." +date +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT -echo "Run with: -O0" | tee -a $REPORT +echo "" +echo "Run normal with: -O0" cd ../mapcodelib gcc $OPTS -O0 -DDEBUG -c mapcoder.c cd ../unittest gcc $OPTS -O0 -DDEBUG unittest.c -lm -lpthread -o unittest ../mapcodelib/mapcoder.o -./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +./unittest +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT -echo "Run with: -O3" | tee -a $REPORT +echo "" +echo "Run normal with: -O3" cd ../mapcodelib gcc $OPTS -O3 -c mapcoder.c cd ../unittest gcc $OPTS -O3 unittest.c -lm -lpthread -o unittest ../mapcodelib/mapcoder.o -./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +./unittest +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT +echo "" echo "Report in: $REPORT" diff --git a/unittest/run_sanitizer.sh b/unittest/run_sanitizer.sh index 7ab5276..28a2632 100755 --- a/unittest/run_sanitizer.sh +++ b/unittest/run_sanitizer.sh @@ -1,5 +1,4 @@ #!/bin/sh -REPORT=_report_sanitizer.txt OPTS="-Wall -Werror -Wno-pointer-to-int-cast" LIB="../mapcodelib/mapcoder.o" @@ -12,40 +11,40 @@ then exit 1 fi -echo "!! -------------------------------------------------------------" | tee -a $REPORT -echo "Run address sanitizer..." | tee $REPORT -date | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +echo "!! -------------------------------------------------------------" +echo "Run address sanitizer..." +date +echo "!! -------------------------------------------------------------" # No optimize -echo "" | tee -a $REPORT -echo "Run with: -O0" | tee -a $REPORT +echo "" +echo "Run address sanitizer with: -O0" cd ../mapcodelib gcc $OPTS -O0 -DDEBUG -c mapcoder.c cd ../unittest gcc $OPTS -O0 -DDEBUG unittest.c -lm -lpthread -fsanitize=address -o unittest $LIB -./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +./unittest +echo "!! -------------------------------------------------------------" # Optimize 2 -echo "" | tee -a $REPORT -echo "Run with: -O2" | tee -a $REPORT +echo "" +echo "Run address sanitizer with: -O2" cd ../mapcodelib gcc $OPTS -O2 -c mapcoder.c cd ../unittest gcc $OPTS -O2 unittest.c -lm -lpthread -fsanitize=address -o unittest $LIB -./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +./unittest +echo "!! -------------------------------------------------------------" # Optimize 3 -echo "" | tee -a $REPORT -echo "Run with: -O3" | tee -a $REPORT +echo "" +echo "Run address sanitizer with: -O3" cd ../mapcodelib gcc $OPTS -O3 -c mapcoder.c cd ../unittest gcc $OPTS -O3 unittest.c -lm -lpthread -fsanitize=address -o unittest $LIB -./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +./unittest +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT +echo "" echo "Report in: $REPORT" diff --git a/unittest/run_valgrind.sh b/unittest/run_valgrind.sh index 0e1b7ad..a67cd81 100755 --- a/unittest/run_valgrind.sh +++ b/unittest/run_valgrind.sh @@ -1,5 +1,4 @@ #!/bin/sh -REPORT=_report_valgrind.txt OPTS="-Wall -Werror -Wno-pointer-to-int-cast" LIB="../mapcodelib/mapcoder.o" @@ -10,19 +9,19 @@ then exit 1 fi -echo "!! -------------------------------------------------------------" | tee -a $REPORT -echo "Run valgrind" | tee $REPORT -date | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +echo "!! -------------------------------------------------------------" +echo "Run valgrind" +date +echo "!! -------------------------------------------------------------" -echo "" | tee -a $REPORT -echo "Run with: -O0" | tee -a report_valgrind.txt +echo "" +echo "Run valgrind with: -O0" cd ../mapcodelib gcc $OPTS -g -O0 -c mapcoder.c cd ../unittest gcc $OPTS -g -O0 unittest.c -lm -lpthread -o unittest $LIB -valgrind --leak-check=yes ./unittest | tee -a $REPORT -echo "!! -------------------------------------------------------------" | tee -a $REPORT +valgrind --leak-check=yes ./unittest +echo "!! -------------------------------------------------------------" echo "" tee -a $REPORT echo "Report in: $REPORT" diff --git a/unittest/test_territories.h b/unittest/test_territories.h index 4296100..2fd81dc 100644 --- a/unittest/test_territories.h +++ b/unittest/test_territories.h @@ -14,8 +14,7 @@ * limitations under the License. */ -// produced by fast_territories.cpp - +// *** GENERATED FILE (fast_territories.cpp), DO NOT CHANGE OR PRETTIFY *** #include "../mapcodelib/mapcode_territories.h" typedef struct { diff --git a/unittest/unittest.c b/unittest/unittest.c index 3fd2636..01e9fe5 100644 --- a/unittest/unittest.c +++ b/unittest/unittest.c @@ -50,9 +50,6 @@ #include -static const double METERS_PER_DEGREE_LAT = 110946.252133; -static const double METERS_PER_DEGREE_LON = 111319.490793; - #define MAX_THREADS 16 // Optimal: not too much, approx. nr of cores * 2, better no more than 32. static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #endif @@ -1026,9 +1023,11 @@ static void testDistance(double d1, double d2) { static int testDistances(void) { + static const double METERS_PER_DEGREE_LAT = 110946.252133; + static const double METERS_PER_DEGREE_LON = 111319.490793; int nrTests = 0; int i; - const double coordpairs[] = { + static const double coordpairs[] = { // lat1, lon1, lat2, lon2, expected distance * 100000 1, 1, 1, 1, 0, 0, 0, 0, 1, 11131949079, @@ -1380,6 +1379,7 @@ static int testCorrectDecode(char *mc, enum Territory tc) { double lon1; double lat2; double lon2; + UWORD utf16[MAX_CLEAN_MAPCODE_LEN + 1]; int rc = decodeMapcodeToLatLonUtf8(&lat1, &lon1, mc, tc, NULL); if (rc < 0) { foundError(); @@ -1391,7 +1391,6 @@ static int testCorrectDecode(char *mc, enum Territory tc) { printf("*** ERROR *** decodeMapcodeToLatLonUtf8 returns '%d' (should be 0) for mapcode='%s'\n", rc, mc); } - UWORD utf16[MAX_CLEAN_MAPCODE_LEN + 1]; convertMapcodeToAlphabetUtf16(utf16, mc, ALPHABET_ARABIC); rc = decodeMapcodeToLatLonUtf16(&lat2, &lon2, utf16, tc, NULL); if (rc < 0) { @@ -1876,6 +1875,33 @@ static int testAlphabets(void) { int j; const char *str, *expect; static const char *TEST_PAIRS[] = { + "irl xx.xxxx", "IRL XX.XXXX", // Grid24 + "cck XX.XX", "CCK XX.XX", // nameless22 + "cze XX.XXX", "CZE XX.XXX", // nameless23 + "NLD XXX.XX", "NLD XXX.XX", // nameless32 + "VAT 5d.dd", "VAT 5D.DD", // Grid22 + "NLD XX.XXX", "NLD XX.XXX", // Grid23 + "bhr xxx.xx", "BHR XXX.XX", // Grid32 + "FRA XXX.XXX", "FRA XXX.XXX", // Grid33 + "irl xx.xxxx", "IRL XX.XXXX", // Grid24 + "cub xxxx.xx", "CUB XXXX.XX", // Grid42 + "ben xxxx.xxx", "BEN XXXX.XXX", // Grid34 + "USA xxxx.xxxx", "USA XXXX.XXXX", // Grid44 + "US-AZ hhh.hh", "US-AZ HHH.HH", // HGrid32 + "Bel hhh.hhh", "BEL HHH.HHH", // HGrid33 + "PAN hh.hhhh", "PAN HH.HHHH", // HGrid24 + "GRC hhhh.hh", "GRC HHHH.HH", // HGrid42 + "NZL hhhh.hhh", "NZL HHHH.HHH", // HGrid43 + "KAZ hhh.hhhh", "KAZ HHH.HHHH", // HGrid34 + "RUS xxxx.xxxx", "RUS XXXX.XXXX", // HGrid44 + "CN-SH hhhh.hhhh", "CN-SH HHHH.HHHH", // HGrid44 + "VAT hhhhh.hhhh", "VAT HHHHH.HHHH", // HGrid54 + "hhhhh.hhhh", "HHHHH.HHHH", // HGrid54 + "TUV hh.hhh", "TUV HH.HHH", // AutoHeader23 + "LVA L88.ZVR", "LVA L88.ZVR", // AutoHeader33 + "WLF XLG.3GP", "WLF XLG.3GP", // HGrid33 R + "VAT j0q3.27r", "VAT J0Q3.27R", // HGrid43 R + "PAK hhhh.hhhh", "PAK HHHH.HHHH", // HGrid44 R "xxx.xxxx", "XXX.XXXX", "nld XX.XX", "NLD XX.XX", ".123", "", @@ -1944,6 +1970,20 @@ static int testAlphabets(void) { str = TEST_PAIRS[j]; expect = TEST_PAIRS[j + 1]; convertMapcodeToAlphabetUtf16(enc, str, i); + { + char utf8[3 * MAX_MAPCODE_RESULT_LEN + 1]; + MapcodeElements mapcodeElements; + double lat1, lon1, lat2, lon2, lat3, lon3; + convertMapcodeToAlphabetUtf8(utf8, str, i); + decodeMapcodeToLatLonUtf16(&lat1, &lon1, enc, TERRITORY_FRA, &mapcodeElements); + decodeMapcodeToLatLonUtf8(&lat2, &lon2, utf8, TERRITORY_FRA, &mapcodeElements); + decodeMapcodeToLatLonUtf8(&lat3, &lon3, str, TERRITORY_FRA, &mapcodeElements); + ++nrTests; + if (lat1 != lat2 || lon1 != lon2 || lat1 != lat3 || lon1 != lon3) { + foundError(); + printf("*** ERROR *** Difference in ascii/utf8/utf16 decoding %s\n", str); + } + } myConvertToRoman(dec, enc); ++nrTests; if (strcmp(dec, expect)) {