+static void format_csv(struct user_options *opts, struct msg *msg)
+{
+ char *tok = (char *) msg->data;
+ token(&tok, '|'); // unknown
+ char *seq = token(&tok, '|');
+ char *type = token(&tok, '|');
+ char *val = token(&tok, '|');
+ char *unit = token(&tok, '|');
+ token(&tok, '|');// unknown
+ char *notes = token(&tok, '|');
+ token(&tok, '|');// unknown
+ char *time = token(&tok, '\r');
+
+ unit[strlen(unit)-2] = 0;
+ fprintf(opts->outf,
+ "%s,\"%.4s-%.2s-%.2s %.2s:%.2s\",\"%s\",\"%s\",\"%s\","
+ "%s,%s,%s,%s,%s,%s,%s\n",
+ seq, &time[0], &time[4], &time[6], &time[8], &time[10],
+ &type[3], val, unit,
+ strchr(notes, 'B') ? "X" : "",
+ strchr(notes, 'A') ? "X" : "",
+ strchr(notes, 'S') ? "X" : "",
+ strchr(notes, 'I') ? "X" : "",
+ strchr(notes, 'D') ? "X" : "",
+ strchr(notes, 'X') ? "X" : "",
+ strchr(notes, 'C') ? "X" : ""
+ );
+}
+
+static int format_message(struct user_options *opts, struct msg *msg, int len)
+{
+ switch (opts->output_format)
+ {
+ case CSV:
+ format_csv(opts, msg);
+ break;
+
+ case CLEAN:
+ sanitize_ascii(msg->data, len);
+ fprintf(opts->outf, "%s\n", msg->data);
+ break;
+
+ case RAW:
+ fprintf(opts->outf, "%s", msg->data);
+ break;
+
+ default:
+ trace(0, "BUG: Invalid message format %d\n",
+ opts->output_format);
+ return -1;
+ }
+
+ fflush(opts->outf);
+
+ return 0;
+}
+
+static int dump_entries(struct user_options *opts, int fd, int usage_code)
+{
+ struct msg msg;
+ int ret;
+ int entries = 0;
+
+ trace(0, "Reading data ...\n");
+ if (opts->output_format == CSV)
+ fprintf(opts->outf, "#,Time,Type,Value,Unit,\"Before meal\","
+ "\"After meal\",Stress,Sick,\"Dont feel right\","
+ "Activity,\"Control test\"\n");
+
+ while (1) {
+ ret = contour_read_entry(fd, usage_code, &msg);
+ if (ret < 45)
+ return -1;
+
+ ret = format_message(opts, &msg, ret);
+ if (ret < 0)
+ return ret;
+
+ entries++;
+
+ if ((opts->outf != stdout) || !isatty(fileno(stdout))) {
+ trace(0, "\r%d entries", entries);
+ fflush(stdout);
+ }
+ }
+ trace(0, "\nDone.\n");
+
+ return 0;
+}
+