summaryrefslogtreecommitdiff
path: root/tables.c
diff options
context:
space:
mode:
authorJohn Millaway <john43@users.sourceforge.net>2002-08-21 01:54:20 +0000
committerJohn Millaway <john43@users.sourceforge.net>2002-08-21 01:54:20 +0000
commit85c40a215fb57e3e29fa744e558f79b096dc61fb (patch)
tree3bbf86d937a11c37d1b97dc725a6c43cd6634f25 /tables.c
parent7113eb4115e0c04f9978be4fd89f9baf218efbc7 (diff)
More work on tables.
Diffstat (limited to 'tables.c')
-rw-r--r--tables.c263
1 files changed, 186 insertions, 77 deletions
diff --git a/tables.c b/tables.c
index 0ebf84f..5178f87 100644
--- a/tables.c
+++ b/tables.c
@@ -36,99 +36,208 @@
#include "flexdef.h"
#define yypad64(n) ((8-((n)%8))%8)
+#define TFLAGS2BYTES(flags)\
+ (((flags) & YYT_DATA8)\
+ ? sizeof(int8_t)\
+ :(((flags) & YYT_DATA16)\
+ ? sizeof(int16_t)\
+ :sizeof(int32_t)))
+
+int yytbl_fwrite32 (FILE * out, uint32_t v);
+int yytbl_fwrite16 (FILE * out, uint16_t v);
+int yytbl_fwrite8 (FILE * out, uint8_t v);
+
+void yytbl_hdr_init (struct yytbl_hdr *th, const char *version_str, const char *name)
+{
+ memset (th, 0, sizeof (struct yytbl_hdr));
+
+ th->th_magic = 0xF13C57B1;
+ th->th_hsize = yypad64 (20 + strlen (version_str) + 1 + strlen (name) + 1);
+ th->th_ssize = 0; // Not known at this point.
+ th->th_flags = 0;
+ th->th_version = copy_string (version_str);
+ th->th_name = copy_string (name);
+}
+
+struct yytbl_data *yytbl_data_create (enum yytbl_id id)
+{
+ struct yytbl_data *td;
+
+ td = (struct yytbl_data *) flex_alloc (sizeof (struct yytbl_data));
+ memset (td, 0, sizeof (struct yytbl_data));
+ td->t_id = id;
+ return td;
+}
-int yytbl_fwrite32 (FILE *out, uint32_t v);
-int yytbl_fwrite16 (FILE *out, uint16_t v);
-int yytbl_fwrite8 (FILE *out, uint8_t v);
+int yytbl_hdr_fwrite (FILE * out, struct yytbl_hdr *th)
+{
+ size_t sz, rv;
+ int pad, bwritten = 0;
+
+ if (yytbl_fwrite32 (out, th->th_magic) < 0
+ || yytbl_fwrite32 (out, th->th_hsize) < 0
+ || yytbl_fwrite32 (out, th->th_ssize) < 0
+ || yytbl_fwrite16 (out, th->th_flags) < 0)
+ return -1;
+ else
+ bwritten += 3 * 4 + 2;
+
+ sz = strlen (th->th_version) + 1;
+ if ((rv = fwrite (th->th_version, 1, sz, out)) != sz)
+ return -1;
+ bwritten += rv;
+
+ sz = strlen (th->th_name) + 1;
+ if ((rv = fwrite (th->th_name, 1, sz, out)) != sz)
+ return 1;
+ bwritten += rv;
+
+ /* add padding */
+ pad = yypad64 (bwritten) - bwritten;
+ while (pad-- > 0)
+ if (yytbl_fwrite8 (out, 0) < 0)
+ return -1;
+ else
+ bwritten++;
+
+ /* Sanity check */
+ if (bwritten != th->th_hsize) {
+ /* Oops. */
+ return -1;
+ }
+
+ return bwritten;
+}
-void yytbl_hdr_init(struct yytbl_hdr *th, const char * version_str, const char *name)
+int yytbl_fwrite32 (FILE * out, uint32_t v)
{
- memset(th, 0, sizeof(struct yytbl_hdr));
-
- th->th_magic = 0xF13C57B1;
- th->th_hsize = yypad64(20 + strlen(version_str) + 1 + strlen(name)+ 1);
- th->th_ssize = 0; // Not known at this point.
- th->th_flags = 0;
- th->th_version = copy_string(version_str);
- th->th_name = copy_string(name);
+ uint32_t vnet;
+ size_t bytes, rv;
+
+ vnet = htonl (v);
+ bytes = sizeof (uint32_t);
+ rv = fwrite (&vnet, bytes, 1, out);
+ if (rv != bytes)
+ return -1;
+ return bytes;
}
-int yytbl_hdr_fwrite(FILE* out, struct yytbl_hdr * th)
+int yytbl_fwrite16 (FILE * out, uint16_t v)
{
- size_t sz,rv;
- int pad,bwritten=0;
-
- if ( yytbl_fwrite32(out, th->th_magic) < 0
- || yytbl_fwrite32(out, th->th_hsize) < 0
- || yytbl_fwrite32(out, th->th_ssize) < 0
- || yytbl_fwrite16(out, th->th_flags) < 0)
- return -1;
- else
- bwritten += 3*4 + 2;
-
- sz = strlen(th->th_version)+1;
- if ((rv=fwrite(th->th_version,1,sz,out)) != sz)
- return -1;
- bwritten += rv;
-
- sz = strlen(th->th_name)+1;
- if ((rv=fwrite(th->th_name,1,sz,out)) != sz)
- return 1;
- bwritten += rv;
-
- /* add padding */
- pad = yypad64(bwritten) - bwritten;
- while(pad-- > 0)
- if (yytbl_fwrite8(out, 0) < 0)
- return -1;
- else
- bwritten++;
-
- /* Sanity check */
- if (bwritten != th->th_hsize){
- /* Oops. */
- return -1;
- }
-
- return bwritten;
+ uint16_t vnet;
+ size_t bytes, rv;
+
+ vnet = htons (v);
+ bytes = sizeof (uint16_t);
+ rv = fwrite (&vnet, bytes, 1, out);
+ if (rv != bytes)
+ return -1;
+ return bytes;
}
-int yytbl_fwrite32(FILE *out, uint32_t v)
+int yytbl_fwrite8 (FILE * out, uint8_t v)
{
- uint32_t vnet;
- size_t bytes, rv;
-
- vnet = htonl(v);
- bytes = sizeof(uint32_t);
- rv = fwrite(&vnet,bytes,1,out);
- if( rv != bytes)
- return -1;
- return bytes;
+ size_t bytes, rv;
+
+ bytes = sizeof (uint8_t);
+ rv = fwrite (&v, bytes, 1, out);
+ if (rv != bytes)
+ return -1;
+ return bytes;
}
-int yytbl_fwrite16(FILE *out, uint16_t v)
+/* calculate the number of bytes (1,2,4) needed to hold the largest absolute value
+ * in this array. */
+static int min_int_size (void *arr, int32_t len, int sz)
{
- uint16_t vnet;
- size_t bytes, rv;
-
- vnet = htons(v);
- bytes = sizeof(uint16_t);
- rv = fwrite(&vnet,bytes,1,out);
- if( rv != bytes)
- return -1;
- return bytes;
+ int32_t curr, max = 0, i;
+
+ for (i = 0; i < len; i++) {
+ switch (sz) {
+ case 1:
+ curr = abs (((int8_t *) arr)[i]);
+ break;
+ case 2:
+ curr = abs (((int16_t *) arr)[i]);
+ break;
+ case 4:
+ curr = abs (((int32_t *) arr)[i]);
+ break;
+ default:
+ fprintf (stderr, "Illegal size (%d) in min_int_size\n", sz);
+ return 32;
+ }
+ if (curr > max)
+ max = curr;
+ }
+ if (max < INT8_MAX)
+ return sizeof (int8_t);
+ else if (max < INT16_MAX)
+ return sizeof (int16_t);
+ else
+ return sizeof (int32_t);
}
-int yytbl_fwrite8(FILE *out, uint8_t v)
+
+/* extract data element [i][j] from int array data tables. */
+static int32_t yytbl_data_geti (const struct yytbl_data *tbl, int i, int j)
{
- size_t bytes, rv;
-
- bytes = sizeof(uint8_t);
- rv = fwrite(&v,bytes,1,out);
- if( rv != bytes)
- return -1;
- return bytes;
+ /* TODO */
+ return 0;
}
+/* Transform data to smallest possible of (int32, int16, int8) */
+void yytbl_data_compress (struct yytbl_data *tbl)
+{
+ int32_t i, sz;
+ void *newdata = 0;
+
+ if (tbl->t_id != YYT_ID_TRANSITION && tbl->t_id != YYT_ID_START_STATE_LIST) {
+ if (tbl->t_hilen == 0) {
+ /* Data is a single-dimensional array of ints */
+ sz = min_int_size (tbl->t_data, tbl->t_lolen, TFLAGS2BYTES (tbl->t_flags));
+ if (sz == TFLAGS2BYTES (tbl->t_flags))
+ /* No change in this table needed. */
+ return;
+
+ if (sz > TFLAGS2BYTES (tbl->t_flags)) {
+ /* TODO: ERROR. The code is wrong somewhere. */
+ return;
+ }
+
+ newdata = flex_alloc (sz * tbl->t_lolen);
+ for (i = 0; i < tbl->t_lolen; i++) {
+ int32_t n;
+
+ n = yytbl_data_geti (tbl, 0, i);
+ switch (sz) {
+ case sizeof (int8_t):
+ ((int8_t *) newdata)[i] = (int8_t) n;
+ break;
+ case sizeof (int16_t):
+ ((int16_t *) newdata)[i] = (int16_t) n;
+ break;
+ case sizeof (int32_t):
+ ((int32_t *) newdata)[i] = (int32_t) n;
+ break;
+ default: /* TODO: ERROR: unknown 'sz' */
+ break;
+ }
+ }
+ free (tbl->t_data);
+ tbl->t_data = newdata;
+
+ }
+ else {
+ /* Data is a two-dimensional array of ints */
+ }
+ }
+ else if (tbl->t_id == YYT_ID_TRANSITION) {
+ /* Data is an array of structs */
+ }
+ else if (tbl->t_id == YYT_ID_START_STATE_LIST) {
+ /* Data is an array of pointers */
+ }
+}
/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */