FreeCalypso > hg > gsm-net-reveng
view d144/edata-input-compile.c @ 57:fe3cdbbc96f9
d144: new program atrau-parse
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 25 Sep 2024 17:45:29 +0000 |
parents | 4681ad8483d6 |
children |
line wrap: on
line source
/* * This program compiles E-data input from our handcrafting format * into the binary format that will be read by itt-ater-16. */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> #define MAX_FIELDS 8 static char *infname, *outfname; static FILE *inf, *outf; static int lineno; static char linebuf[256]; static char *fields[MAX_FIELDS]; static unsigned nfields; static uint8_t frame_nibbles[72]; static unsigned subframe_count; static int get_line() { char *cp; if (!fgets(linebuf, sizeof linebuf, inf)) return 1; lineno++; if (!index(linebuf, '\n')) { fprintf(stderr, "%s line %d: too long or missing newline\n", infname, lineno); exit(1); } nfields = 0; for (cp = linebuf; ; ) { while (isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') break; if (nfields >= MAX_FIELDS) { fprintf(stderr, "%s line %d: too many fields\n", infname, lineno); exit(1); } fields[nfields++] = cp; while (*cp && !isspace(*cp)) cp++; if (*cp) *cp++ = '\0'; } return 0; } static int get_line_nonempty() { int rc; for (;;) { rc = get_line(); if (rc) return rc; if (nfields) return 0; } } static int decode_hex_digit(c) { if (isdigit(c)) return c - '0'; else if (isupper(c)) return c - 'A' + 10; else return c - 'a' + 10; } static void bits_line() { uint8_t *op; char *cp; unsigned n; if (nfields != 2) { fprintf(stderr, "%s line %d: bits command takes one argument\n", infname, lineno); exit(1); } if (strlen(fields[1]) != 9) { fprintf(stderr, "%s line %d: bits argument has wrong length\n", infname, lineno); exit(1); } if (subframe_count >= 8) { fprintf(stderr, "%s line %d: 8 subframes already given, can't have more\n", infname, lineno); exit(1); } op = frame_nibbles + subframe_count * 9; cp = fields[1]; for (n = 0; n < 9; n++) { if (!isxdigit(*cp)) { fprintf(stderr, "%s line %d: bits argument is not valid hex\n", infname, lineno); exit(1); } *op++ = decode_hex_digit(*cp++); } subframe_count++; } static void frame_line() { uint8_t bin[38], m_bits[2]; unsigned n, i; if (nfields != 2) { fprintf(stderr, "%s line %d: frame command takes one argument\n", infname, lineno); exit(1); } for (n = 0; n < 2; n++) { switch (fields[1][n]) { case '0': m_bits[n] = 0; break; case '1': m_bits[n] = 1; break; default: bad_arg: fprintf(stderr, "%s line %d: invalid M-bits argument \"%s\"\n", infname, lineno, fields[1]); exit(1); } } if (fields[1][2]) goto bad_arg; if (subframe_count != 8) { fprintf(stderr, "%s line %d: not preceded by exactly 8 subframes\n", infname, lineno); exit(1); } bin[0] = 0xD4; bin[1] = (m_bits[0] << 1) | m_bits[1]; i = 0; for (n = 0; n < 36; n++) { bin[n+2] = (frame_nibbles[i] << 4) | frame_nibbles[i+1]; i += 2; } fwrite(bin, 1, 38, outf); subframe_count = 0; } main(argc, argv) char **argv; { int rc; if (argc != 3) { fprintf(stderr, "usage: %s input.src output.bin\n", argv[0]); exit(1); } infname = argv[1]; outfname = argv[2]; inf = fopen(infname, "r"); if (!inf) { perror(infname); exit(1); } outf = fopen(outfname, "w"); if (!outf) { perror(outfname); exit(1); } for (;;) { rc = get_line_nonempty(); if (rc) break; if (!strcasecmp(fields[0], "bits")) bits_line(); else if (!strcasecmp(fields[0], "frame")) frame_line(); else { fprintf(stderr, "%s line %d: non-understood keyword \"%s\"\n", infname, lineno, fields[0]); exit(1); } } exit(0); }