1/* xtom -- convert a hexadecimal string to a MINT, and return a pointer to 2 the MINT. 3 4Copyright 1991, 1994, 1995, 1996, 2000, 2001, 2002, 2005 Free Software 5Foundation, Inc. 6 7This file is part of the GNU MP Library. 8 9The GNU MP Library is free software; you can redistribute it and/or modify 10it under the terms of the GNU Lesser General Public License as published by 11the Free Software Foundation; either version 3 of the License, or (at your 12option) any later version. 13 14The GNU MP Library is distributed in the hope that it will be useful, but 15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17License for more details. 18 19You should have received a copy of the GNU Lesser General Public License 20along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 21 22#include <string.h> 23#include <ctype.h> 24#include "mp.h" 25#include "gmp.h" 26#include "gmp-impl.h" 27 28extern const unsigned char __gmp_digit_value_tab[]; 29#define digit_value __gmp_digit_value_tab 30 31MINT * 32xtom (const char *str) 33{ 34 size_t str_size; 35 char *s, *begs; 36 size_t i; 37 mp_size_t xsize; 38 int c; 39 int negative; 40 MINT *x = (MINT *) (*__gmp_allocate_func) (sizeof (MINT)); 41 TMP_DECL; 42 43 /* Skip whitespace. */ 44 do 45 c = (unsigned char) *str++; 46 while (isspace (c)); 47 48 negative = 0; 49 if (c == '-') 50 { 51 negative = 1; 52 c = (unsigned char) *str++; 53 } 54 55 if (digit_value[c] >= 16) 56 return 0; /* error if no digits */ 57 58 TMP_MARK; 59 str_size = strlen (str - 1); 60 s = begs = (char *) TMP_ALLOC (str_size + 1); 61 62 for (i = 0; i < str_size; i++) 63 { 64 if (!isspace (c)) 65 { 66 int dig = digit_value[c]; 67 if (dig >= 16) 68 { 69 TMP_FREE; 70 return 0; 71 } 72 *s++ = dig; 73 } 74 c = (unsigned char) *str++; 75 } 76 77 str_size = s - begs; 78 79 xsize = str_size / mp_bases[16].chars_per_limb + 1; 80 x->_mp_alloc = xsize; 81 x->_mp_d = (mp_ptr) (*__gmp_allocate_func) (xsize * BYTES_PER_MP_LIMB); 82 83 xsize = mpn_set_str (x->_mp_d, (unsigned char *) begs, str_size, 16); 84 x->_mp_size = negative ? -xsize : xsize; 85 86 TMP_FREE; 87 return x; 88} 89