Merge pull request #9 from esoule/hotfix-gsv-shorter-sentence-2

GSV sentence with 0 to 4 satellites, plus gcc -Wfloat-equal
This commit is contained in:
Kosma Moczek 2014-06-18 11:31:49 +02:00
commit 79c98e2d43
5 changed files with 265 additions and 77 deletions

View File

@ -19,7 +19,7 @@ scan-build: clean
scan-build $(MAKE) tests scan-build $(MAKE) tests
clean: clean:
$(RM) tests *.o $(RM) tests example *.o
tests: tests.o minmea.o tests: tests.o minmea.o
example: example.o minmea.o example: example.o minmea.o

View File

@ -12,7 +12,9 @@
#include "minmea.h" #include "minmea.h"
int main() #define INDENT_SPACES " "
int main(void)
{ {
char line[MINMEA_MAX_LENGTH]; char line[MINMEA_MAX_LENGTH];
while (fgets(line, sizeof(line), stdin) != NULL) { while (fgets(line, sizeof(line), stdin) != NULL) {
@ -21,62 +23,79 @@ int main()
case MINMEA_SENTENCE_RMC: { case MINMEA_SENTENCE_RMC: {
struct minmea_sentence_rmc frame; struct minmea_sentence_rmc frame;
if (minmea_parse_rmc(&frame, line)) { if (minmea_parse_rmc(&frame, line)) {
printf("$xxRMC: raw coordinates and speed: (%d/%d,%d/%d) %d/%d\n", printf(INDENT_SPACES "$xxRMC: raw coordinates and speed: (%d/%d,%d/%d) %d/%d\n",
frame.latitude.value, frame.latitude.scale, frame.latitude.value, frame.latitude.scale,
frame.longitude.value, frame.longitude.scale, frame.longitude.value, frame.longitude.scale,
frame.speed.value, frame.speed.scale); frame.speed.value, frame.speed.scale);
printf("$xxRMC fixed-point coordinates and speed scaled to three decimal places: (%d,%d) %d\n", printf(INDENT_SPACES "$xxRMC fixed-point coordinates and speed scaled to three decimal places: (%d,%d) %d\n",
minmea_rescale(&frame.latitude, 1000), minmea_rescale(&frame.latitude, 1000),
minmea_rescale(&frame.longitude, 1000), minmea_rescale(&frame.longitude, 1000),
minmea_rescale(&frame.speed, 1000)); minmea_rescale(&frame.speed, 1000));
printf("$xxRMC floating point degree coordinates and speed: (%f,%f) %f\n", printf(INDENT_SPACES "$xxRMC floating point degree coordinates and speed: (%f,%f) %f\n",
minmea_tocoord(&frame.latitude), minmea_tocoord(&frame.latitude),
minmea_tocoord(&frame.longitude), minmea_tocoord(&frame.longitude),
minmea_tofloat(&frame.speed)); minmea_tofloat(&frame.speed));
} }
else {
printf(INDENT_SPACES "$xxRMC sentence is not parsed\n");
}
} break; } break;
case MINMEA_SENTENCE_GGA: { case MINMEA_SENTENCE_GGA: {
struct minmea_sentence_gga frame; struct minmea_sentence_gga frame;
if (minmea_parse_gga(&frame, line)) { if (minmea_parse_gga(&frame, line)) {
printf("$xxGGA: fix quality: %d\n", frame.fix_quality); printf(INDENT_SPACES "$xxGGA: fix quality: %d\n", frame.fix_quality);
}
else {
printf(INDENT_SPACES "$xxGGA sentence is not parsed\n");
} }
} break; } break;
case MINMEA_SENTENCE_GST: { case MINMEA_SENTENCE_GST: {
struct minmea_sentence_gst frame; struct minmea_sentence_gst frame;
if (minmea_parse_gst(&frame, line)) { if (minmea_parse_gst(&frame, line)) {
printf("$xxGST: raw latitude,longitude and altitude error deviation: (%d/%d,%d/%d,%d/%d)\n", printf(INDENT_SPACES "$xxGST: raw latitude,longitude and altitude error deviation: (%d/%d,%d/%d,%d/%d)\n",
frame.latitude_error_deviation.value, frame.latitude_error_deviation.scale, frame.latitude_error_deviation.value, frame.latitude_error_deviation.scale,
frame.longitude_error_deviation.value, frame.longitude_error_deviation.scale, frame.longitude_error_deviation.value, frame.longitude_error_deviation.scale,
frame.altitude_error_deviation.value, frame.altitude_error_deviation.scale); frame.altitude_error_deviation.value, frame.altitude_error_deviation.scale);
printf("$xxGST fixed point latitude,longitude and altitude error deviation \ printf(INDENT_SPACES "$xxGST fixed point latitude,longitude and altitude error deviation"
scaled to one decimal place: (%d,%d,%d)\n", " scaled to one decimal place: (%d,%d,%d)\n",
minmea_rescale(&frame.latitude_error_deviation, 10), minmea_rescale(&frame.latitude_error_deviation, 10),
minmea_rescale(&frame.longitude_error_deviation, 10), minmea_rescale(&frame.longitude_error_deviation, 10),
minmea_rescale(&frame.altitude_error_deviation, 10)); minmea_rescale(&frame.altitude_error_deviation, 10));
printf("$xxGST floating point degree latitude, longitude and altitude error deviation: (%f,%f,%f)", printf(INDENT_SPACES "$xxGST floating point degree latitude, longitude and altitude error deviation: (%f,%f,%f)",
minmea_tofloat(&frame.latitude_error_deviation), minmea_tofloat(&frame.latitude_error_deviation),
minmea_tofloat(&frame.longitude_error_deviation), minmea_tofloat(&frame.longitude_error_deviation),
minmea_tofloat(&frame.altitude_error_deviation)); minmea_tofloat(&frame.altitude_error_deviation));
} }
else {
printf(INDENT_SPACES "$xxGST sentence is not parsed\n");
}
} break; } break;
case MINMEA_SENTENCE_GSV: { case MINMEA_SENTENCE_GSV: {
struct minmea_sentence_gsv frame; struct minmea_sentence_gsv frame;
if (minmea_parse_gsv(&frame, line)) { if (minmea_parse_gsv(&frame, line)) {
printf("$xxGSV: message %d of %d\n", frame.msg_nr, frame.total_msgs); printf(INDENT_SPACES "$xxGSV: message %d of %d\n", frame.msg_nr, frame.total_msgs);
printf("$xxGSV: sattelites in view: %d\n", frame.total_sats); printf(INDENT_SPACES "$xxGSV: sattelites in view: %d\n", frame.total_sats);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
printf("$xxGSV: sat nr %d, elevation: %d, azimuth: %d, snr: %d dbm\n", printf(INDENT_SPACES "$xxGSV: sat nr %d, elevation: %d, azimuth: %d, snr: %d dbm\n",
frame.sats[i].nr, frame.sats[i].nr,
frame.sats[i].elevation, frame.sats[i].elevation,
frame.sats[i].azimuth, frame.sats[i].azimuth,
frame.sats[i].snr); frame.sats[i].snr);
} }
else {
printf(INDENT_SPACES "$xxGSV sentence is not parsed\n");
}
} break;
case MINMEA_INVALID: {
printf(INDENT_SPACES "$xxxxx sentence is not valid\n");
} break; } break;
default: { default: {
printf(INDENT_SPACES "$xxxxx sentence is not parsed\n");
} break; } break;
} }
} }

