Hi Bhupesh, > -----Original Message----- > From: Bhupesh Sharma [mailto:bhsharma@xxxxxxxxxx] > Sent: Tuesday, March 06, 2018 7:17 PM > To: Tachibana Masaki() <mas-tachibana@xxxxxxxxxxxxx> > Cc: kexec@xxxxxxxxxxxxxxxxxxx; Hayashi Masahiko() <mas-hayashi@xxxxxxxxxxxxx> > Subject: Re: [PATCH v2 1/3] Add a new helper file 'tools.c' that provides some useful APIs > > Hello Masaki, > > On Tue, Mar 6, 2018 at 3:33 PM, Masaki Tachibana > <mas-tachibana@xxxxxxxxxxxxx> wrote: > > Hi bhupesh, > > > > Thank you for your V2 patchset. > > > > When you have introduced tools.c from crash utility, > > you have deleted a part of htol()'s error handling > > that is unnecessary for makedumpfile as follows; > > > > htol_error: > > - switch (flags & (FAULT_ON_ERROR|RETURN_ON_ERROR)) > > - { > > - case FAULT_ON_ERROR: > > - RESTART(); > > - > > - case RETURN_ON_ERROR: > > - if (errptr) > > - *errptr = TRUE; > > - break; > > - } > > - > > return BADADDR; > > } > > > > As a result of this, htol() does not refer to 3rd parameter 'errptr' > > and RETURN_ON_ERROR. > > I understand that some codes are not used on makedumpfile's tools.c. > > They may be used in the future. > > Indeed the 3rd parameter in 'htol()' is not currently needed by > makedumpfile code, but like you mentioned I earlier thought it might > be required for future compatibility some some future feature > addition. > > > However I think 'errptr' should be deleted, so I have tried modifying > > your patches as follows; > > $ diff "PATCH v2 13 Add a new helper file 'tools > > .c' that provides some useful APIs.patch.old" "PATCH v2 13 Add a new helper file > > 'tools.c' that provides some useful APIs.patch" > > 100c100 > > < +ulong htol(char *s, int flags, int *errptr); > > --- > >> +ulong htol(char *s, int flags); > > 681c681 > > < +htol(char *s, int flags, int *errptr) > > --- > >> +htol(char *s, int flags) > > > > $ diff "PATCH v2 23 arm64 Add support to read sy > > mbols like _stext from 'prockallsyms'.patch.old" "PATCH v2 23 arm64 Add support > > to read symbols like _stext from 'prockallsyms'.patch" > > 62c62 > > < @@ -177,6 +181,45 @@ get_phys_base_arm64(void) > > --- > >> @@ -177,6 +181,44 @@ get_phys_base_arm64(void) > > 94,95c94 > > < + kallsym = htol(kallsyms[0], RETURN_ON_ERROR, > > < + NULL); > > --- > >> + kallsym = htol(kallsyms[0], 0); > > > > How about this ? > > If you agree, I'll merge the modified patchset into V1.6.4. > > Yes. This seems fine to me. We can add the 3rd parameter to 'htol' > later if its needed in future. > > Please feel free to merge the modified patchset into V1.6.4 OK. I will merge the modified patchset into V1.6.4. Thanks Tachibana > > Regards, > Bhupesh > > > > >> -----Original Message----- > >> From: kexec [mailto:kexec-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of Bhupesh Sharma > >> Sent: Tuesday, March 06, 2018 2:13 AM > >> To: kexec@xxxxxxxxxxxxxxxxxxx > >> Cc: bhsharma@xxxxxxxxxx; bhupesh.linux@xxxxxxxxx > >> Subject: [PATCH v2 1/3] Add a new helper file 'tools.c' that provides some useful APIs > >> > >> This patch borrows the 'tools.c' helper file from the crash utility > >> project and adds it to the makedumpfile source code, to allow > >> some basic useful APIs to be present which can be invoked from > >> other source code files. > >> > >> 'tools.c' provides some useful APIs like 'htol' (convert > >> a string to a hexadecimal long value), etc. which can be > >> invoked by other functions (a functionality that is exposed > >> by follow-up patches). > >> > >> Signed-off-by: Bhupesh Sharma <bhsharma@xxxxxxxxxx> > >> --- > >> Makefile | 2 +- > >> common.h | 8 + > >> makedumpfile.h | 14 ++ > >> tools.c | 766 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > >> 4 files changed, 789 insertions(+), 1 deletion(-) > >> create mode 100644 tools.c > >> > >> diff --git a/Makefile b/Makefile > >> index f4b7c56b6f3d..e870b1362c95 100644 > >> --- a/Makefile > >> +++ b/Makefile > >> @@ -46,7 +46,7 @@ CFLAGS_ARCH += -m32 > >> endif > >> > >> SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h > >> -SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c > >> +SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c > >> OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART)) > >> SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c > >> arch/sparc64.c > >> OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) > >> diff --git a/common.h b/common.h > >> index 6ad3ca7b952c..6e2f657a79c7 100644 > >> --- a/common.h > >> +++ b/common.h > >> @@ -19,6 +19,8 @@ > >> #define TRUE (1) > >> #define FALSE (0) > >> #define ERROR (-1) > >> +#define UNUSED (-1) > >> +#define RETURN_ON_ERROR (0x2) > >> > >> #ifndef LONG_MAX > >> #define LONG_MAX ((long)(~0UL>>1)) > >> @@ -35,12 +37,18 @@ > >> #define round(x, y) (((x) / (y)) * (y)) > >> #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) > >> > >> +#define NUM_HEX (0x1) > >> +#define NUM_DEC (0x2) > >> +#define NUM_EXPR (0x4) > >> +#define NUM_ANY (NUM_HEX|NUM_DEC|NUM_EXPR) > >> + > >> /* > >> * Incorrect address > >> */ > >> #define NOT_MEMMAP_ADDR (0x0) > >> #define NOT_KV_ADDR (0x0) > >> #define NOT_PADDR (ULONGLONG_MAX) > >> +#define BADADDR ((ulong)(-1)) > >> > >> #endif /* COMMON_H */ > >> > >> diff --git a/makedumpfile.h b/makedumpfile.h > >> index 01eece231475..0ce75e29fa7f 100644 > >> --- a/makedumpfile.h > >> +++ b/makedumpfile.h > >> @@ -237,6 +237,9 @@ isAnon(unsigned long mapping) > >> #define MIN_ELF_HEADER_SIZE \ > >> MAX(MIN_ELF32_HEADER_SIZE, MIN_ELF64_HEADER_SIZE) > >> static inline int string_exists(char *s) { return (s ? TRUE : FALSE); } > >> +#define STREQ(A, B) (string_exists((char *)A) && \ > >> + string_exists((char *)B) && \ > >> + (strcmp((char *)(A), (char *)(B)) == 0)) > >> #define STRNEQ(A, B)(string_exists((char *)(A)) && \ > >> string_exists((char *)(B)) && \ > >> (strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0)) > >> @@ -2319,4 +2322,15 @@ int prepare_splitblock_table(void); > >> int initialize_zlib(z_stream *stream, int level); > >> int finalize_zlib(z_stream *stream); > >> > >> +int parse_line(char *str, char *argv[]); > >> +char *shift_string_left(char *s, int cnt); > >> +char *clean_line(char *line); > >> +char *strip_linefeeds(char *line); > >> +char *strip_beginning_whitespace(char *line); > >> +char *strip_ending_whitespace(char *line); > >> +ulong htol(char *s, int flags, int *errptr); > >> +int hexadecimal(char *s, int count); > >> +int decimal(char *s, int count); > >> +int file_exists(char *file); > >> + > >> #endif /* MAKEDUMPFILE_H */ > >> diff --git a/tools.c b/tools.c > >> new file mode 100644 > >> index 000000000000..746ffa104816 > >> --- /dev/null > >> +++ b/tools.c > >> @@ -0,0 +1,766 @@ > >> +/* tools.c - Borrowed from crash utility code > >> + * (https://github.com/crash-utility/crash) > >> + * > >> + * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. > >> + * Copyright (C) 2002-2017 David Anderson > >> + * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved. > >> + * > >> + * 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 program is distributed in the hope that it will be useful, > >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of > >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > >> + * GNU General Public License for more details. > >> + */ > >> + > >> +#include "common.h" > >> +#include "makedumpfile.h" > >> +#include <ctype.h> > >> + > >> +#define FAULT_ON_ERROR (0x1) > >> +#define RETURN_ON_ERROR (0x2) > >> +#define QUIET (0x4) > >> +#define HEX_BIAS (0x8) > >> +#define LONG_LONG (0x10) > >> +#define RETURN_PARTIAL (0x20) > >> +#define NO_DEVMEM_SWITCH (0x40) > >> + > >> +#define MAX_HEXADDR_STRLEN (16) > >> + > >> +#define FIRSTCHAR(s) (s[0]) > >> + > >> +/* > >> + * Determine whether a file exists, using the caller's stat structure if > >> + * one was passed in. > >> + */ > >> +int > >> +file_exists(char *file) > >> +{ > >> + struct stat sbuf; > >> + > >> + if (stat(file, &sbuf) == 0) > >> + return TRUE; > >> + > >> + return FALSE; > >> +} > >> + > >> +/* > >> + * Parse a line into tokens, populate the passed-in argv[] array, and > >> + * return the count of arguments found. This function modifies the > >> + * passed-string by inserting a NULL character at the end of each token. > >> + * Expressions encompassed by parentheses, and strings encompassed by > >> + * apostrophes, are collected into single tokens. > >> + */ > >> +int > >> +parse_line(char *str, char *argv[]) > >> +{ > >> + int i, j, k; > >> + int string; > >> + int expression; > >> + > >> + for (i = 0; i < MAXARGS; i++) > >> + argv[i] = NULL; > >> + > >> + clean_line(str); > >> + > >> + if (str == NULL || strlen(str) == 0) > >> + return(0); > >> + > >> + i = j = k = 0; > >> + string = expression = FALSE; > >> + > >> + /* > >> + * Special handling for when the first character is a '"'. > >> + */ > >> + if (str[0] == '"') { > >> +next: > >> + do { > >> + i++; > >> + } while ((str[i] != NULLCHAR) && (str[i] != '"')); > >> + > >> + switch (str[i]) > >> + { > >> + case NULLCHAR: > >> + argv[j] = &str[k]; > >> + return j+1; > >> + case '"': > >> + argv[j++] = &str[k+1]; > >> + str[i++] = NULLCHAR; > >> + if (str[i] == '"') { > >> + k = i; > >> + goto next; > >> + } > >> + break; > >> + } > >> + } else > >> + argv[j++] = str; > >> + > >> + while (TRUE) { > >> + if (j == MAXARGS) > >> + ERRMSG("too many arguments in string!\n"); > >> + > >> + while (str[i] != ' ' && str[i] != '\t' && str[i] != NULLCHAR) { > >> + i++; > >> + } > >> + > >> + switch (str[i]) > >> + { > >> + case ' ': > >> + case '\t': > >> + str[i++] = NULLCHAR; > >> + > >> + while (str[i] == ' ' || str[i] == '\t') { > >> + i++; > >> + } > >> + > >> + if (str[i] == '"') { > >> + str[i] = ' '; > >> + string = TRUE; > >> + i++; > >> + } > >> + > >> + if (!string && str[i] == '(') { > >> + expression = TRUE; > >> + } > >> + > >> + if (str[i] != NULLCHAR && str[i] != '\n') { > >> + argv[j++] = &str[i]; > >> + if (string) { > >> + string = FALSE; > >> + while (str[i] != '"' && str[i] != NULLCHAR) > >> + i++; > >> + if (str[i] == '"') > >> + str[i] = ' '; > >> + } > >> + if (expression) { > >> + expression = FALSE; > >> + while (str[i] != ')' && str[i] != NULLCHAR) > >> + i++; > >> + } > >> + break; > >> + } > >> + /* else fall through */ > >> + case '\n': > >> + str[i] = NULLCHAR; > >> + /* keep falling... */ > >> + case NULLCHAR: > >> + argv[j] = NULLCHAR; > >> + return(j); > >> + } > >> + } > >> +} > >> + > >> +/* > >> + * Defuse controversy re: extensions to ctype.h > >> + */ > >> +int > >> +whitespace(int c) > >> +{ > >> + return ((c == ' ') ||(c == '\t')); > >> +} > >> + > >> +int > >> +ascii(int c) > >> +{ > >> + return ((c >= 0) && (c <= 0x7f)); > >> +} > >> + > >> +/* > >> + * Strip line-ending whitespace and linefeeds. > >> + */ > >> +char * > >> +strip_line_end(char *line) > >> +{ > >> + strip_linefeeds(line); > >> + strip_ending_whitespace(line); > >> + return(line); > >> +} > >> + > >> +/* > >> + * Strip line-beginning and line-ending whitespace and linefeeds. > >> + */ > >> +char * > >> +clean_line(char *line) > >> +{ > >> + strip_beginning_whitespace(line); > >> + strip_linefeeds(line); > >> + strip_ending_whitespace(line); > >> + return(line); > >> +} > >> + > >> +/* > >> + * Strip line-ending linefeeds in a string. > >> + */ > >> +char * > >> +strip_linefeeds(char *line) > >> +{ > >> + char *p; > >> + > >> + if (line == NULL || strlen(line) == 0) > >> + return(line); > >> + > >> + p = &LASTCHAR(line); > >> + > >> + while (*p == '\n') { > >> + *p = NULLCHAR; > >> + if (--p < line) > >> + break; > >> + } > >> + > >> + return(line); > >> +} > >> + > >> +/* > >> + * Strip a specified line-ending character in a string. > >> + */ > >> +char * > >> +strip_ending_char(char *line, char c) > >> +{ > >> + char *p; > >> + > >> + if (line == NULL || strlen(line) == 0) > >> + return(line); > >> + > >> + p = &LASTCHAR(line); > >> + > >> + if (*p == c) > >> + *p = NULLCHAR; > >> + > >> + return(line); > >> +} > >> + > >> +/* > >> + * Strip a specified line-beginning character in a string. > >> + */ > >> +char * > >> +strip_beginning_char(char *line, char c) > >> +{ > >> + if (line == NULL || strlen(line) == 0) > >> + return(line); > >> + > >> + if (FIRSTCHAR(line) == c) > >> + shift_string_left(line, 1); > >> + > >> + return(line); > >> +} > >> + > >> +/* > >> + * Strip line-ending whitespace. > >> + */ > >> +char * > >> +strip_ending_whitespace(char *line) > >> +{ > >> + char *p; > >> + > >> + if (line == NULL || strlen(line) == 0) > >> + return(line); > >> + > >> + p = &LASTCHAR(line); > >> + > >> + while (*p == ' ' || *p == '\t') { > >> + *p = NULLCHAR; > >> + if (p == line) > >> + break; > >> + p--; > >> + } > >> + > >> + return(line); > >> +} > >> + > >> +/* > >> + * Strip line-beginning whitespace. > >> + */ > >> +char * > >> +strip_beginning_whitespace(char *line) > >> +{ > >> + char buf[BUFSIZE]; > >> + char *p; > >> + > >> + if (line == NULL || strlen(line) == 0) > >> + return(line); > >> + > >> + strcpy(buf, line); > >> + p = &buf[0]; > >> + while (*p == ' ' || *p == '\t') > >> + p++; > >> + strcpy(line, p); > >> + > >> + return(line); > >> +} > >> + > >> +/* > >> + * End line at first comma found. > >> + */ > >> +char * > >> +strip_comma(char *line) > >> +{ > >> + char *p; > >> + > >> + if ((p = strstr(line, ","))) > >> + *p = NULLCHAR; > >> + > >> + return(line); > >> +} > >> + > >> +/* > >> + * Strip the 0x from the beginning of a hexadecimal value string. > >> + */ > >> +char * > >> +strip_hex(char *line) > >> +{ > >> + if (STRNEQ(line, "0x")) > >> + shift_string_left(line, 2); > >> + > >> + return(line); > >> +} > >> + > >> +/* > >> + * Turn a string into upper-case. > >> + */ > >> +char * > >> +upper_case(const char *s, char *buf) > >> +{ > >> + const char *p1; > >> + char *p2; > >> + > >> + p1 = s; > >> + p2 = buf; > >> + > >> + while (*p1) { > >> + *p2 = toupper(*p1); > >> + p1++, p2++; > >> + } > >> + > >> + *p2 = NULLCHAR; > >> + > >> + return(buf); > >> +} > >> + > >> +/* > >> + * Return pointer to first non-space/tab in a string. > >> + */ > >> +char * > >> +first_nonspace(char *s) > >> +{ > >> + return(s + strspn(s, " \t")); > >> +} > >> + > >> +/* > >> + * Return pointer to first space/tab in a string. If none are found, > >> + * return a pointer to the string terminating NULL. > >> + */ > >> +char * > >> +first_space(char *s) > >> +{ > >> + return(s + strcspn(s, " \t")); > >> +} > >> + > >> +/* > >> + * Replace the first space/tab found in a string with a NULL character. > >> + */ > >> +char * > >> +null_first_space(char *s) > >> +{ > >> + char *p1; > >> + > >> + p1 = first_space(s); > >> + if (*p1) > >> + *p1 = NULLCHAR; > >> + > >> + return s; > >> +} > >> + > >> +/* > >> + * Replace any instances of the characters in string c that are found in > >> + * string s with the character passed in r. > >> + */ > >> +char * > >> +replace_string(char *s, char *c, char r) > >> +{ > >> + int i, j; > >> + > >> + for (i = 0; s[i]; i++) { > >> + for (j = 0; c[j]; j++) { > >> + if (s[i] == c[j]) > >> + s[i] = r; > >> + } > >> + } > >> + > >> + return s; > >> +} > >> + > >> +/* > >> + * Find the rightmost instance of a substring in a string. > >> + */ > >> +char * > >> +strstr_rightmost(char *s, char *lookfor) > >> +{ > >> + char *next, *last, *p; > >> + > >> + for (p = s, last = NULL; *p; p++) { > >> + if (!(next = strstr(p, lookfor))) > >> + break; > >> + last = p = next; > >> + } > >> + > >> + return last; > >> +} > >> + > >> +/* > >> + * Shifts the contents of a string to the left by cnt characters, > >> + * disposing the leftmost characters. > >> + */ > >> +char * > >> +shift_string_left(char *s, int cnt) > >> +{ > >> + int origlen; > >> + > >> + if (!cnt) > >> + return(s); > >> + > >> + origlen = strlen(s); > >> + memmove(s, s+cnt, (origlen-cnt)); > >> + *(s+(origlen-cnt)) = NULLCHAR; > >> + return(s); > >> +} > >> + > >> +/* > >> + * Prints a string verbatim, allowing strings with % signs to be displayed > >> + * without printf conversions. > >> + */ > >> +void > >> +print_verbatim(FILE *filep, char *line) > >> +{ > >> + int i; > >> + > >> + for (i = 0; i < strlen(line); i++) { > >> + fputc(line[i], filep); > >> + fflush(filep); > >> + } > >> +} > >> + > >> +char * > >> +fixup_percent(char *s) > >> +{ > >> + char *p1; > >> + > >> + if ((p1 = strstr(s, "%")) == NULL) > >> + return s; > >> + > >> + s[strlen(s)+1] = NULLCHAR; > >> + memmove(p1+1, p1, strlen(p1)); > >> + *p1 = '%'; > >> + > >> + return s; > >> +} > >> + > >> +/* > >> + * Append a two-character string to a number to make 1, 2, 3 and 4 into > >> + * 1st, 2nd, 3rd, 4th, and so on... > >> + */ > >> +char * > >> +ordinal(ulong val, char *buf) > >> +{ > >> + char *p1; > >> + > >> + sprintf(buf, "%ld", val); > >> + p1 = &buf[strlen(buf)-1]; > >> + > >> + switch (*p1) > >> + { > >> + case '1': > >> + strcat(buf, "st"); > >> + break; > >> + case '2': > >> + strcat(buf, "nd"); > >> + break; > >> + case '3': > >> + strcat(buf, "rd"); > >> + break; > >> + default: > >> + strcat(buf, "th"); > >> + break; > >> + } > >> + > >> + return buf; > >> +} > >> + > >> +/* > >> + * Determine whether a string contains only decimal characters. > >> + * If count is non-zero, limit the search to count characters. > >> + */ > >> +int > >> +decimal(char *s, int count) > >> +{ > >> + char *p; > >> + int cnt, digits; > >> + > >> + if (!count) { > >> + strip_line_end(s); > >> + cnt = 0; > >> + } else > >> + cnt = count; > >> + > >> + for (p = &s[0], digits = 0; *p; p++) { > >> + switch(*p) > >> + { > >> + case '0': > >> + case '1': > >> + case '2': > >> + case '3': > >> + case '4': > >> + case '5': > >> + case '6': > >> + case '7': > >> + case '8': > >> + case '9': > >> + digits++; > >> + case ' ': > >> + break; > >> + default: > >> + return FALSE; > >> + } > >> + > >> + if (count && (--cnt == 0)) > >> + break; > >> + } > >> + > >> + return (digits ? TRUE : FALSE); > >> +} > >> + > >> +/* > >> + * Determine whether a string contains only ASCII characters. > >> + */ > >> +int > >> +ascii_string(char *s) > >> +{ > >> + char *p; > >> + > >> + for (p = &s[0]; *p; p++) { > >> + if (!ascii(*p)) > >> + return FALSE; > >> + } > >> + > >> + return TRUE; > >> +} > >> + > >> +/* > >> + * Check whether a string contains only printable ASCII characters. > >> + */ > >> +int > >> +printable_string(char *s) > >> +{ > >> + char *p; > >> + > >> + for (p = &s[0]; *p; p++) { > >> + if (!isprint(*p)) > >> + return FALSE; > >> + } > >> + > >> + return TRUE; > >> +} > >> + > >> +/* > >> + * Convert a string to a hexadecimal long value. > >> + */ > >> +ulong > >> +htol(char *s, int flags, int *errptr) > >> +{ > >> + ulong i, j; > >> + ulong n; > >> + > >> + if (s == NULL) { > >> + if (!(flags & QUIET)) > >> + ERRMSG("received NULL string\n"); > >> + goto htol_error; > >> + } > >> + > >> + if (STRNEQ(s, "0x") || STRNEQ(s, "0X")) > >> + s += 2; > >> + > >> + if (strlen(s) > MAX_HEXADDR_STRLEN) { > >> + if (!(flags & QUIET)) > >> + ERRMSG("input string too large: \"%s\" (%d vs %d)\n", > >> + s, (int)strlen(s), (int)MAX_HEXADDR_STRLEN); > >> + goto htol_error; > >> + } > >> + > >> + for (n = i = 0; s[i] != 0; i++) { > >> + switch (s[i]) > >> + { > >> + case 'a': > >> + case 'b': > >> + case 'c': > >> + case 'd': > >> + case 'e': > >> + case 'f': > >> + j = (s[i] - 'a') + 10; > >> + break; > >> + case 'A': > >> + case 'B': > >> + case 'C': > >> + case 'D': > >> + case 'E': > >> + case 'F': > >> + j = (s[i] - 'A') + 10; > >> + break; > >> + case '1': > >> + case '2': > >> + case '3': > >> + case '4': > >> + case '5': > >> + case '6': > >> + case '7': > >> + case '8': > >> + case '9': > >> + case '0': > >> + j = s[i] - '0'; > >> + break; > >> + case 'x': > >> + case 'X': > >> + case 'h': > >> + continue; > >> + default: > >> + if (!(flags & QUIET)) > >> + ERRMSG("invalid input: \"%s\"\n", s); > >> + goto htol_error; > >> + } > >> + n = (16 * n) + j; > >> + } > >> + > >> + return(n); > >> + > >> +htol_error: > >> + return BADADDR; > >> +} > >> + > >> +/* > >> + * Determine whether a string contains only hexadecimal characters. > >> + * If count is non-zero, limit the search to count characters. > >> + */ > >> +int > >> +hexadecimal(char *s, int count) > >> +{ > >> + char *p; > >> + int cnt, digits; > >> + > >> + if (!count) { > >> + strip_line_end(s); > >> + cnt = 0; > >> + } else > >> + cnt = count; > >> + > >> + for (p = &s[0], digits = 0; *p; p++) { > >> + switch(*p) > >> + { > >> + case 'a': > >> + case 'b': > >> + case 'c': > >> + case 'd': > >> + case 'e': > >> + case 'f': > >> + case 'A': > >> + case 'B': > >> + case 'C': > >> + case 'D': > >> + case 'E': > >> + case 'F': > >> + case '1': > >> + case '2': > >> + case '3': > >> + case '4': > >> + case '5': > >> + case '6': > >> + case '7': > >> + case '8': > >> + case '9': > >> + case '0': > >> + digits++; > >> + case 'x': > >> + case 'X': > >> + break; > >> + > >> + case ' ': > >> + if (*(p+1) == NULLCHAR) > >> + break; > >> + else > >> + return FALSE; > >> + default: > >> + return FALSE; > >> + } > >> + > >> + if (count && (--cnt == 0)) > >> + break; > >> + } > >> + > >> + return (digits ? TRUE : FALSE); > >> +} > >> + > >> +/* > >> + * Determine whether a string contains only hexadecimal characters. > >> + * and cannot be construed as a decimal number. > >> + * If count is non-zero, limit the search to count characters. > >> + */ > >> +int > >> +hexadecimal_only(char *s, int count) > >> +{ > >> + char *p; > >> + int cnt, only; > >> + > >> + if (!count) { > >> + strip_line_end(s); > >> + cnt = 0; > >> + } else > >> + cnt = count; > >> + > >> + only = 0; > >> + > >> + for (p = &s[0]; *p; p++) { > >> + switch(*p) > >> + { > >> + case 'a': > >> + case 'b': > >> + case 'c': > >> + case 'd': > >> + case 'e': > >> + case 'f': > >> + case 'A': > >> + case 'B': > >> + case 'C': > >> + case 'D': > >> + case 'E': > >> + case 'F': > >> + case 'x': > >> + case 'X': > >> + only++; > >> + break; > >> + case '1': > >> + case '2': > >> + case '3': > >> + case '4': > >> + case '5': > >> + case '6': > >> + case '7': > >> + case '8': > >> + case '9': > >> + case '0': > >> + break; > >> + > >> + case ' ': > >> + if (*(p+1) == NULLCHAR) > >> + break; > >> + else > >> + return FALSE; > >> + default: > >> + return FALSE; > >> + } > >> + > >> + if (count && (--cnt == 0)) > >> + break; > >> + } > >> + > >> + return only; > >> +} > >> -- > >> 2.7.4 > >> > >> > >> _______________________________________________ > >> kexec mailing list > >> kexec@xxxxxxxxxxxxxxxxxxx > >> http://lists.infradead.org/mailman/listinfo/kexec > > > > _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec