/* * IGC parser * @brief parse IGC file, get all data points, compute average horizontal/vertical speed, print to STDOUT * * As per standard: https://xp-soaring.github.io/igc_file_format/igc_format_2008.html * https://xp-soaring.github.io/igc_file_format/igc_fr_specification_with_al8_2023-2-1_0.pdf * * @author xamidev * @license GNU GPL v3 */ #include #include #include #include #include "igc.h" void parse_igc_file(FILE* fp) { size_t len = 0; char* line = NULL; while (getline(&line, &len, fp) != -1) { switch(line[0]) { case DATAPOINT: struct IGC_DataPoint* dp = (struct IGC_DataPoint*)malloc(sizeof(struct IGC_DataPoint)); char hour[3], min[3], sec[3] = {0}; char lat_d[3], lat_m[3], lat_s[4] = {0}; char lon_d[4], lon_m[3], lon_s[4] = {0}; memcpy(hour, line+1, 2); memcpy(min, line+3, 2); memcpy(sec, line+5, 2); memcpy(lat_d, line+7, 2); memcpy(lat_m, line+9, 2); memcpy(lat_s, line+11, 3); memcpy(lon_d, line+15, 3); memcpy(lon_m, line+18, 2); memcpy(lon_s, line+20, 3); dp->hour = atoi(hour); dp->minute = atoi(min); dp->second = atoi(sec); dp->lat.deg = atoi(lat_d); dp->lat.min = atoi(lat_m); dp->lat.sec = atoi(lat_s); dp->lat.cardinal = line[14] == NORTH ? NORTH : SOUTH; dp->lon.deg = atoi(lon_d); dp->lon.min = atoi(lon_m); dp->lon.sec = atoi(lon_s); dp->lon.cardinal = line[23] == EAST ? EAST : WEST; printf("%s", line); printf("Data point: %d:%d:%d | %d°%d'%d\"%c %d°%d'%d\"%c\n", dp->hour, dp->minute, dp->second, dp->lat.deg, dp->lat.min, dp->lat.sec, dp->lat.cardinal, dp->lon.deg, dp->lon.min, dp->lon.sec, dp->lon.cardinal); // Debug exit(0); break; default: break; } } } int main(int argc, char* argv[]) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return -EINVAL; } char filename[NAME_MAX] = {0}; strncpy(filename, argv[1], NAME_MAX-1); FILE* fp = fopen(filename, "r"); if (!fp) { printf("Couldn't open file %s\n", filename); return -EINVAL; } parse_igc_file(fp); return EXIT_SUCCESS; }