From ba010851fafea3da0d0655b103158f0a9efe6406 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Mon, 19 Dec 2022 21:46:52 +0000 Subject: Remove lib/x1000-installer Carrying this library is somewhat of a maintenance burden because some Rockbox APIs are mocked or duplicated in the test suite and thus need to be fixed up when refactoring. It's also unused & incomplete, so there's no good reason to keep it in tree any more. Change-Id: If39c62744b4edc0d81b1b6608ee5df69430e6581 --- lib/x1000-installer/src/xf_flashmap.c | 327 ---------------------------------- 1 file changed, 327 deletions(-) delete mode 100644 lib/x1000-installer/src/xf_flashmap.c (limited to 'lib/x1000-installer/src/xf_flashmap.c') diff --git a/lib/x1000-installer/src/xf_flashmap.c b/lib/x1000-installer/src/xf_flashmap.c deleted file mode 100644 index 972bf320ad..0000000000 --- a/lib/x1000-installer/src/xf_flashmap.c +++ /dev/null @@ -1,327 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "xf_flashmap.h" -#include "xf_error.h" -#include -#include -#include -#include - -static int xdigit_to_int(char c) -{ - if(c >= 'a' && c <= 'f') - return 10 + (c - 'a'); - if(c >= 'A' && c <= 'F') - return 10 + (c - 'A'); - if(c >= '0' && c <= '9') - return c - '0'; - return -1; -} - -static int isfilenamechar(char c) -{ - return (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - c == '$' || c == '%' || c == '\'' || c == '-' || c == '_' || - c == '@' || c == '~' || c == '`' || c == '!' || c == '(' || - c == ')' || c == '{' || c == '}' || c == '^' || c == '#' || - c == '&' || c == '+' || c == ',' || c == ';' || c == '=' || - c == '[' || c == ']' || c == '.'; -} - -int xf_map_parseline(const char* line, struct xf_map* map) -{ - enum { - s_name, - s_md5, - s_first_num, - s_file_len = s_first_num, - s_offset, - s_length, - s_done, - }; - -#define skipws() do { while(*line == ' ' || *line == '\t') ++line; } while(0) -#define nextstate() do { ++state; length = 0; ++line; skipws(); } while(0) - - int state = s_name; - int length = 0; - int digit_val; - uint32_t int_val; - uint32_t* num_ptr[3] = {&map->file_length, &map->offset, &map->length}; - bool has_md5 = true; - - skipws(); - while(*line && *line != '\n') { - switch(state) { - case s_name: - if(*line == ' ' || *line == '\t') { - nextstate(); - continue; - } else if(isfilenamechar(*line)) { - if(length == XF_MAP_NAMELEN) - return XF_E_FILENAME_TOO_LONG; - - map->name[length++] = *line++; - map->name[length] = '\0'; - continue; - } else { - return XF_E_SYNTAX_ERROR; - } - - case s_md5: - if(*line == '-') { - memset(map->md5, 0, 16); - map->file_length = 0; - has_md5 = false; - ++line; - } else { - for(int i = 0; i < 16; ++i) { - int_val = 0; - for(int j = 0; j < 2; ++j) { - digit_val = xdigit_to_int(*line++); - if(digit_val < 0) - return XF_E_SYNTAX_ERROR; - - int_val <<= 4; - int_val |= digit_val; - } - - map->md5[i] = int_val; - } - } - - if(*line == ' ' || *line == '\t') { - /* skip file length if md5 is not present */ - if(!has_md5) - ++state; - - nextstate(); - continue; - } else { - return XF_E_SYNTAX_ERROR; - } - - case s_file_len: - case s_offset: - case s_length: - int_val = 0; - - if(*line == '0') { - ++line; - if(*line == 'x' || *line == 'X') { - ++line; - while((digit_val = xdigit_to_int(*line)) >= 0) { - ++line; - - if(int_val > UINT32_MAX/16) - return XF_E_INT_OVERFLOW; - - int_val *= 16; - int_val |= digit_val; - } - } - } else if(*line >= '1' && *line <= '9') { - do { - if(int_val > UINT32_MAX/10) - return XF_E_INT_OVERFLOW; - int_val *= 10; - - digit_val = *line++ - '0'; - if(int_val > UINT32_MAX - digit_val) - return XF_E_INT_OVERFLOW; - - int_val += digit_val; - } while(*line >= '0' && *line <= '9'); - } - - *num_ptr[state - s_first_num] = int_val; - - if(*line == ' ' || *line == '\t') { - nextstate(); - continue; - } else if(state+1 == s_done && *line == '\0') { - /* end of input */ - continue; - } else { - return XF_E_SYNTAX_ERROR; - } - - case s_done: - if(isspace(*line)) { - line++; - continue; /* swallow trailing spaces, carriage return, etc */ - } else - return XF_E_SYNTAX_ERROR; - } - } - -#undef skipws -#undef nextstate - - /* one last overflow check - ensure mapped range is addressable */ - if(map->offset > UINT32_MAX - map->length) - return XF_E_INT_OVERFLOW; - - if(has_md5) - map->flags = XF_MAP_HAS_MD5 | XF_MAP_HAS_FILE_LENGTH; - else - map->flags = 0; - - return XF_E_SUCCESS; -} - -struct map_parse_args { - struct xf_map* map; - int num; - int maxnum; -}; - -int map_parse_line_cb(int n, char* buf, void* arg) -{ - (void)n; - - struct map_parse_args* args = arg; - - /* skip whitespace */ - while(*buf && isspace(*buf)) - ++buf; - - /* ignore comments and blank lines */ - if(*buf == '#' || *buf == '\0') - return 0; - - struct xf_map dummy_map; - struct xf_map* dst_map; - if(args->num < args->maxnum) - dst_map = &args->map[args->num]; - else - dst_map = &dummy_map; - - int rc = xf_map_parseline(buf, dst_map); - if(rc) - return rc; - - args->num++; - return 0; -} - -int xf_map_parse(struct xf_stream* s, struct xf_map* map, int maxnum) -{ - char buf[200]; - struct map_parse_args args; - args.map = map; - args.num = 0; - args.maxnum = maxnum; - - int rc = xf_stream_read_lines(s, buf, sizeof(buf), - map_parse_line_cb, &args); - if(rc < 0) - return rc; - - return args.num; -} - -static int xf_map_compare(const void* a, const void* b) -{ - const struct xf_map* mapA = a; - const struct xf_map* mapB = b; - - if(mapA->offset < mapB->offset) - return -1; - else if(mapA->offset == mapB->offset) - return 0; - else - return 1; -} - -int xf_map_sort(struct xf_map* map, int num) -{ - qsort(map, num, sizeof(struct xf_map), xf_map_compare); - return xf_map_validate(map, num); -} - -int xf_map_validate(const struct xf_map* map, int num) -{ - for(int i = 1; i < num; ++i) - if(map[i].offset <= map[i-1].offset) - return -1; - - for(int i = 1; i < num; ++i) - if(map[i-1].offset + map[i-1].length > map[i].offset) - return i; - - return 0; -} - -int xf_map_write(struct xf_map* map, int num, struct xf_stream* s) -{ - static const char hex[] = "0123456789abcdef"; - char buf[200]; - char md5str[33]; - int total_len = 0; - - md5str[32] = '\0'; - - for(int i = 0; i < num; ++i) { - bool has_md5 = false; - if(map->flags & XF_MAP_HAS_MD5) { - if(!(map->flags & XF_MAP_HAS_FILE_LENGTH)) - return XF_E_INVALID_PARAMETER; - - has_md5 = true; - for(int j = 0; j < 16; ++j) { - uint8_t byte = map[i].md5[j]; - md5str[2*j] = hex[(byte >> 4) & 0xf]; - md5str[2*j+1] = hex[byte & 0xf]; - } - } - - int len; - if(!has_md5) { - len = snprintf(buf, sizeof(buf), "%s - %lx %lu\n", - map[i].name, - (unsigned long)map[i].offset, - (unsigned long)map[i].length); - } else { - len = snprintf(buf, sizeof(buf), "%s %s %lu 0x%lx %lu\n", - map[i].name, md5str, - (unsigned long)map[i].file_length, - (unsigned long)map[i].offset, - (unsigned long)map[i].length); - } - - if(len < 0 || (size_t)len >= sizeof(buf)) - return XF_E_LINE_TOO_LONG; - - if(s) { - int rc = xf_stream_write(s, buf, len); - if(rc != len) - return XF_E_IO; - } - - total_len += len; - } - - return total_len; -} -- cgit v1.2.3