#include #include #include #include #include #include "log.h" #define PLOT_LINES 6 static void log_add_ent(log_t *l, logent_t *le); static void logent_destroy(logent_t *le); static void fatal_error(const char *format, ...); static f_t *finit(char *name, const char *mode); static void fend(f_t *f); /** * Get the time: function to use as logfunc_t **/ void gettime(unsigned long long *t) { struct timeval tp; unsigned long long ctime; gettimeofday( &tp, NULL ); ctime = tp.tv_sec; ctime *= 1000000; ctime += tp.tv_usec; *t = ctime; } log_t *log_init(char *fn, const char *mode, char *xlabel, char *ylabel, logfunc_t func) { char buf[256]; stat_t st; log_t *l = (log_t *) malloc(sizeof(log_t)); if (l == NULL) fatal_error("Could not allocate memory for the new log [%s].", fn); if (stat(LOG_DIR, &st) != 0) if (mkdir(LOG_DIR, 0777)) fatal_error("CouldĀ not create directory: %s", LOG_DIR); sprintf(buf, "%s/%s-%s", LOG_DIR, fn, LOG_PLT); l->file = finit(buf, mode); if (l->file->lines == 0) l->file->lines = PLOT_LINES; l->entries = 0; l->entry = NULL; l->xlabel = strdup(xlabel); l->ylabel = strdup(ylabel); l->func = func; return l; } logent_t *logent_init(log_t *l, char *desc, ...) { char buf[256]; char *id; va_list vargs; logent_t *le = (logent_t *)malloc(sizeof(logent_t)); if (l == NULL) fatal_error("Log is NULL\n"); if (le == NULL) fatal_error("Could not allocate memory for log entry: %s:%s\n", l->file->fn, desc); le->desc = strdup(desc); va_start(vargs, desc); id = va_arg(vargs, char*); va_end(vargs); if (id != NULL) sprintf(buf, "%s-%d.data", l->file->fn, l->file->lines - PLOT_LINES + l->entries); else sprintf(buf, "%s-%s.data", l->file->fn, id); printf("FN: %s\n", buf); le->file = finit(buf, l->file->mode); log_add_ent(l, le); return le; } void logent_start(logent_t *le, ...) { va_list vargs; if (le == NULL) fatal_error("Log entry is NULL\n"); va_start(vargs, le); le->log->func(&le->t1); va_end(vargs); } void logent_end(logent_t *le, int idx, int ent, ...) { int res; va_list vargs; if (le == NULL) fatal_error("Logentry is NULL\n"); va_start(vargs, ent); le->log->func(&le->t2, vargs); va_end(vargs); if (ent <= 0) ent = 1; res = (int)(le->t2 - le->t1) / ent; fprintf(le->file->f, "%d %d\n", idx, res); fflush(le->file->f); } void log_destroy(log_t *l) { int i; if (ftell(l->file->f) == 0) { fprintf(l->file->f, "set terminal postscript color\n"); fprintf(l->file->f, "set output \"%s-%s\"\n", l->file->fn, LOG_CMP); fprintf(l->file->f, "set autoscale\n"); fprintf(l->file->f, "set xlabel \"%s\"\nset ylabel \"%s\"\n", l->xlabel, l->ylabel); fprintf(l->file->f, "set key right\nplot"); } for (i = 0; i < l->entries; i++) { if (l->entry[i]->file->lines == 0) { fprintf(l->file->f, " \\\n\"%s\" w linespoints lw 2 t \"%s\",", l->entry[i]->file->fn, l->entry[i]->desc ); } logent_destroy(l->entry[i]); } fflush(l->file->f); fend(l->file); free(l->xlabel); free(l->ylabel); if (l->entry != NULL) free(l->entry); } /** * When something bad happens.... we end! **/ static void fatal_error(const char *format, ...) { va_list vargs; fprintf(stdout, "[FATAL] "); va_start(vargs, format); vfprintf(stdout, format, vargs); va_end(vargs); exit(EXIT_FAILURE); } static f_t *finit(char *name, const char *mode) { char c; f_t *f = (f_t *)malloc(sizeof(f_t)); if (f == NULL) fatal_error("Could not allocate memory for %s\n", name); f->fn = strdup(name); f->f = fopen(f->fn, mode); f->lines = 0; f->mode = mode; if (f->f == NULL) fatal_error("Coult not open %s[%s]\n", name, mode); while ((c = fgetc(f->f)) != EOF) if (c == '\n') f->lines++; fseek(f->f, 0, SEEK_END); return f; } static void fend(f_t *f) { if (f == NULL) fatal_error("Cant close NULL-file\n"); if (f->f == NULL) return; printf("[FILE] stored in: %s\n", f->fn); free(f->fn); fclose(f->f); } static void log_add_ent(log_t *l, logent_t *le) { int i; logent_t **entry = (logent_t **)malloc(sizeof(logent_t*) * (l->entries + 1)); for (i = 0; i < l->entries; i++) entry[i] = l->entry[i]; entry[l->entries++] = le; if (l->entry != NULL) free(l->entry); l->entry = entry; le->log = l; } static void logent_destroy(logent_t *le) { if (le == NULL) fatal_error("Cant close log entry 0x%p\n", le); if (le->file->f != NULL) fend(le->file); le->file->f = NULL; free(le->desc); free(le); }