Permalink
Browse files

Add testing

  • Loading branch information...
1 parent e6e273d commit 4732dfd395d243ff9fe8b11dc1a658a137756b48 @scheibo committed Mar 1, 2014
Showing with 209 additions and 90 deletions.
  1. +2 −0 .gitignore
  2. +15 −14 Makefile
  3. +9 −0 activity.c
  4. +10 −0 activity.h
  5. +52 −27 csv.c
  6. +7 −5 csv.h
  7. +14 −13 fitparse.c
  8. +4 −13 fitparse.h
  9. +3 −0 fix.c → fix.c.tmp
  10. +13 −18 gpx.c
  11. +79 −0 test.c
  12. 0 {test → tests}/file.gpx
  13. 0 {test → tests}/gc/1292585194-20906.gpx
  14. 0 {test → tests}/gc/2008_12_28_08_13_27.tcx
  15. 0 {test → tests}/gc/2009_01_09_11_13_14.tcx
  16. 0 {test → tests}/gc/2009_08_30_21_17_25.tcx
  17. 0 {test → tests}/gc/2009_09_19_09_22_42.tcx
  18. 0 {test → tests}/gc/2010-04-05-21-45-04.tcx
  19. BIN {test → tests}/gc/2012_01_11_11_51_01.fit
  20. BIN {test → tests}/gc/2012_02_05_09_03_59.fit
  21. BIN {test → tests}/gc/2013-04-11-17-32-50.fit
  22. BIN {test → tests}/gc/20130716_202738.fit
  23. BIN {test → tests}/gc/20130717_143733.fit
  24. 0 {test → tests}/gc/A_ride_mapped_on_11_22_2011.gpx
  25. 0 {test → tests}/gc/Move_2014_01_16_19_48_44.gpx
  26. 0 {test → tests}/gc/Move_2014_01_17_09_33_11.gpx
  27. 0 {test → tests}/rides/activity_385437041.gpx
  28. 0 {test → tests}/rides/activity_385437041.tcx
  29. 0 {test → tests}/rides/activity_441537534.gpx
  30. 0 {test → tests}/rides/activity_441537534.tcx
  31. 0 {test → tests}/rides/activity_448048575.tcx
  32. 0 {test → tests}/rides/time to stop being a little bitch.gpx
  33. 0 {test → tests}/runs/-photo finish-- 23 x (-45 @ ~5k pace w- -45r)-.gpx
  34. 0 {test → tests}/runs/activity_447524792.gpx
  35. 0 {test → tests}/runs/activity_447524792.tcx
  36. 0 {test → tests}/test.gpx
  37. 0 {test → tests}/test.tcx
  38. +1 −0 util.c
