1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
TP-Link_Archer-XR500v/EN7526G_3.18Kernel_SDK/apps/public/linux-atm/qgen/first.c
2024-07-22 01:58:46 -03:00

195 lines
5.4 KiB
C
Executable File

/* first.c - Phase I, input data preprocessing */
/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */
#include <stdlib.h>
#include <stdio.h>
#include "common.h"
#include "qgen.h"
#include "file.h"
int field = 0;
int group = 0;
int offset = 0;
int varlen_fields = 0;
static unsigned char mask = 0;
static int seq = 0;
#define ALLOC(field) ({ \
if (mask & beg_mask) \
die("bit collision (%s: 0x%02X+0x%02X)",walk->id,mask,beg_mask); \
field->pos += offset; \
if (next <= 8) { \
mask |= end_mask; \
walk->jump = 0; \
} \
else { \
mask = end_mask; \
walk->jump = (next-1) >> 3; \
} \
if (walk->flush && walk->size) { \
if (!mask) die("nothing to flush (%s)",walk->id); \
walk->jump++; \
mask = 0; \
} })
static void process(FIELD *start,int defines)
{
FIELD *walk;
TAG *scan;
unsigned char beg_mask,end_mask,orig_mask;
int tmp,shift,next;
for (walk = start; walk; walk = walk->next) {
walk->field = field; /* record it even if this isn't a real field (we
need to know the first field number later in
second.c and this way we don't have to search
for it) */
if (walk->structure) {
int start_field,start_group;
start_field = field;
start_group = group;
process(walk->my_block,walk->structure->instances > 0);
if (walk->structure->instances > 1) {
walk->structure->instances = -1;
walk->structure->first_field = start_field;
walk->structure->fields = field-start_field;
walk->structure->groups = group-start_group;
}
continue;
}
walk->seq = seq++; /* number of fields, always increases */
if (*walk->id != '_') {
if (defines) to_h("#define QF_%s %d\n",walk->id,field);
to_test(" \"%s\",\n",walk->id);
field++;
}
if (mask && walk->brk)
die("mask 0x%02x at break (%s)\n",mask,walk->id);
/* compute position and adjust masks */
tmp = walk->size > 7 ? 0xff : (1 << walk->size)-1;
beg_mask = tmp << walk->pos;
tmp = 0xff & ~((1 << (8-(walk->size & 7)))-1);
if (walk->size && !tmp) tmp = 0xff;
next = walk->pos+walk->size;
shift = 8-(next & 7);
if (shift == 8) shift = 0;
end_mask = tmp >> shift;
if (debug)
printf("mask 0x%02X, beg 0x%02X, end 0x%02X, offset %d, flush %d, "
"%s\n",mask,beg_mask,end_mask,offset,walk->flush,walk->id);
/* handle values */
if (!walk->value) {
if (walk->var_len == -2) walk->var_len = varlen_fields++;
ALLOC(walk);
offset += walk->jump*8;
}
else switch (walk->value->type) {
case vt_id:
ALLOC(walk);
to_c(" q_put(q_initial,%d,%d,%s); /* %s */\n",walk->pos,
walk->size,walk->value->id,walk->id);
offset += walk->jump*8;
break;
case vt_case:
if (*walk->id != '_') {
ALLOC(walk);
offset += walk->jump*8;
#if 0 /* bad idea */
for (scan = walk->value->tags; scan; scan = scan->next)
if (scan->deflt) {
to_c(" q_put(q_initial,%d,%d,%s); "
"/* %s */\n",walk->pos,walk->size,
scan->value,walk->id);
}
#endif
}
/* fall through */
#if 0
if (*walk->id != '_') {
ALLOC(walk);
offset += walk->jump*8;
orig_mask = mask;
for (scan = walk->value->tags; scan; scan = scan->next)
{
if (scan->id && defines)
to_h("#define QG_%s %d\n",scan->id,-group-1);
scan->group = group++;
scan->pos = walk->pos;
mask = orig_mask;
to_c(" q_put(q_initial,%d,%d,%s); /* %s */\n",
walk->pos,walk->size,scan->value,walk->id);
process(scan->block,defines);
if (mask) offset += 8;
}
break;
}
#endif
/* fall through */
case vt_multi:
orig_mask = mask;
for (scan = walk->value->tags; scan; scan = scan->next) {
if (scan->id && defines)
to_h("#define QG_%s %d\n",scan->id,-group-1);
scan->group = group++;
scan->pos = walk->pos;
if (debug)
printf("| %s/%s (walk->flush = %d)\n",walk->id,
scan->value,walk->flush);
if (*walk->id != '_') mask = orig_mask;
else {
ALLOC(scan);
if (debug)
printf("| jump = %d (mask 0x%02x)\n",
walk->jump,mask);
offset += walk->jump*8;
to_c(" q_put(q_initial,%d,%d,%s); /* %s */\n",
scan->pos,walk->size,scan->value,walk->id);
}
process(scan->block,defines);
if (*walk->id != '_' && mask) die("EF129");
}
break;
case vt_length:
ALLOC(walk);
offset += walk->jump*8;
process(walk->value->block,defines);
break;
default:
abort();
}
}
}
void first(FIELD *def)
{
def->group = group++;
to_h("/*\n * Identifiers to access numbers of fields and of named\n");
to_h(" * groups (unnamed groups don't need that). Field numbers are\n");
to_h(" * zero-based. Group numbers are negative and -1-based.\n */\n\n");
to_c("static unsigned char q_initial[Q_DATA_BYTES];\n\n");
to_c("/*\n * Initialization of constant data. Could also do this in\n");
to_c(" * the translator and output the resulting byte stream.\n */\n\n");
to_c("static void q_init_global(void)\n{\n");
to_c(" memset(q_initial,0,sizeof(q_initial));\n");
to_test("static const char *fields[] = {\n");
process(def,1);
to_test(" NULL\n};\n\n");
to_c("}\n\n");
if (mask) offset += 8;
to_h("\n/*\n * Sizes of various tables which are allocated at run-time.\n");
to_h(" */\n");
to_h("\n#define Q_DATA_BYTES %d\n",offset/8);
to_h("#define Q_GROUPS %d\n",group);
to_h("#define Q_FIELDS %d\n",field);
to_h("#define Q_VARLEN_FIELDS %d\n\n",varlen_fields);
}