View File

@ -252,7 +252,7 @@ bool minmea_scan(const char *sentence, const char *format, ...)
} break; } break;
case 'T': { // Time (int, int, int, int), -1 if empty. case 'T': { // Time (int, int, int, int), -1 if empty.
struct minmea_time *time = va_arg(ap, struct minmea_time *); struct minmea_time *time_ = va_arg(ap, struct minmea_time *);
int h = -1, i = -1, s = -1, u = -1; int h = -1, i = -1, s = -1, u = -1;
@ -281,10 +281,10 @@ bool minmea_scan(const char *sentence, const char *format, ...)
} }
} }
time->hours = h; time_->hours = h;
time->minutes = i; time_->minutes = i;
time->seconds = s; time_->seconds = s;
time->microseconds = u; time_->microseconds = u;
} break; } break;
case '_': { // Ignore the field. case '_': { // Ignore the field.
@ -481,9 +481,13 @@ bool minmea_parse_gst(struct minmea_sentence_gst *frame, const char *sentence)
bool minmea_parse_gsv(struct minmea_sentence_gsv *frame, const char *sentence) bool minmea_parse_gsv(struct minmea_sentence_gsv *frame, const char *sentence)
{ {
// $GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00*74 // $GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00*74
// $GPGSV,3,3,11,22,42,067,42,24,14,311,43,27,05,244,00,,,,*4D
// $GPGSV,4,2,11,08,51,203,30,09,45,215,28*75
// $GPGSV,4,4,13,39,31,170,27*40
// $GPGSV,4,4,13*7B
char type[6]; char type[6];
if (!minmea_scan(sentence, "tiiiiiiiiiiiiiiiiiii", if (!minmea_scan(sentence, "tiii;iiiiiiiiiiiiiiii",
type, type,
&frame->total_msgs, &frame->total_msgs,
&frame->msg_nr, &frame->msg_nr,
@ -513,9 +517,9 @@ bool minmea_parse_gsv(struct minmea_sentence_gsv *frame, const char *sentence)
return true; return true;
} }
int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time) int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time_)
{ {
if (date->year == -1 || time->hours == -1) if (date->year == -1 || time_->hours == -1)
return -1; return -1;
struct tm tm; struct tm tm;
@ -523,14 +527,14 @@ int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, cons
tm.tm_year = 2000 + date->year - 1900; tm.tm_year = 2000 + date->year - 1900;
tm.tm_mon = date->month - 1; tm.tm_mon = date->month - 1;
tm.tm_mday = date->day; tm.tm_mday = date->day;
tm.tm_hour = time->hours; tm.tm_hour = time_->hours;
tm.tm_min = time->minutes; tm.tm_min = time_->minutes;
tm.tm_sec = time->seconds; tm.tm_sec = time_->seconds;
time_t timestamp = timegm(&tm); time_t timestamp = timegm(&tm);
if (timestamp != -1) { if (timestamp != -1) {
tv->tv_sec = timestamp; tv->tv_sec = timestamp;
tv->tv_usec = time->microseconds; tv->tv_usec = time_->microseconds;
return 0; return 0;
} else { } else {
return -1; return -1;

View File

@ -182,7 +182,7 @@ bool minmea_parse_gsv(struct minmea_sentence_gsv *frame, const char *sentence);
/** /**
* Convert GPS UTC date/time representation to a UNIX timestamp. * Convert GPS UTC date/time representation to a UNIX timestamp.
*/ */
int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time); int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time_);
/** /**
* Rescale a fixed-point value to a different scale. Rounds towards zero. * Rescale a fixed-point value to a different scale. Rounds towards zero.

267
tests.c
View File

@ -268,28 +268,28 @@ END_TEST
START_TEST(test_minmea_scan_T) START_TEST(test_minmea_scan_T)
{ {
struct minmea_time time; struct minmea_time time_;
ck_assert(minmea_scan("$GPXXX,2359", "_T", &time) == false); ck_assert(minmea_scan("$GPXXX,2359", "_T", &time_) == false);
ck_assert(minmea_scan("$GPXXX,foobar", "_T", &time) == false); ck_assert(minmea_scan("$GPXXX,foobar", "_T", &time_) == false);
ck_assert(minmea_scan("$GPXXX,235960", "_T", &time) == true); ck_assert(minmea_scan("$GPXXX,235960", "_T", &time_) == true);
ck_assert_int_eq(time.hours, 23); ck_assert_int_eq(time_.hours, 23);
ck_assert_int_eq(time.minutes, 59); ck_assert_int_eq(time_.minutes, 59);
ck_assert_int_eq(time.seconds, 60); ck_assert_int_eq(time_.seconds, 60);
ck_assert_int_eq(time.microseconds, 0); ck_assert_int_eq(time_.microseconds, 0);
ck_assert(minmea_scan("$GPXXX,213700.001", "_T", &time) == true); ck_assert(minmea_scan("$GPXXX,213700.001", "_T", &time_) == true);
ck_assert_int_eq(time.hours, 21); ck_assert_int_eq(time_.hours, 21);
ck_assert_int_eq(time.minutes, 37); ck_assert_int_eq(time_.minutes, 37);
ck_assert_int_eq(time.seconds, 0); ck_assert_int_eq(time_.seconds, 0);
ck_assert_int_eq(time.microseconds, 1000); ck_assert_int_eq(time_.microseconds, 1000);
ck_assert(minmea_scan("$GPXXX,,,,,,,nope", "_T", &time) == true); ck_assert(minmea_scan("$GPXXX,,,,,,,nope", "_T", &time_) == true);
ck_assert_int_eq(time.hours, -1); ck_assert_int_eq(time_.hours, -1);
ck_assert_int_eq(time.minutes, -1); ck_assert_int_eq(time_.minutes, -1);
ck_assert_int_eq(time.seconds, -1); ck_assert_int_eq(time_.seconds, -1);
ck_assert_int_eq(time.microseconds, -1); ck_assert_int_eq(time_.microseconds, -1);
} }
END_TEST END_TEST
@ -297,7 +297,7 @@ START_TEST(test_minmea_scan_complex1)
{ {
const char *sentence = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47\r\n"; const char *sentence = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47\r\n";
char type[6]; char type[6];
struct minmea_time time; struct minmea_time time_;
struct minmea_float latitude; int latitude_direction; struct minmea_float latitude; int latitude_direction;
struct minmea_float longitude; int longitude_direction; struct minmea_float longitude; int longitude_direction;
int fix_quality; int fix_quality;
@ -307,7 +307,7 @@ START_TEST(test_minmea_scan_complex1)
struct minmea_float height; char height_units; struct minmea_float height; char height_units;
ck_assert(minmea_scan(sentence, "tTfdfdiiffcfc__", ck_assert(minmea_scan(sentence, "tTfdfdiiffcfc__",
type, type,
&time, &time_,
&latitude, &latitude_direction, &latitude, &latitude_direction,
&longitude, &longitude_direction, &longitude, &longitude_direction,
&fix_quality, &fix_quality,
@ -316,9 +316,9 @@ START_TEST(test_minmea_scan_complex1)
&altitude, &altitude_units, &altitude, &altitude_units,
&height, &height_units) == true); &height, &height_units) == true);
ck_assert_str_eq(type, "GPGGA"); ck_assert_str_eq(type, "GPGGA");
ck_assert_int_eq(time.hours, 12); ck_assert_int_eq(time_.hours, 12);
ck_assert_int_eq(time.minutes, 35); ck_assert_int_eq(time_.minutes, 35);
ck_assert_int_eq(time.seconds, 19); ck_assert_int_eq(time_.seconds, 19);
ck_assert_int_eq(latitude.value, 4807038); ck_assert_int_eq(latitude.value, 4807038);
ck_assert_int_eq(latitude.scale, 1000); ck_assert_int_eq(latitude.scale, 1000);
ck_assert_int_eq(latitude_direction, 1); ck_assert_int_eq(latitude_direction, 1);
@ -343,7 +343,7 @@ START_TEST(test_minmea_scan_complex2)
{ {
const char *sentence = "$GPBWC,081837,,,,,,T,,M,,N,*13"; const char *sentence = "$GPBWC,081837,,,,,,T,,M,,N,*13";
char type[6]; char type[6];
struct minmea_time time; struct minmea_time time_;
struct minmea_float latitude; int latitude_direction; struct minmea_float latitude; int latitude_direction;
struct minmea_float longitude; int longitude_direction; struct minmea_float longitude; int longitude_direction;
struct minmea_float bearing_true; char bearing_true_mark; struct minmea_float bearing_true; char bearing_true_mark;
@ -352,7 +352,7 @@ START_TEST(test_minmea_scan_complex2)
char name[MINMEA_MAX_LENGTH]; char name[MINMEA_MAX_LENGTH];
ck_assert(minmea_scan(sentence, "tTfdfdfcfcfcs", ck_assert(minmea_scan(sentence, "tTfdfdfcfcfcs",
type, type,
&time, &time_,
&latitude, &latitude_direction, &latitude, &latitude_direction,
&longitude, &longitude_direction, &longitude, &longitude_direction,
&bearing_true, &bearing_true_mark, &bearing_true, &bearing_true_mark,
@ -360,9 +360,9 @@ START_TEST(test_minmea_scan_complex2)
&distance, &distance_units, &distance, &distance_units,
name) == true); name) == true);
ck_assert_str_eq(type, "GPBWC"); ck_assert_str_eq(type, "GPBWC");
ck_assert_int_eq(time.hours, 8); ck_assert_int_eq(time_.hours, 8);
ck_assert_int_eq(time.minutes, 18); ck_assert_int_eq(time_.minutes, 18);
ck_assert_int_eq(time.seconds, 37); ck_assert_int_eq(time_.seconds, 37);
ck_assert_int_eq(latitude.scale, 0); ck_assert_int_eq(latitude.scale, 0);
ck_assert_int_eq(latitude_direction, 0); ck_assert_int_eq(latitude_direction, 0);
ck_assert_int_eq(longitude.scale, 0); ck_assert_int_eq(longitude.scale, 0);
@ -381,7 +381,7 @@ START_TEST(test_minmea_scan_complex3)
{ {
const char *sentence = "$GPGST,024603.00,3.2,6.6,4.7,47.3,5.8,5.6,22.0*58"; const char *sentence = "$GPGST,024603.00,3.2,6.6,4.7,47.3,5.8,5.6,22.0*58";
char type[6]; char type[6];
struct minmea_time time; struct minmea_time time_;
struct minmea_float rms_deviation; struct minmea_float rms_deviation;
struct minmea_float semi_major_deviation; struct minmea_float semi_major_deviation;
struct minmea_float semi_minor_deviation; struct minmea_float semi_minor_deviation;
@ -391,7 +391,7 @@ START_TEST(test_minmea_scan_complex3)
struct minmea_float altitude_error_deviation; struct minmea_float altitude_error_deviation;
ck_assert(minmea_scan(sentence, "tTfffffff", ck_assert(minmea_scan(sentence, "tTfffffff",
type, type,
&time, &time_,
&rms_deviation, &rms_deviation,
&semi_major_deviation, &semi_major_deviation,
&semi_minor_deviation, &semi_minor_deviation,
@ -400,10 +400,10 @@ START_TEST(test_minmea_scan_complex3)
&longitude_error_deviation, &longitude_error_deviation,
&altitude_error_deviation) == true); &altitude_error_deviation) == true);
ck_assert_str_eq(type, "GPGST"); ck_assert_str_eq(type, "GPGST");
ck_assert_int_eq(time.hours, 2); ck_assert_int_eq(time_.hours, 2);
ck_assert_int_eq(time.minutes, 46); ck_assert_int_eq(time_.minutes, 46);
ck_assert_int_eq(time.seconds, 3); ck_assert_int_eq(time_.seconds, 3);
ck_assert_int_eq(time.microseconds, 0); ck_assert_int_eq(time_.microseconds, 0);
ck_assert_int_eq(rms_deviation.value, 32); ck_assert_int_eq(rms_deviation.value, 32);
ck_assert_int_eq(rms_deviation.scale, 10); ck_assert_int_eq(rms_deviation.scale, 10);
ck_assert_int_eq(semi_major_deviation.value, 66); ck_assert_int_eq(semi_major_deviation.value, 66);
@ -596,6 +596,171 @@ START_TEST(test_minmea_parse_gsv1)
} }
END_TEST END_TEST
START_TEST(test_minmea_parse_gsv2)
{
const char *sentence = "$GPGSV,4,2,11,08,51,203,30,09,45,215,28*75";
struct minmea_sentence_gsv frame = {};
static const struct minmea_sentence_gsv expected = {
.total_msgs = 4,
.msg_nr = 2,
.total_sats = 11,
.sats = {
{
.nr = 8,
.elevation = 51,
.azimuth = 203,
.snr = 30
},
{
.nr = 9,
.elevation = 45,
.azimuth = 215,
.snr = 28
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
}
}
};
ck_assert(minmea_check(sentence) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
}
END_TEST
START_TEST(test_minmea_parse_gsv3)
{
const char *sentence = "$GPGSV,4,4,13,39,31,170,27*40";
struct minmea_sentence_gsv frame = {};
static const struct minmea_sentence_gsv expected = {
.total_msgs = 4,
.msg_nr = 4,
.total_sats = 13,
.sats = {
{
.nr = 39,
.elevation = 31,
.azimuth = 170,
.snr = 27
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
}
}
};
ck_assert(minmea_check(sentence) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
}
END_TEST
START_TEST(test_minmea_parse_gsv4)
{
const char *sentence = "$GPGSV,4,4,13*7B";
struct minmea_sentence_gsv frame = {};
static const struct minmea_sentence_gsv expected = {
.total_msgs = 4,
.msg_nr = 4,
.total_sats = 13,
.sats = {
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
},
{
.nr = 0,
.elevation = 0,
.azimuth = 0,
.snr = 0
}
}
};
ck_assert(minmea_check(sentence) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
}
END_TEST
START_TEST(test_minmea_parse_gsv5)
{
const char *sentence = "$GPGSV,4,1,13,02,28,259,33,04,12,212,27,05,34,305,30,07,79,138,*7F";
struct minmea_sentence_gsv frame = {};
static const struct minmea_sentence_gsv expected = {
.total_msgs = 4,
.msg_nr = 1,
.total_sats = 13,
.sats = {
{
.nr = 2,
.elevation = 28,
.azimuth = 259,
.snr = 33
},
{
.nr = 4,
.elevation = 12,
.azimuth = 212,
.snr = 27
},
{
.nr = 5,
.elevation = 34,
.azimuth = 305,
.snr = 30
},
{
.nr = 7,
.elevation = 79,
.azimuth = 138,
.snr = 0
}
}
};
ck_assert(minmea_check(sentence) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
}
END_TEST
START_TEST(test_minmea_usage1) START_TEST(test_minmea_usage1)
{ {
const char *sentences[] = { const char *sentences[] = {
@ -649,18 +814,18 @@ END_TEST
START_TEST(test_minmea_gettimeofday) START_TEST(test_minmea_gettimeofday)
{ {
struct minmea_date date = { 14, 2, 14 }; struct minmea_date date = { 14, 2, 14 };
struct minmea_time time = { 13, 0, 9, 123456 }; struct minmea_time time_ = { 13, 0, 9, 123456 };
struct timeval tv; struct timeval tv;
ck_assert(minmea_gettimeofday(&tv, &date, &time) == 0); ck_assert(minmea_gettimeofday(&tv, &date, &time_) == 0);
ck_assert_int_eq(tv.tv_sec, 1392382809); ck_assert_int_eq(tv.tv_sec, 1392382809);
ck_assert_int_eq(tv.tv_usec, 123456); ck_assert_int_eq(tv.tv_usec, 123456);
date.year = -1; date.year = -1;
ck_assert(minmea_gettimeofday(&tv, &date, &time) != 0); ck_assert(minmea_gettimeofday(&tv, &date, &time_) != 0);
date.year = 2014; date.year = 2014;
time.hours = -1; time_.hours = -1;
ck_assert(minmea_gettimeofday(&tv, &date, &time) != 0); ck_assert(minmea_gettimeofday(&tv, &date, &time_) != 0);
} }
END_TEST END_TEST
@ -682,32 +847,28 @@ START_TEST(test_minmea_rescale)
} }
END_TEST END_TEST
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
/* The float values used in tests should be exactly representable under IEEE754; /* The float values used in tests should be exactly representable under IEEE754;
* false negatives will occur otherwise. */ * false negatives will occur otherwise. */
START_TEST(test_minmea_float) START_TEST(test_minmea_float)
{ {
ck_assert(isnan(minmea_tofloat(&(struct minmea_float) { 42, 0 }))); ck_assert(isnan(minmea_tofloat(&(struct minmea_float) { 42, 0 })));
ck_assert(minmea_tofloat(&(struct minmea_float) { 7, 1}) == 7.0); ck_assert(fabsf(minmea_tofloat(&(struct minmea_float) { 7, 1}) - 7.0f) <= 0.0f);
ck_assert(minmea_tofloat(&(struct minmea_float) { -200, 100}) == -2.0); ck_assert(fabsf(minmea_tofloat(&(struct minmea_float) { -200, 100}) - (-2.0f)) <= 0.0f);
ck_assert(minmea_tofloat(&(struct minmea_float) { 15, 10}) == 1.5); ck_assert(fabsf(minmea_tofloat(&(struct minmea_float) { 15, 10}) - 1.5f) <= 0.0f);
} }
END_TEST END_TEST
START_TEST(test_minmea_coord) START_TEST(test_minmea_coord)
{ {
ck_assert(isnan(minmea_tocoord(&(struct minmea_float) { 42, 0 }))); ck_assert(isnan(minmea_tocoord(&(struct minmea_float) { 42, 0 })));
ck_assert(minmea_tocoord(&(struct minmea_float) { 4200, 1 }) == 42.0); ck_assert(fabsf(minmea_tocoord(&(struct minmea_float) { 4200, 1 }) - 42.0f) <= 0.0f);
ck_assert(minmea_tocoord(&(struct minmea_float) { 420000, 100 }) == 42.0); ck_assert(fabsf(minmea_tocoord(&(struct minmea_float) { 420000, 100 }) - 42.0f) <= 0.0f);
ck_assert(minmea_tocoord(&(struct minmea_float) { 423000, 100 }) == 42.5); ck_assert(fabsf(minmea_tocoord(&(struct minmea_float) { 423000, 100 }) - 42.5f) <= 0.0f);
} }
END_TEST END_TEST
#pragma GCC diagnostic pop static Suite *minmea_suite(void)
Suite *minmea_suite(void)
{ {
Suite *s = suite_create ("minmea"); Suite *s = suite_create ("minmea");
@ -738,6 +899,10 @@ Suite *minmea_suite(void)
tcase_add_test(tc_parse, test_minmea_parse_gll2); tcase_add_test(tc_parse, test_minmea_parse_gll2);
tcase_add_test(tc_parse, test_minmea_parse_gst1); tcase_add_test(tc_parse, test_minmea_parse_gst1);
tcase_add_test(tc_parse, test_minmea_parse_gsv1); tcase_add_test(tc_parse, test_minmea_parse_gsv1);
tcase_add_test(tc_parse, test_minmea_parse_gsv2);
tcase_add_test(tc_parse, test_minmea_parse_gsv3);
tcase_add_test(tc_parse, test_minmea_parse_gsv4);
tcase_add_test(tc_parse, test_minmea_parse_gsv5);
suite_add_tcase(s, tc_parse); suite_add_tcase(s, tc_parse);
TCase *tc_usage = tcase_create("minmea_usage"); TCase *tc_usage = tcase_create("minmea_usage");
@ -754,7 +919,7 @@ Suite *minmea_suite(void)
return s; return s;
} }
int main() int main(void)
{ {
int number_failed; int number_failed;
Suite *s = minmea_suite(); Suite *s = minmea_suite();