Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit ac646a1a5042d03f835ac2e29ffd0c1420365f78 @b4winckler committed Feb 16, 2012
Showing with 386 additions and 0 deletions.
  1. +235 −0 src/lxbread.c
  2. +105 −0 src/map_lib.c
  3. +46 −0 src/map_lib.h
@@ -0,0 +1,235 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "map_lib.h"
+
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#define MAX_PAR 99
+
+typedef struct {
+ int begin_text, end_text;
+ int begin_data, end_data;
+ int begin_analysis, end_analysis;
+} fcs_header;
+
+static int par_mask[MAX_PAR];
+
+
+char *read_file(const char *filename, long *size)
+{
+ FILE *fp = fopen(filename, "r");
+ if (!fp)
+ return NULL;
+
+ fseek(fp, 0, SEEK_END);
+ long filesize = ftell(fp);
+ rewind(fp);
+ if (!(filesize > 0)) {
+ fclose(fp);
+ return NULL;
+ }
+
+ char *buf = malloc(filesize);
+ if (!buf) {
+ fclose(fp);
+ return NULL;
+ }
+
+ long actual = fread(buf, 1, filesize, fp);
+ fclose(fp);
+
+ if (actual != filesize) {
+ free(buf);
+ fclose(fp);
+ return NULL;
+ }
+
+ if (size)
+ *size = filesize;
+
+ return buf;
+}
+
+const char *parameter_key(int n, char type)
+{
+ static char buf[6]; // max 5 chars and null
+ if (n < 0 || n >= MAX_PAR)
+ return "";
+
+ sprintf(buf, "$P%d%c", n+1, type);
+ return buf;
+}
+
+void init_parameter_mask(map_t txt)
+{
+ memset(par_mask, 0, MAX_PAR*sizeof(par_mask[0]));
+
+ int npar = map_get_int(txt, "$PAR");
+ for (int i = 0; i < npar; ++i) {
+ const char *key = parameter_key(i, 'R');
+ par_mask[i] = map_get_int(txt, key);
+ if (par_mask[i] > 0)
+ --par_mask[i];
+ }
+}
+
+int parameter_mask(int n)
+{
+ return n >= 0 && n < MAX_PAR ? par_mask[n] : 0;
+}
+
+int parse_header(const char *data, long size, fcs_header *hdr)
+{
+ if (!hdr) return FALSE;
+
+ if (size < 58) {
+ fprintf(stderr, "data too small (%lu)\n", size);
+ return FALSE;
+ }
+
+ if (0 != strncmp(data, "FCS3.0 ", 10)) {
+ fprintf(stderr, "bad magic\n");
+ return FALSE;
+ }
+
+ int ok = TRUE;
+ ok &= sscanf(&data[10], "%8d", &hdr->begin_text);
+ ok &= sscanf(&data[18], "%8d", &hdr->end_text);
+ ok &= sscanf(&data[26], "%8d", &hdr->begin_data);
+ ok &= sscanf(&data[34], "%8d", &hdr->end_data);
+ ok &= sscanf(&data[42], "%8d", &hdr->begin_analysis);
+ ok &= sscanf(&data[50], "%8d", &hdr->end_analysis);
+
+ if (!ok)
+ fprintf(stderr, "segment offset parse failed\n");
+
+ return ok;
+}
+
+map_t parse_text(const char *text, long size)
+{
+ assert(size > 1);
+
+ map_t m = map_create();
+ char *sep = strndup(text, 1);
+ char *data = strndup(text+1, size-1);
+
+ char *p = data;
+ for (;;) {
+ char *key = strsep(&p, sep);
+ if (!key) break;
+ char *val = strsep(&p, sep);
+ if (!val) break;
+
+ map_set(m, key, val);
+ }
+
+ free(data);
+ free(sep);
+
+ return m;
+}
+
+int check_par_format(map_t txt)
+{
+ int npar = map_get_int(txt, "$PAR");
+ if (npar > MAX_PAR) {
+ fprintf(stderr, "Too many parameters: %d\n", npar);
+ return FALSE;
+ }
+
+ const char *data_type = map_get(txt, "$DATATYPE");
+ if (strcasecmp("I", data_type) != 0) {
+ fprintf(stderr, "Data is not integral ($DATATYPE=%s)\n", data_type);
+ return FALSE;
+ }
+
+ const char *mode = map_get(txt, "$MODE");
+ if (strcasecmp("L", mode) != 0) {
+ fprintf(stderr, "Data not in list format ($MODE=%s)\n", mode);
+ return FALSE;
+ }
+
+ init_parameter_mask(txt);
+
+ for (int i = 0; i < npar; ++i) {
+ const char *key = parameter_key(i, 'B');
+ int bits = map_get_int(txt, key);
+ if (bits != 32) {
+ fprintf(stderr, "Parameter %d is not 32 bits (%s=%d)\n",
+ i, key, bits);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+void print_header(map_t txt)
+{
+ int npar = map_get_int(txt, "$PAR");
+
+ printf("# ");
+ for (int i = 0; i < npar; ++i) {
+ const char *label = map_get(txt, parameter_key(i, 'S'));
+ const char *size = map_get(txt, parameter_key(i, 'R'));
+ printf("%s(%s)%s", label, size, i==npar-1 ? "\n" : ", ");
+ }
+}
+
+void print_data(const int32_t *data, long size, map_t txt)
+{
+ int ntot = map_get_int(txt, "$TOT");
+ int npar = map_get_int(txt, "$PAR");
+ int niter = 0;
+ const char *p = (const char *)data;
+ const char *end = p + size; // - npar * sizeof(int32_t) + 1;
+
+ while (p < end && niter++ < ntot) {
+ const int32_t *p32 = (const int32_t *)p;
+ for (int i = 0; i < npar; ++i, ++p32)
+ printf("%d%s", *p32 & parameter_mask(i), i==npar-1 ? "\n" : "\t");
+
+ p = (const char *)p32;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ assert(argc == 2);
+
+ long size;
+ char *buf = read_file(argv[1], &size);
+ assert(buf != NULL);
+
+ fcs_header hdr;
+ int ok = parse_header(buf, size, &hdr);
+ if (!ok) return -1;
+
+ long txt_size = hdr.end_text - hdr.begin_text;
+ assert(txt_size > 0 && hdr.begin_text > 0 && hdr.end_text <= size);
+
+ map_t txt = parse_text(buf + hdr.begin_text, txt_size);
+
+ if (!check_par_format(txt))
+ return -1;
+
+ print_header(txt);
+
+ long data_size = hdr.end_data - hdr.begin_data;
+ print_data((int32_t*)(buf + hdr.begin_data), data_size, txt);
+
+ map_free(txt);
+
+ return 0;
+}
@@ -0,0 +1,105 @@
+// map_lib
+// A simple associative-array library for C
+//
+// License: MIT / X11
+// Copyright (c) 2009 by James K. Lawless
+// jimbo@radiks.net http://www.radiks.net/~jimbo
+// http://www.mailsend-online.com
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "map_lib.h"
+
+struct map_s {
+ struct map_s *nxt;
+ char *name;
+ char *value;
+};
+
+
+map_t map_create() {
+ map_t m;
+ m=(map_t)malloc(sizeof(struct map_s));
+ m->name=NULL;
+ m->value=NULL;
+ m->nxt=NULL;
+ return m;
+}
+
+
+void map_free(map_t m) {
+ if (m)
+ free(m);
+}
+
+
+void map_set(map_t m,char *name,char *value) {
+ map_t map;
+
+ if(m->name==NULL) {
+ m->name=(char *)malloc(strlen(name)+1);
+ strcpy(m->name,name);
+ m->value=(char *)malloc(strlen(value)+1);
+ strcpy(m->value,value);
+ m->nxt=NULL;
+ return;
+ }
+ for(map=m;;map=map->nxt) {
+ if(!strcasecmp(name,map->name)) {
+ if(map->value!=NULL) {
+ free(map->value);
+ map->value=(char *)malloc(strlen(value)+1);
+ strcpy(map->value,value);
+ return;
+ }
+ }
+ if(map->nxt==NULL) {
+ map->nxt=(map_t)malloc(sizeof(struct map_s));
+ map=map->nxt;
+ map->name=(char *)malloc(strlen(name)+1);
+ strcpy(map->name,name);
+ map->value=(char *)malloc(strlen(value)+1);
+ strcpy(map->value,value);
+ map->nxt=NULL;
+ return;
+ }
+ }
+}
+
+const char *map_get(map_t m, const char *name) {
+ map_t map;
+ for(map=m;map!=NULL;map=map->nxt) {
+ if(!strcasecmp(name,map->name)) {
+ return map->value;
+ }
+ }
+ return "";
+}
+
+
+int map_get_int(map_t m, const char *key)
+{
+ return atoi(map_get(m, key));
+}
@@ -0,0 +1,46 @@
+// map_lib
+// A simple associative-array library for C
+//
+// License: MIT / X11
+// Copyright (c) 2009 by James K. Lawless
+// jimbo@radiks.net http://www.radiks.net/~jimbo
+// http://www.mailsend-online.com
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+
+#ifndef MAP_LIB_H
+#define MAP_LIB_H
+
+struct map_s;
+
+typedef struct map_s *map_t;
+
+
+map_t map_create();
+void map_free(map_t m);
+void map_set(map_t m, char *key, char *value);
+const char *map_get(map_t m, const char *key);
+int map_get_int(map_t m, const char *key);
+
+#endif
+

0 comments on commit ac646a1

Please sign in to comment.