From 3bad90e10ee5576b46c9b0521fb1f6af527e169c Mon Sep 17 00:00:00 2001 From: Alexander Amelkin Date: Fri, 19 Mar 2021 15:12:17 +0300 Subject: [PATCH] frugen: Add an option to force ASCII encoding It is now possible to disable text encoding autodetection and force ASCII 8-bit encoding. To do so with libfru, use `fru_set_autodetect(false)`. To do so with frugen, use `frugen -A` or `frugen --ascii`. Partially resolves #11 Signed-off-by: Alexander Amelkin --- fru.c | 50 ++++++++++++++++++++++++++++++++------------------ fru.h | 3 +++ frugen.c | 10 ++++++++++ 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/fru.c b/fru.c index 17e878c..8ca4c04 100644 --- a/fru.c +++ b/fru.c @@ -37,6 +37,13 @@ #define DEBUG(f, args...) #endif +static bool autodetect = true; + +void fru_set_autodetect(bool enable) +{ + autodetect = enable; +} + /** * Strip trailing spaces */ @@ -92,10 +99,15 @@ uint8_t fru_get_typelen(int len, /**< [in] Length of the data or LEN // As we reach this point, we know the data must be text. // We will try to find the encoding that suits best. + if (autodetect) { + typelen = FRU_TYPELEN(BCDPLUS, (len + 1) / 2); // By default - the most range-restricted text type - typelen = FRU_TYPELEN(BCDPLUS, (len + 1) / 2); // By default - the most range-restricted text type - - DEBUG("Assuming BCD plus data...\n"); + DEBUG("Assuming BCD plus data...\n"); + } + else { + DEBUG("Assuming ASCII data...\n"); + typelen = FRU_TYPELEN(TEXT, len); + } // Go through the data and expand charset as needed for (i = 0; i < len; i++) { @@ -112,22 +124,24 @@ uint8_t fru_get_typelen(int len, /**< [in] Length of the data or LEN break; } - if (typelen < FRU_MAKETYPE(TEXT) - && (data[i] > '_' || data[i] < ' ')) - { // Do not reduce the range - // The data doesn't fit into 6-bit ASCII, expand to simple text. - DEBUG("[%c] Data is simple text!\n", data[i]); - typelen = FRU_TYPELEN(TEXT, len); - continue; - } + if (autodetect) { + if (typelen < FRU_MAKETYPE(TEXT) + && (data[i] > '_' || data[i] < ' ')) + { // Do not reduce the range + // The data doesn't fit into 6-bit ASCII, expand to simple text. + DEBUG("[%c] Data is simple text!\n", data[i]); + typelen = FRU_TYPELEN(TEXT, len); + continue; + } - if (typelen < FRU_MAKETYPE(ASCII_6BIT) && // Do not reduce the range - !isdigit(data[i]) && data[i] != ' ' && data[i] != '-' && data[i] != '.') - { - // The data doesn't fit into BCD plus, expand to - DEBUG("[%c] Data is 6-bit ASCII!\n", data[i]); - typelen = FRU_TYPELEN(ASCII_6BIT, FRU_6BIT_LENGTH(len)); - } + if (typelen < FRU_MAKETYPE(ASCII_6BIT) && // Do not reduce the range + !isdigit(data[i]) && data[i] != ' ' && data[i] != '-' && data[i] != '.') + { + // The data doesn't fit into BCD plus, expand to + DEBUG("[%c] Data is 6-bit ASCII!\n", data[i]); + typelen = FRU_TYPELEN(ASCII_6BIT, FRU_6BIT_LENGTH(len)); + } + } /* autodetect */ } return typelen; diff --git a/fru.h b/fru.h index cfa5b74..394898b 100644 --- a/fru.h +++ b/fru.h @@ -8,6 +8,7 @@ #ifndef __FRULIB_FRU_H__ #define __FRULIB_FRU_H__ +#include #include #include #include @@ -300,6 +301,8 @@ typedef struct { #define fru_loadfield(eafield, value) strncpy(eafield, value, FRU_FIELDMAXLEN) +void fru_set_autodetect(bool enable); + fru_chassis_area_t * fru_chassis_info(const fru_exploded_chassis_t *chassis); fru_board_area_t * fru_board_info(const fru_exploded_board_t *board); fru_product_area_t * fru_product_info(const fru_exploded_product_t *product); diff --git a/frugen.c b/frugen.c index 77265f2..a127b94 100644 --- a/frugen.c +++ b/frugen.c @@ -378,6 +378,11 @@ int main(int argc, char *argv[]) /* Mark the following '*-custom' data as binary */ { .name = "binary", .val = 'b', .has_arg = false }, + /* Disable autodetection, force ASCII encoding on standard fields, + * Detection of binary (out of ASCII range) stays in place. + */ + { .name = "ascii", .val = 'I', .has_arg = false }, + /* Set input file format to JSON */ { .name = "json", .val = 'j', .has_arg = false }, @@ -420,6 +425,8 @@ int main(int argc, char *argv[]) "Example: frugen --binary --board-custom 0012DEADBEAF\n" "\n\t\t" "There must be an even number of characters in a 'binary' argument", + ['I'] = "Disable auto-encoding on all fields, force ASCII.\n\t\t" + "Out of ASCII range data will still result in binary encoding.", ['j'] = "Set input text file format to JSON (default). Specify before '--from'", ['z'] = "Load FRU information from a text file", /* Chassis info area related options */ @@ -479,6 +486,9 @@ int main(int argc, char *argv[]) debug(2, "Next custom field will be considered binary"); cust_binary = true; break; + case 'I': // ASCII + fru_set_autodetect(false); + break; case 'v': // verbose debug_level++; debug(debug_level, "Verbosity level set to %d", debug_level);