View
@@ -1,2 +1,4 @@
*.o
gpx
+tests/out
+test
View
@@ -1,27 +1,25 @@
OPTIMIZATION ?= -O2
DEBUG = -g -ggdb
WARN = -Wall -pedantic
-CFLAGS += $(WARN) $(DEBUG) -pthread
+CFLAGS += $(WARN) $(DEBUG) -pthread -Ilib/mxml -Ilib/date
#TARGET = fitparse
#OBJECTS = activity.o fit.o tcx.o gpx.o
+OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)
+LIB_HEADERS = lib/mxml/mxml.h lib/date/libdate.h
+LIBS = lib/mxml/libmxml.a lib/date/libdate.a
-default: gpx
+default: test
-all: gpx
+all: test
-gpx: gpx.o activity.o util.o lib/mxml/libmxml.a lib/date/libdate.a
- $(CC) $^ $(CFLAGS) -o $@
+test: $(OBJECTS) $(LIBS) $(HEADERS)
+ $(CC) $(OBJECTS) $(LIBS) -Wall -o $@
+ mkdir -p tests/out
-gpx.o: gpx.c gpx.h lib/mxml/mxml.h $(HEADERS)
- $(CC) $(CFLAGS) -Ilib/mxml -c $< -o $@
-
-util.o: util.c lib/date/date.h $(HEADERS)
- $(CC) $(CFLAGS) -Ilib/date -c $< -o $@
-
-activity.o: activity.c $(HEADERS)
- $(CC) $(CFLAGS) -c $< -o $@
+test.o: test.c $(HEADERS)
+ $(CC) $(CFLAGS) -DDEBUG -DDEFAULT_DIR=tests/out -c $< -o $@
lib/mxml/Makefile:
cd lib/mxml >/dev/null && ./configure >/dev/null
@@ -32,11 +30,14 @@ lib/mxml/libmxml.a: lib/mxml/Makefile
lib/date/libdate.a:
$(MAKE) -C lib/date >/dev/null
+%.o: %.c $(HEADERS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
format:
-@clang-format -style=Google -i *.c *.h
clean:
- rm -rf *.o util
+ rm -rf *.o util tests/out test gpx
cd lib/mxml >/dev/null && git clean -f -d -x >/dev/null && git checkout -- mxml.xml >/dev/null
cd lib/date >/dev/null && git clean -f -d -x >/dev/null
View
@@ -29,6 +29,7 @@ Activity *activity_new(void) {
return NULL;
}
a->sport = UnknownSport;
+ a->format = UnknownFileFormat;
a->laps = NULL; /* TODO */
a->data_points = NULL;
a->num_points = 0;
@@ -57,6 +58,7 @@ void activity_destroy(Activity *a) {
}
/* TODO make sure we infer missing values and do corrections */
+/* TODO see gpx parser for additional checks we must perform */
int activity_add_point(Activity *a, DataPoint *dp) {
unsigned i;
@@ -68,6 +70,9 @@ int activity_add_point(Activity *a, DataPoint *dp) {
/* TODO fill in inferred missing values a la gpx/tcx */
for (i = 0; i < DataFieldCount; i++) {
a->data_points[a->num_points].data[i] = dp->data[i];
+ if (dp->data[i] != UNSET_FIELD && !a->has_data[i]) {
+ a->has_data[i] = true;
+ }
}
a->num_points++;
@@ -84,3 +89,7 @@ int activity_add_lap(Activity *a, uint32_t lap) {
/* add activity->laps[next] = lap; */
return 0;
}
+
+bool activity_equal(Activity *a, Activity *b) {
+ return false; /* TODO */
+}
View
@@ -13,6 +13,14 @@ typedef enum {
} bool;
typedef enum {
+ CSV,
+ GPX,
+ TCX,
+ FIT,
+ UnknownFileFormat
+} FileFormat;
+
+typedef enum {
Timestamp,
Latitude,
Longitude,
@@ -104,6 +112,7 @@ typedef enum {
*/
typedef struct {
Sport sport;
+ FileFormat format; /* the original format it was read in from */
uint32_t *laps; /* TODO array of timestamps, always at least one */
DataPoint *data_points;
size_t num_points;
@@ -119,5 +128,6 @@ Activity *activity_new(void);
void activity_destroy(Activity *a);
int activity_add_point(Activity *a, DataPoint *dp);
int activity_add_lap(Activity *a, uint32_t lap);
+bool activity_equal(Activity *a, Activity *b);
#endif /* _ACTIVITY_H_ */
View
79 csv.c
@@ -1,7 +1,12 @@
+#include <string.h>
+#include <stdio.h>
+
#include "csv.h"
+/* test empty option and remove = true... */
+
static DataField name_to_field(char *name) {
- // TODO convert name to lower case....
+ /* TODO convert name to lower case.... */
if (!strcmp(name, "timestamp") || !strcmp(name, "time")) {
return Timestamp;
} else if (!strcmp(name, "latitude") || !strcmp(name, "lat")) {
@@ -41,57 +46,76 @@ static DataField name_to_field(char *name) {
* all are doubles in base SI unit which we then convert into our format */
int csv_read(char *filename, Activity *a) {
FILE *f = NULL;
- DataField data_fields[DataFieldCount]; // TODO worry all set to zero which is
- // Timestamp
+ char buf[CSV_BUFSIZ], *comma, *last, field_str[CSV_FIELD_SIZE];
+ DataField data_fields[DataFieldCount], field;
DataPoint point;
- char buf[CSV_BUFSIZ];
+ unsigned i, count = 0;
+ /* initialize */
+ for (i = 0; i < DataFieldCount; i++) {
+ data_fields[i] = DataFieldCount;
+ }
unset_data_point(&point);
if (!(f = fopen(filename, "r"))) {
return 1;
}
/* make sure we can read the header */
- if (!fget(buf, sizeof(buf), f)) {
+ if (!fgets(buf, sizeof(buf), f)) {
return 1;
}
- // builder header array
+ for (last = buf, comma = strchr(buf, ','); count < DataFieldCount && comma; comma = strchr(last, ',')) {
+ strncpy(field_str, last, comma - last);
+ field_str[comma - last] = '\0';
+
+ if ((field = name_to_field(field_str))) {
+ data_fields[count] = field;
+ count++;
+ }
+ last = comma + 1;
+ }
+ if (count < DataFieldCount) {
+ name_to_field(last);
+ }
+
+ /*
+ // builder header array
for (;;) {
// read in array of doubles - IN ORDER
activity_add_point(a, &point);
unset_data_point(&point);
}
+ */
fclose(f);
return 0;
}
-static int write_csv(FILE *f, const char *format, size_t i, DataField f,
+static void write_field(FILE *f, const char *format, size_t i, DataField field,
Activity *a, CSVOptions o, bool *first) {
double d = a->data_points[i].data[field];
if (!o.remove_unset || a->has_data[field]) {
+ if (!*first) {
+ fprintf(f, ",");
+ }
if (d == UNSET_FIELD) {
fprintf(f, "%s", o.unset_value);
} else {
fprintf(f, format, d);
}
- if (!*first) {
- fprintf(f, ",");
- }
*first = false;
}
}
-int csv_write(char *filename, Activity *a, CSVOptions o) {
+int csv_write_options(char *filename, Activity *a, CSVOptions o) {
FILE *f = NULL;
unsigned i;
bool first = true;
- DataPoint *d;
if (!(f = fopen(filename, "w"))) {
return 1;
@@ -101,28 +125,29 @@ int csv_write(char *filename, Activity *a, CSVOptions o) {
for (i = 0; i < DataFieldCount; i++) {
if (!o.remove_unset || a->has_data[i]) {
if (first) {
- fprintf(f, "%s" DATA_FIELDS[i]);
+ fprintf(f, "%s", DATA_FIELDS[i]);
first = false;
} else {
- fprintf(f, ",%s" DATA_FIELDS[i]);
+ fprintf(f, ",%s", DATA_FIELDS[i]);
}
}
}
fprintf(f, "\n");
- for (i = 0; i < a->num_points; i++, first = true) {
- CSV(f, "%.0f", i, Timestamp, a, &o, &first);
- CSV(f, "%.15f", i, Latitude, a, &o, &first);
- CSV(f, "%.15f", i, Longitude, a, &o, &first);
- CSV(f, "%.3f", i, Altitude, a, &o, &first);
- CSV(f, "%.2f", i, Distance, a, &o, &first);
- CSV(f, "%.2f", i, Speed, a, &o, &first);
- CSV(f, "%.0f", i, Power, a, &o, &first);
- CSV(f, "%.2f", i, Grade, a, &o, &first);
- CSV(f, "%.0f", i, HeartRate, a, &o, &first);
- CSV(f, "%.0f", i, Cadence, a, &o, &first);
- CSV(f, "%.0f", i, LRBalance, a, &o, &first);
- CSV(f, "%.0f", i, Temperature, a, &o, &first);
+ /* print data points - must be at least one non empty */
+ for (i = 0, first = true; i < a->num_points; i++, first = true) {
+ write_field(f, "%.0f", i, Timestamp, a, o, &first);
+ write_field(f, "%.15f", i, Latitude, a, o, &first);
+ write_field(f, "%.15f", i, Longitude, a, o, &first);
+ write_field(f, "%.3f", i, Altitude, a, o, &first);
+ write_field(f, "%.2f", i, Distance, a, o, &first);
+ write_field(f, "%.2f", i, Speed, a, o, &first);
+ write_field(f, "%.0f", i, Power, a, o, &first);
+ write_field(f, "%.2f", i, Grade, a, o, &first);
+ write_field(f, "%.0f", i, HeartRate, a, o, &first);
+ write_field(f, "%.0f", i, Cadence, a, o, &first);
+ write_field(f, "%.0f", i, LRBalance, a, o, &first);
+ write_field(f, "%.0f", i, Temperature, a, o, &first);
fprintf(f, "\n");
}
View
12 csv.h
@@ -6,18 +6,20 @@
#define DEFAULT_CSV_OPTIONS \
{ false, "NA" }
#define CSV_BUFSIZ 4096
+#define CSV_FIELD_SIZE 32
typedef struct {
bool remove_unset;
char *unset_value;
/* Something Lap related? */
} CSVOptions;
-static int csv_write(char *filename, Activity *activity) {
- return csv_write(filename, activity, DEFAULT_CSV_OPTIONS);
-}
-
int csv_read(char *filename, Activity *activity);
-int csv_write(char *filename, Activity *activity, CSVOptions options);
+int csv_write_options(char *filename, Activity *activity, CSVOptions options);
+
+static inline int csv_write(char *filename, Activity *activity) {
+ CSVOptions options = DEFAULT_CSV_OPTIONS;
+ return csv_write_options(filename, activity, options);
+}
#endif /* _CSV_H_ */
View
@@ -1,4 +1,5 @@
#include <string.h>
+#include <ctype.h>
#include "fitparse.h"
#include "activity.h"
@@ -22,16 +23,16 @@
*/
/* indexed by FileFormat */
-static ReadFn *readers[] = {csv_read, fit_read, gpx_read, tcx_read};
+static const ReadFn readers[] = {csv_read, gpx_read, tcx_read, fit_read };
/* indexed by FileFormat */
-static WriteFn *writers[] = {csv_write, fit_write, gpx_write, tcx_write};
+static const WriteFn writers[] = {csv_write, gpx_write, tcx_write, fit_write };
static FileFormat file_format_from_name(char *filename) {
char ext[4];
- unsigned i;
+ int i;
size_t len = strlen(filename);
- for (i = 2; i >= 0; i++) {
+ for (i = 2; i >= 0; i--) {
ext[i] = tolower(*(filename + len - 3 + i));
}
ext[3] = '\0';
@@ -44,36 +45,36 @@ static FileFormat file_format_from_name(char *filename) {
return UnknownFileFormat;
}
-int fitparse_read(Activity *activity, char *filename) {
+int fitparse_read(char *filename, Activity *activity) {
size_t i;
FileFormat format = file_format_from_name(filename);
if (format != UnknownFileFormat &&
- !fitparse_read_format(activity, filename, format)) {
+ !fitparse_read_format(filename, format, activity)) {
return 0;
}
for (i = 0; i < sizeof(ARRAY_SIZE(readers)); i++) {
- if (!readers[i](activiity, filename)) {
+ if (!readers[i](filename, activity)) {
return 0;
}
}
return 1;
}
-int fitparse_write(Activity *activity, char *filename) {
+
+int fitparse_write(char *filename, Activity *activity) {
FileFormat format = file_format_from_name(filename);
if (format != UnknownFileFormat) {
format = DEFAULT_WRITE_FORMAT;
}
- return fitparse_write_format(activity, filename, format);
+ return fitparse_write_format(filename, format, activity);
}
-int fitparse_read_format(Activity *activity, char *filename,
- FileFormat format) {
+
+int fitparse_read_format(char *filename, FileFormat format, Activity *activity) {
return readers[format](filename, activity);
}
-int fitparse_write_format(Activity *activity, char *filename,
- FileFormat format) {
+int fitparse_write_format(char *filename, FileFormat format, Activity *activity) {
return writers[format](filename, activity);
}
View
@@ -6,19 +6,10 @@
typedef int (*ReadFn)(char *, Activity *);
typedef int (*WriteFn)(char *, Activity *);
-typedef enum {
- CSV,
- GPX,
- TCX,
- FIT,
- UnknownFileFormat
-} FileFormat;
-
-int fitparse_read(Activity *activity, char *filename);
-int fitparse_write(Activity *activity, char *filename);
+int fitparse_read(char *filename, Activity *activity);
+int fitparse_write(char *filename, Activity *activity);
/* helper functions - could just call the *_read or *_write function directly */
-int fitparse_read_format(Activity *activity, char *filename, FileFormat format);
-int fitparse_write_format(Activity *activity, char *filename,
- FileFormat format);
+int fitparse_read_format(char *filename, FileFormat format, Activity *activity);
+int fitparse_write_format(char *filename, FileFormat format, Activity *activity);
#endif /* _FITPARSE_H_ */
Oops, something went wrong.

0 comments on commit 4732dfd

Please sign in to comment.