1 /* floatio.h: low level conversion, based on floatnum. */ 2 /* 3 Copyright (C) 2007, 2008 Wolf Lammen. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License , or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; see the file COPYING. If not, write to: 17 18 The Free Software Foundation, Inc. 19 59 Temple Place, Suite 330 20 Boston, MA 02111-1307 USA. 21 22 23 You may contact the author by: 24 e-mail: ookami1 <at> gmx <dot> de 25 mail: Wolf Lammen 26 Oertzweg 45 27 22307 Hamburg 28 Germany 29 30 *************************************************************************/ 31 32 #include <core/errors.h> 33 34 #ifndef FLOATIO_H 35 # define FLOATIO_H 36 37 #define NO_DIGIT 0x7F 38 39 #define IO_BASE_ZERO 1 40 #define IO_BASE_NAN 0 41 #define IO_BASE_DEFAULT (-1) 42 43 #define IO_SIGN_PLUS 1 44 #define IO_SIGN_NONE 0 45 #define IO_SIGN_MINUS (-1) 46 #define IO_SIGN_COMPLEMENT (-2) 47 48 #define IO_FLAG_SUPPRESS_PLUS 0x001 49 #define IO_FLAG_SUPPRESS_BASETAG 0x002 50 #define IO_FLAG_SUPPRESS_CMPL 0x004 51 #define IO_FLAG_SUPPRESS_LDG_ZERO 0x008 52 #define IO_FLAG_SUPPRESS_TRL_ZERO 0x010 53 #define IO_FLAG_SUPPRESS_DOT 0x020 54 #define IO_FLAG_SUPPRESS_EXPPLUS 0x040 55 #define IO_FLAG_SUPPRESS_EXPBASE 0x080 56 #define IO_FLAG_SUPPRESS_EXPZERO 0x100 57 #define IO_FLAG_SHOW_BASE 0x200 58 #define IO_FLAG_SHOW_EXPBASE 0x400 59 60 #ifdef __cplusplus 61 extern "C"{ 62 #endif 63 64 typedef struct{ 65 int sz; 66 char* buf; 67 }t_buffer; 68 typedef t_buffer* p_buffer; 69 70 /* t_seq_desc describes the format of a sequence of digits. 71 leadingSignDigits are the count of leading zeros (or for 72 two's complement, F's, 7's or 1's), trailing0 are the number 73 of zeros at the end of the sequence and digits are the total 74 count of digits in the sequence. If a sequence contains only 75 zeros, in some contexts, they are counted as sign digits, 76 in others they are trailing zeros. 77 base is the number base the sequence is coded in (one of 2, 8, 78 10 or 16) and is reserved for callback. */ 79 typedef struct{ 80 int leadingSignDigits; 81 int trailing0; 82 int digits; 83 int base; 84 void* param; 85 } t_seq_desc; 86 typedef t_seq_desc* p_seq_desc; 87 88 /* the number of digits not being a leading sign digit or a trailing zero */ 89 int _significantdigits(p_seq_desc n); 90 91 /* sequences of digits can be encoded in various ways (ASCII, bc_num style, 92 packed and so on). In order to access a single digit, a getter has to 93 be supplied for each encoding. This is the common interface of these getters. 94 ofs is the index of the digit in the sequence, the first (most significant) 95 having an index 0. The getter should return a sign digit (mostly 0) for 96 negative indices and 0 for indices greator or equal to the length of the 97 sequence. Instances of t_getdigit usually access the param field of n to 98 find the data structure where the digits are encoded in */ 99 typedef char (*t_getdigit)(int ofs, p_seq_desc param); 100 101 /* list of tokens that are created in an output process. 102 Instead of returning a single ASCII string, all parts 103 of a number are kept in separate places, so a post-processor 104 can reorder or beautify them */ 105 typedef struct{ 106 signed char sign; 107 signed char base; 108 t_buffer intpart; 109 t_buffer fracpart; 110 int exp; 111 } t_otokens; 112 typedef t_otokens* p_otokens; 113 114 /* list of tokens that are sources in an input process. 115 Instead of using a single ASCII string, all parts 116 of a number are kept in separate places, stripped off all 117 grammar related information. The tokens need not be 0 118 terminated, as long as the token is delimited by something 119 not mistaken as a part of it. */ 120 typedef struct{ 121 signed char sign; 122 signed char base; 123 const char* intpart; 124 const char* fracpart; 125 signed char expsign; 126 unsigned exp; 127 unsigned maxdigits; 128 } t_itokens; 129 typedef t_itokens* p_itokens; 130 131 typedef struct{ 132 t_seq_desc seq; 133 t_getdigit getdigit; 134 } t_ext_seq_desc; 135 typedef t_ext_seq_desc* p_ext_seq_desc; 136 137 typedef struct{ 138 signed char sign; 139 signed char base; 140 } t_prefix; 141 typedef t_prefix* p_prefix; 142 143 typedef struct{ 144 t_prefix prefix; 145 t_ext_seq_desc intpart; 146 t_ext_seq_desc fracpart; 147 int exp; 148 } t_number_desc; 149 typedef t_number_desc* p_number_desc; 150 151 void _clearnumber(p_number_desc n); 152 153 Error str2desc(p_number_desc n, p_itokens tokens); 154 Error desc2str(p_otokens tokens, p_number_desc n, int scale); 155 Error exp2str(p_buffer dest, int exp, char base); 156 157 /*------------ additional stuff ------------------*/ 158 159 /* t_ioparams is a data structure that contains all necessary information 160 to convert an ASCII character encoded number into a t_token and vice versa. 161 Most information is grammar related like dot, basetag and so on. Others 162 like maxdigits describe general limits of floatnums. */ 163 typedef struct{ 164 signed char base; 165 signed char expbase; 166 char dot; 167 char* basetag; 168 char* expbegin; 169 char* expend; 170 char* cmpltag; 171 unsigned maxdigits; 172 } t_ioparams; 173 typedef t_ioparams* p_ioparams; 174 175 const char* basePrefix(char base); 176 Error parse(p_itokens tokens, const char** buf); 177 int cattokens(char* buf, int bufsz, p_otokens tokens, 178 signed char expbase, unsigned flags); 179 void float_stdconvert(); 180 char setioparams(p_ioparams params); 181 char delioparams(signed char base); 182 p_ioparams getioparams(signed char base); 183 signed char setdefaultbase(signed char base); 184 185 #ifdef __cplusplus 186 } 187 #endif 188 189 #endif /* FLOATIO_H */ 190