From: Niki Date: Tue, 25 Jun 2024 14:57:16 +0000 (+0200) Subject: working version (All but BIT) X-Git-Url: http://git.nikiroo.be/?a=commitdiff_plain;h=4ae211526b4d1f0f66e5484fbea9b6ffa781820b;p=cbook.git working version (All but BIT) --- diff --git a/src/cbook/cbook_csv.c b/src/cbook/cbook_csv.c index 135922d..8bbdc13 100755 --- a/src/cbook/cbook_csv.c +++ b/src/cbook/cbook_csv.c @@ -19,6 +19,7 @@ #include #include +#include // C99 #include "cbook.h" #include "cutils/cutils.h" @@ -40,7 +41,10 @@ static char *write_field(FILE *outfile, book_t *book, line_t *field, static void one_field(FILE *outfile, book_t *book, line_t *field, char *data); // Convert EBCDIC to ASCII -static void ascii(FILE *outfile, char *ebcdic, size_t sz); +static void ascii(book_t *book, FILE *outfile, char *ebcdic, size_t sz); + +// Convert one car EBCDIC to ASCII +static char ascii_car(unsigned char ebcdic); // PUBLIC @@ -169,11 +173,39 @@ static void one_field(FILE *outfile, book_t *book, line_t *field, char *data) { break; } + if (book->debug) { + fprintf(stderr, "\n"); + for (size_t i = 0 ; i < field->bytes ; i++) { + char *type; + switch(field->type) { + case CBOOK_FMT_CHAR: type = "CHAR"; break; + case CBOOK_FMT_VARCHAR: type = "VARCHAR"; break; + case CBOOK_FMT_DECIMAL: type = "DEC"; break; + case CBOOK_FMT_UDECIMAL:type = "UDEC"; break; + case CBOOK_FMT_FIXED_BINARY: type= "BIN" ;break; + case CBOOK_FMT_UFIXED_BINARY:type= "UBIN";break; + case CBOOK_FMT_PICTURE: type = "PIC"; break; + default: type = "OTHER"; + } + unsigned char byte = (unsigned char)data[i]; + char ascii = '?'; + if (byte >= 32 && byte <= 126) + ascii = byte; + if (book->raw_ebcdic) + ascii = ascii_car(byte); + fprintf(stderr, + "%s (%s) -- Byte %zu = 0x%02X : %.3i (%c)\n", + type, field->name, i, byte, byte, ascii + ); + } + } + + switch(field->type) { case CBOOK_FMT_CHAR: fwrite("\"", 1, 1, outfile); if (book->raw_ebcdic) { - ascii(outfile, data, field->bytes); + ascii(book, outfile, data, field->bytes); fwrite(ascii_line->string, 1, ascii_line->length, outfile); } else { @@ -288,29 +320,6 @@ static void one_field(FILE *outfile, book_t *book, line_t *field, char *data) { if (str->length == dec_idx) cstring_add_car(str, '.'); } - - if (book->debug) { - if ((x1 >= 0) && (x1 <= 9)) - x1 = '0' + x1; - else - x1 = '?'; - if ((x2 >= 0) && (x2 <= 9)) - x2 = '0' + x2; - else - x2 = '?'; - if (last && field->type == CBOOK_FMT_DECIMAL) { - if (positive == 1) x2 = '+'; - else if(positive == 0) x2 = '-'; - else x2 = '!'; - } - fprintf(stderr, "%s -- Byte %zu = " - "0x%02X : %.3i (%c) -> (%c,%c)\n", - field->name, i+1, byte, byte, - (byte>=32 && byte<=126) ? byte : '?', - x1, x2 - ); - } - } if (positive) @@ -323,50 +332,84 @@ static void one_field(FILE *outfile, book_t *book, line_t *field, char *data) { free_cstring(str); break; case CBOOK_FMT_PICTURE: - fwrite(data, 1, field->bytes, outfile); - if (book->debug) { - fprintf(stderr, "\n"); - for (size_t i = 0 ; i < field->bytes ; i++) { - unsigned char byte = (unsigned char)data[i]; - fprintf(stderr, "%s -- Byte %zu = " - "0x%02X : %.3i " - "(%c)\n", - field->name, i, - byte, byte, - (byte>=32 && byte<=126) ? byte : '?' - ); - } - } + field->type = CBOOK_FMT_CHAR; + one_field(outfile, book, field, data); + field->type = CBOOK_FMT_PICTURE; break; - //TODO: the rest case CBOOK_FMT_FIXED_BINARY: case CBOOK_FMT_UFIXED_BINARY: - default: - ; - if (book->debug) { - fprintf(stderr, "\n"); - for (size_t i = 0 ; i < field->bytes ; i++) { - unsigned char byte = (unsigned char)data[i]; - fprintf(stderr, "%s -- Byte %zu = " - "0x%02X : %.3i " - "(%c)\n", - field->name, i, - byte, byte, - (byte>=32 && byte<=126) ? byte : '?' - ); + if (field->bytes > 8) { + char aa[100]; + sprintf(aa, "%zu", field->bytes); + book->err_mess = cstring_concat( + "BINARY size unsupported: ", aa + ); + break; + } + + char o[100]; + + int signbit = (field->type == CBOOK_FMT_FIXED_BINARY) + && ((unsigned char)data[0] & 0x80); + + /* + TODO: fix for positive values + + char c[8]; + uint64_t *i64 = (uint64_t *)(void*)c; + int64_t *u64 = (int64_t *)(void*)c; + + if (field->type == CBOOK_FMT_FIXED_BINARY) { + *u64 = 0; + if (signbit) { + for (int i = 0 ; i < 8 ; i++) { + c[i] = (unsigned char)0xFF; + } + } else { + *u64 = 0; } + + memcpy(c + (8 - field->bytes), data, field->bytes); + sprintf(o, "%li", *i64); + } else { + *u64 = 0; + memcpy(c + (8 - field->bytes), data, field->bytes); + sprintf(o, "%lu", *u64); + } + */ + + size_t val = 0; + for (size_t i = 0 ; i < field->bytes ; i++) { + unsigned char byte = (unsigned char)data[i]; + //if (!i && signbit) + // byte = (byte & 0x7F); + if (signbit) + byte = ~byte; + val = val * 256 + byte; + } + + if (signbit) { + val++; + fwrite(&"-", 1, 1, outfile); } + sprintf(o, "%zu", val); + + fwrite(o, 1, strlen(o), outfile); + break; + default: + ; cstring_t *tmp = new_cstring(); cstring_add(tmp, "FMT_"); cstring_add_car(tmp, '0' + field->type); cstring_add(tmp, " is not yet supported"); book->err_mess = cstring_convert(tmp); + break; } } -static void ascii(FILE *outfile, char *ebcdic, size_t sz) { +static void ascii(book_t *book, FILE *outfile, char *ebcdic, size_t sz) { /* - Professor: "So the American government went to * IBM to come up with an encryption standard, * and they came up with..." @@ -380,65 +423,83 @@ static void ascii(FILE *outfile, char *ebcdic, size_t sz) { for (size_t i = 0 ; i < sz ; i++) { unsigned char byte = ebcdic[i]; - if ((byte >= 0xF0) && (byte <= 0xF9)) { /* 0 - 9 */ - cstring_add_car(ascii_line, byte - 0xC0); - } else if ((byte >= 0xC1) && (byte <= 0xC9)) { /* A - I */ - cstring_add_car(ascii_line, byte - 0x80); - } else if ((byte >= 0xD1) && (byte <= 0xD9)) { /* J - R */ - cstring_add_car(ascii_line, byte - 0x87); - } else if ((byte >= 0xE2) && (byte <= 0xE9)) { /* S - Z */ - cstring_add_car(ascii_line, byte - 0x8F); - } else if ((byte >= 0x81) && (byte <= 0x89)) { /* a - i */ - cstring_add_car(ascii_line, byte - 0x20); - } else if ((byte >= 0x91) && (byte <= 0x99)) { /* j - r */ - cstring_add_car(ascii_line, byte - 0x27); - } else if ((byte >= 0xA2) && (byte <= 0xA9)) { /* s - z */ - cstring_add_car(ascii_line, byte - 0x2F); + byte = ascii_car(byte); + if (byte) { + if (byte == '"') // double the quotes + cstring_add_car(ascii_line, byte); + cstring_add_car(ascii_line, byte); } else { - switch(byte) { - case 0x40: cstring_add_car(ascii_line, ' '); break; - case 0x4F: cstring_add_car(ascii_line, '!'); break; - case 0x7F: // double it - cstring_add_car(ascii_line, '"'); - cstring_add_car(ascii_line, '"'); - break; - case 0x7B: cstring_add_car(ascii_line, '#'); break; - case 0x5B: cstring_add_car(ascii_line, '$'); break; - case 0x6C: cstring_add_car(ascii_line, '%'); break; - case 0x50: cstring_add_car(ascii_line, '&'); break; - case 0x7D: cstring_add_car(ascii_line, '\''); break; - case 0x4D: cstring_add_car(ascii_line, '('); break; - case 0x5D: cstring_add_car(ascii_line, ')'); break; - case 0x5C: cstring_add_car(ascii_line, '*'); break; - case 0x4E: cstring_add_car(ascii_line, '+'); break; - case 0x6B: cstring_add_car(ascii_line, ','); break; - case 0x60: cstring_add_car(ascii_line, '-'); break; - case 0x4B: cstring_add_car(ascii_line, '.'); break; - case 0x61: cstring_add_car(ascii_line, '/'); break; - case 0x7A: cstring_add_car(ascii_line, ':'); break; - case 0x5E: cstring_add_car(ascii_line, ';'); break; - case 0x4C: cstring_add_car(ascii_line, '<'); break; - case 0x7E: cstring_add_car(ascii_line, '='); break; - case 0x6E: cstring_add_car(ascii_line, '>'); break; - case 0x6F: cstring_add_car(ascii_line, '?'); break; - case 0x7C: cstring_add_car(ascii_line, '@'); break; - case 0x4A: cstring_add_car(ascii_line, '['); break; - case 0xE0: cstring_add_car(ascii_line, '\\'); break; - case 0x5A: cstring_add_car(ascii_line, ']'); break; - case 0x5F: cstring_add_car(ascii_line, '^'); break; - case 0x6D: cstring_add_car(ascii_line, '_'); break; - case 0x79: cstring_add_car(ascii_line, '`'); break; - case 0xC0: cstring_add_car(ascii_line, '{'); break; - case 0x6A: cstring_add_car(ascii_line, '|'); break; - case 0xD0: cstring_add_car(ascii_line, '}'); break; - case 0xA1: cstring_add_car(ascii_line, '~'); break; - // TODO: 0xC2A5 = 0xE0 \ (idem à 0x5C !!!) - default: - // 0x2117 = (P) or ℗ char - cstring_add_car(ascii_line, 0x21); - cstring_add_car(ascii_line, 0x17); - break; - } + // Unknown char -> 0x2117 = (P) or ℗ + cstring_add_car(ascii_line, 0x21); + cstring_add_car(ascii_line, 0x17); + + char bit[100]; + sprintf(bit, "%zu", i+1); + char byte2[3]; + sprintf(byte2, "%02X", byte); + cstring_t *tmp = new_cstring(); + cstring_add(tmp, "Bad character: "); + cstring_add(tmp, "Byte "); + cstring_add(tmp, bit); + cstring_add(tmp, " = 0x"); + cstring_add(tmp, byte2); + book->err_mess = cstring_convert(tmp); } } } + +static char ascii_car(unsigned char byte) { + if ((byte >= 0xF0) && (byte <= 0xF9)) { /* 0 - 9 */ + return(byte - 0xC0); + } else if ((byte >= 0xC1) && (byte <= 0xC9)) { /* A - I */ + return(byte - 0x80); + } else if ((byte >= 0xD1) && (byte <= 0xD9)) { /* J - R */ + return(byte - 0x87); + } else if ((byte >= 0xE2) && (byte <= 0xE9)) { /* S - Z */ + return(byte - 0x8F); + } else if ((byte >= 0x81) && (byte <= 0x89)) { /* a - i */ + return(byte - 0x20); + } else if ((byte >= 0x91) && (byte <= 0x99)) { /* j - r */ + return(byte - 0x27); + } else if ((byte >= 0xA2) && (byte <= 0xA9)) { /* s - z */ + return(byte - 0x2F); + } else { + switch(byte) { + case 0x40: return(' '); + case 0x4F: return('!'); + case 0x7F: return('"'); + case 0x7B: return('#'); + case 0x5B: return('$'); + case 0x6C: return('%'); + case 0x50: return('&'); + case 0x7D: return('\''); + case 0x4D: return('('); + case 0x5D: return(')'); + case 0x5C: return('*'); + case 0x4E: return('+'); + case 0x6B: return(','); + case 0x60: return('-'); + case 0x4B: return('.'); + case 0x61: return('/'); + case 0x7A: return(':'); + case 0x5E: return(';'); + case 0x4C: return('<'); + case 0x7E: return('='); + case 0x6E: return('>'); + case 0x6F: return('?'); + case 0x7C: return('@'); + case 0x4A: return('['); + case 0xE0: return('\\'); + case 0x5A: return(']'); + case 0x5F: return('^'); + case 0x6D: return('_'); + case 0x79: return('`'); + case 0xC0: return('{'); + case 0x6A: return('|'); + case 0xD0: return('}'); + case 0xA1: return('~'); + default: return '\0'; + } + } +} + diff --git a/src/cbook/cbook_pl1.c b/src/cbook/cbook_pl1.c index b8309c0..643358a 100755 --- a/src/cbook/cbook_pl1.c +++ b/src/cbook/cbook_pl1.c @@ -177,11 +177,17 @@ skip: } } + // Compute only the first level (reorder_lines must ensure that + // the size of sublevels are reported to higher levels) book->bytes = 0; array_loop(book->lines, line, line_t *) { book->bytes += (*line)->bytes; } + if (book->debug) { + fprintf(stderr, "Book has a size of: %zu bytes\n", book->bytes); + } + reorder_lines(book); return 1; @@ -748,22 +754,23 @@ CBOOK_FORMAT format(char *text, char **pic_fmt) { return CBOOK_FMT_ERROR; } - // Only BINARY and DECIMAL have a sign in those we support - if ((sign || unsign) - && fmt != CBOOK_FMT_DECIMAL - && fmt != CBOOK_FMT_FIXED_BINARY) { - return CBOOK_FMT_ERROR; - } - - // Manage the UNISGNED variants - if (unsign && fmt == CBOOK_FMT_DECIMAL) - fmt = CBOOK_FMT_UDECIMAL; - if (unsign && fmt == CBOOK_FMT_FIXED_BINARY) - fmt = CBOOK_FMT_UFIXED_BINARY; - prev = fmt; } + // Only BINARY and DECIMAL have a sign in those we support + if ((sign || unsign) + && fmt != CBOOK_FMT_DECIMAL + && fmt != CBOOK_FMT_FIXED_BINARY) { + return CBOOK_FMT_ERROR; + } + + // Manage the UNISGNED variants + if (unsign && fmt == CBOOK_FMT_DECIMAL) + fmt = CBOOK_FMT_UDECIMAL; + if (unsign && fmt == CBOOK_FMT_FIXED_BINARY) + fmt = CBOOK_FMT_UFIXED_BINARY; + + if (var) { if (fmt != CBOOK_FMT_CHAR) { return CBOOK_FMT_ERROR; diff --git a/src/cutils b/src/cutils index 6e1a127..0dbfba1 160000 --- a/src/cutils +++ b/src/cutils @@ -1 +1 @@ -Subproject commit 6e1a12739841bc4f7d4e5a2fc8b36d72fc0e8cb2 +Subproject commit 0dbfba1b2c91562142588c6ebf0538233eccd1ef