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