converted cpint code to C++ in preparation for making it understand SRM files

This commit is contained in:
Sean C. Rhea
2007-04-17 21:55:08 +00:00
parent 611e57688b
commit ecdd556ca3
7 changed files with 111 additions and 92 deletions

View File

@@ -21,9 +21,9 @@
CC=gcc
CFLAGS=-g -W -Wall -Werror -ansi -pedantic -std=c99
CMDS=ptdl ptpk ptunpk cpint
LIBS=../lib/libgc.a
LIBRARIES=-lm
INCLUDES=-I../lib
LIBS=../lib/libgc.a ../cpint/libcpint.a
LIBRARIES=-lm -lQtCore
INCLUDES=-I../lib -I../cpint
all: $(CMDS)
.PHONY: all clean
@@ -35,7 +35,7 @@ clean:
$(CC) -c $(CFLAGS) $(INCLUDES) $<
cpint: cpint.o $(LIBS)
$(CXX) -o $@ $^ $(LIBRARIES)
$(CXX) -o $@ $^ $(LIBS) $(LIBRARIES)
ptdl: ptdl.o $(LIBS)
$(CC) -o $@ $^ $(LIBRARIES)

View File

@@ -25,23 +25,27 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "srm.h"
#include "pt.h"
#include "cpint.h"
struct point
struct cpint_point
{
double secs;
int watts;
struct point *next;
cpint_point(double s, int w) : secs(s), watts(w) {}
};
static struct point *head, *tail;
time_t start_since_epoch;
static double last_secs;
static int rec_int_ms;
struct cpint_data {
QList<cpint_point> points;
time_t start_since_epoch;
double last_secs;
int rec_int_ms;
cpint_data() : start_since_epoch(0), last_secs(0.0), rec_int_ms(0) {}
};
static int
secs_to_interval(double secs)
secs_to_interval(double secs, int rec_int_ms)
{
if (rec_int_ms == 0) {
fprintf(stderr, "Missing recording interval.\n");
@@ -50,62 +54,56 @@ secs_to_interval(double secs)
return (int) round(secs * 1000.0 / rec_int_ms);
}
static void
add_point(double secs, double watts)
{
struct point *p = (struct point*) malloc(sizeof(struct point));
p->secs = secs;
p->watts = watts;
p->next = NULL;
if (tail) tail->next = p; else head = p;
tail = p;
}
static void
config_cb(unsigned interval, unsigned rec_int,
unsigned wheel_sz_mm, void *context)
{
double new_rec_int_ms = rec_int * 1.26 * 1000.0;
interval = wheel_sz_mm = 0;
context = NULL;
assert((rec_int_ms == 0.0) || (rec_int_ms == new_rec_int_ms));
rec_int_ms = new_rec_int_ms;
(void) interval;
(void) wheel_sz_mm;
cpint_data *data = (cpint_data*) context;
int new_rec_int_ms = rec_int * 1260;
assert((data->rec_int_ms == 0) || (data->rec_int_ms == new_rec_int_ms));
data->rec_int_ms = new_rec_int_ms;
}
static void
time_cb(struct tm *time, time_t since_epoch, void *context)
{
double secs;
context = NULL;
time = NULL;
if (start_since_epoch == 0)
start_since_epoch = since_epoch;
secs = since_epoch - start_since_epoch;
(void) time;
cpint_data *data = (cpint_data*) context;
if (data->start_since_epoch == 0)
data->start_since_epoch = since_epoch;
double secs = since_epoch - data->start_since_epoch;
/* Be conservative: a sleep interval counts as all zeros. */
add_point(secs, 0.0);
last_secs = secs;
data->points.append(cpint_point(secs, 0));
data->last_secs = secs;
}
static void
data_cb(double secs, double nm, double mph, double watts, double miles,
unsigned cad, unsigned hr, unsigned interval, void *context)
{
context = NULL;
nm = 0.0; miles = 0.0; cad = 0; hr = 0; interval = 0;
cpint_data *data = (cpint_data*) context;
(void) nm;
(void) miles;
(void) cad;
(void) hr;
(void) interval;
/* Be conservative: count NaN's as zeros. */
add_point(secs, (mph == -1.0) ? 0.0 : watts);
last_secs = secs;
data->points.append(cpint_point(secs, ((mph == -1.0) ? 0
: (int) round(watts))));
data->last_secs = secs;
}
static void
error_cb(const char *msg, void *context)
{
context = NULL;
(void) context;
fprintf(stderr, "%s\n", msg);
exit(1);
}
struct cpi_file_info *
cpi_file_info *
cpi_files_to_update(const char *dir)
{
DIR *dirp;
@@ -113,7 +111,7 @@ cpi_files_to_update(const char *dir)
regex_t reg;
struct stat sbi, sbo;
char *inname, *outname;
struct cpi_file_info *head = NULL, *tail = NULL;
cpi_file_info *head = NULL, *tail = NULL;
if (regcomp(&reg, "^([0-9][0-9][0-9][0-9])_([0-9][0-9])_([0-9][0-9])"
"_([0-9][0-9])_([0-9][0-9])_([0-9][0-9])\\.raw$", REG_EXTENDED))
@@ -125,16 +123,16 @@ cpi_files_to_update(const char *dir)
int nmatch = 7;
regmatch_t *pmatch = (regmatch_t*) calloc(nmatch, sizeof(regmatch_t));
if (regexec(&reg, dp->d_name, nmatch, pmatch, 0) == 0) {
inname = malloc(strlen(dir) + 25);
outname = malloc(strlen(dir) + 25);
inname = (char*) malloc(strlen(dir) + 25);
outname = (char*) malloc(strlen(dir) + 25);
sprintf(inname, "%s/%s", dir, dp->d_name);
if (stat(inname, &sbi))
assert(0);
sprintf(outname, "%s/%s", dir, dp->d_name);
strcpy(outname + strlen(outname) - 4, ".cpi");
if ((stat(outname, &sbo)) || (sbo.st_mtime < sbi.st_mtime)) {
struct cpi_file_info *info = (struct cpi_file_info*)
malloc(sizeof(struct cpi_file_info));
cpi_file_info *info =
(cpi_file_info*) malloc(sizeof(cpi_file_info));
info->file = strdup(dp->d_name);
info->inname = inname;
info->outname = outname;
@@ -162,40 +160,36 @@ cpi_files_to_update(const char *dir)
}
void
update_cpi_file(struct cpi_file_info *info,
update_cpi_file(cpi_file_info *info,
int (*cancel_cb)(void *user_data),
void *user_data)
{
FILE *in, *out;
int canceled = 0;
double start_secs, prev_secs, dur_secs, avg, sum;
int dur_ints, i, total_intervals;
int dur_ints, total_intervals;
double *bests;
struct point *p, *q;
int progress_count = 0;
in = fopen(info->inname, "r");
assert(in);
out = fopen(info->outname, "w");
assert(out);
if (head) {
p = head;
while (p) { q = p; p = p->next; free(q); }
head = tail = NULL;
}
start_since_epoch = 0;
last_secs = 0.0;
pt_read_raw(in, 0 /* not compat */, NULL,
cpint_data data;
pt_read_raw(in, 0 /* not compat */, &data,
&config_cb, &time_cb, &data_cb, &error_cb);
total_intervals = secs_to_interval(tail->secs);
total_intervals =
secs_to_interval(data.points.back().secs, data.rec_int_ms);
bests = (double*) calloc(total_intervals + 1, sizeof(double));
start_secs = prev_secs = 0.0;
for (p = head; p; p = p->next) {
sum = 0.0;
for (q = p; q; q = q->next) {
for (int i = 0; i < data.points.size(); ++i) {
cpint_point *p = &data.points[i];
for (int j = i; j < data.points.size(); ++j) {
sum = 0.0;
cpint_point *q = &data.points[j];
if (cancel_cb && (++progress_count % 1000 == 0)) {
if (cancel_cb(user_data)) {
canceled = 1;
@@ -204,7 +198,7 @@ update_cpi_file(struct cpi_file_info *info,
}
sum += (q->secs - prev_secs) * q->watts;
dur_secs = q->secs - start_secs;
dur_ints = secs_to_interval(dur_secs);
dur_ints = secs_to_interval(dur_secs, data.rec_int_ms);
avg = sum / dur_secs;
if (bests[dur_ints] < avg)
bests[dur_ints] = avg;
@@ -213,9 +207,9 @@ update_cpi_file(struct cpi_file_info *info,
start_secs = prev_secs = p->secs;
}
for (i = 0; i <= total_intervals; ++i) {
for (int i = 0; i <= total_intervals; ++i) {
if (bests[i] != 0)
fprintf(out, "%6.3f %3.0f\n", i * rec_int_ms / 1000.0 / 60.0,
fprintf(out, "%6.3f %3.0f\n", i * data.rec_int_ms / 1000.0 / 60.0,
round(bests[i]));
}
@@ -227,9 +221,9 @@ done:
}
void
free_cpi_file_info(struct cpi_file_info *head)
free_cpi_file_info(cpi_file_info *head)
{
struct cpi_file_info *tmp;
cpi_file_info *tmp;
while (head) {
free(head->file);
free(head->inname);
@@ -244,27 +238,24 @@ free_cpi_file_info(struct cpi_file_info *head)
static int
read_one(const char *inname, double *bests[], int *bestlen)
{
FILE *in;
char line[40];
int lineno;
double mins;
int watts;
double *tmp;
int interval;
if (!(in = fopen(inname, "r")))
FILE *in = fopen(inname, "r");
if (!in)
return -1;
lineno = 1;
int lineno = 1;
int rec_int_ms = 0;
char line[40];
while (fgets(line, sizeof(line), in) != NULL) {
double mins;
int watts;
if (sscanf(line, "%lf %d\n", &mins, &watts) != 2) {
fprintf(stderr, "Bad match on line %d: %s", lineno, line);
exit(1);
}
if (rec_int_ms == 0)
rec_int_ms = mins * 60.0 * 1000.0;
interval = secs_to_interval(mins * 60.0);
rec_int_ms = (int) round(mins * 60.0 * 1000.0);
int interval = secs_to_interval(mins * 60.0, rec_int_ms);
while (interval >= *bestlen) {
tmp = calloc(*bestlen * 2, sizeof(double));
double *tmp = (double*) calloc(*bestlen * 2, sizeof(double));
memcpy(tmp, *bests, *bestlen * sizeof(double));
free(*bests);
*bests = tmp;
@@ -281,15 +272,12 @@ read_one(const char *inname, double *bests[], int *bestlen)
int
read_cpi_file(const char *dir, const char *raw, double *bests[], int *bestlen)
{
char *inname;
int result;
*bestlen = 1000;
*bests = calloc(*bestlen, sizeof(double));
inname = malloc(strlen(dir) + 25);
*bests = (double*) calloc(*bestlen, sizeof(double));
char *inname = (char*) malloc(strlen(dir) + 25);
sprintf(inname, "%s/%s", dir, raw);
strcpy(inname + strlen(inname) - 4, ".cpi");
result = read_one(inname, bests, bestlen);
int result = read_one(inname, bests, bestlen);
free(inname);
return result;
}
@@ -302,8 +290,8 @@ combine_cpi_files(const char *dir, double *bests[], int *bestlen)
char *inname;
*bestlen = 1000;
*bests = calloc(*bestlen, sizeof(double));
inname = malloc(strlen(dir) + 25);
*bests = (double*) calloc(*bestlen, sizeof(double));
inname = (char*) malloc(strlen(dir) + 25);
dirp = opendir(dir);
assert(dirp);
while ((dp = readdir(dirp)) != NULL) {
@@ -316,4 +304,3 @@ combine_cpi_files(const char *dir, double *bests[], int *bestlen)
free(inname);
}

View File

@@ -23,6 +23,10 @@
#include <regex.h>
#ifdef __cplusplus
extern "C" {
#endif
struct cpi_file_info {
char *file, *inname, *outname;
regmatch_t *pmatch;
@@ -42,5 +46,9 @@ extern int read_cpi_file(const char *dir, const char *raw,
extern void combine_cpi_files(const char *dir, double *bests[], int *bestlen);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __cpint_h */

16
src/cpint/cpint.pro Normal file
View File

@@ -0,0 +1,16 @@
######################################################################
# Automatically generated by qmake (2.01a) Sun Apr 8 17:19:06 2007
######################################################################
TEMPLATE = lib
TARGET =
DEPENDPATH += .
INCLUDEPATH += . ../lib ../srm
CONFIG += static debug
LIBS += -lm
# Input
HEADERS += cpint.h
SOURCES += cpint.cpp

View File

@@ -5,10 +5,10 @@
TEMPLATE = app
TARGET +=
DEPENDPATH += .
INCLUDEPATH += /home/srhea/src/qwt-5.0.1/src ../lib ../srm
INCLUDEPATH += /home/srhea/src/qwt-5.0.1/src ../lib ../srm ../cpint
CONFIG += static debug
LIBS += /home/srhea/src/qwt-5.0.1/lib/libqwt.a ../lib/libgc.a
LIBS += ../srm/libsrm.a
LIBS += /home/srhea/src/qwt-5.0.1/lib/libqwt.a
LIBS += ../lib/libgc.a ../cpint/libcpint.a ../srm/libsrm.a
LIBS += -lm -lz
macx {
LIBS += -framework Carbon

View File

@@ -28,7 +28,7 @@ all: libgc.a
clean:
rm -f *.o libgc.a
libgc.a: pt.o cpint.o
libgc.a: pt.o # cpint.o
rm -f $@
ar q $@ $^

View File

@@ -21,6 +21,10 @@
#ifndef __pt_h
#define __pt_h 1
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <unistd.h>
#include <time.h>
@@ -96,5 +100,9 @@ extern void pt_read_dat(FILE *in,
double, int, int, int, void*),
void *user_data);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __pt_h */