summaryrefslogtreecommitdiff
path: root/string_utils.c
blob: cbe310f12d22925a431954d785892e87cdd5e76c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/* START LIBRARY DESCRIPTION *********************************************
FLOAT.LIB
	Copyright (c) 2006, Avtech Electrosystems Ltd.

DESCRIPTION:
	Functions that deal with strings and floating point numbers.

SUPPORT LIB'S:
END DESCRIPTION **********************************************************/


#include <string.h>
#include <ctype.h>
#include <math.h>
#include <glib/gprintf.h>
#include "globals.h"
#include "string_utils.h"

void Float_To_Text(int decimal_digits,float number_in, gchar ** text_out)
{
	g_assert (*text_out == NULL);

	if (fabs(number_in)<1.1*smallest_allowed_number) {
		if (number_in<0.0) {
			*text_out = g_strdup_printf("-0.%0*d",decimal_digits,0);
		} else {
			*text_out = g_strdup_printf("0.%0*d",decimal_digits,0);
		}
		return;
	}

	*text_out = g_strdup_printf("%.*e", decimal_digits, number_in);
}


int String_trim_excess_digits(char *parameter)
{
	/* this function takes a parameter like "1.2345678901234567890" and reduces it to "1.234567" */
	/* so that atof() will work properly */

	gchar* new_string = g_strdup(parameter);
	memset(new_string, 0, strlen(parameter));

	int i;
	int j;
	int sig_digits;	/* number of significant digits so far */
	long exp_power;		/* append an exponent of this power */
	int sign;			/* is the exponent negative? */
	int start_of_exponent;	/* location of exponent */

	i=0;	/* location in input string */
	j=0;	/* location in output string */
	sig_digits=0;
	exp_power=0;
	sign=NO;

#define max_sig_dig 8

	if (!(isdigit(parameter[0]) || parameter[0]=='+' || parameter[0]=='-' || parameter[0]=='.')) {
		return OK;
	}

	/* take care of sign */
	if (parameter[0]=='+' || parameter[0]=='-') {
		new_string[j]=parameter[i];
		++i;
		++j;
	}

	/* leave in leading zeros */
	while (parameter[i]=='0') {
		new_string[j]=parameter[i];
		++i;
		++j;
	}

	/* leave in up to 8 pre-decimal significant digits */
	while (isdigit(parameter[i]) && sig_digits<max_sig_dig) {
		new_string[j]=parameter[i];
		++i;
		++j;
		++sig_digits;
	}

	/* if there are remaining digits, truncate and add exponent, and then return immediately */
	while (isdigit(parameter[i]) && sig_digits==max_sig_dig) {
		++i;
		++exp_power;
	}
	if (exp_power>0) {
		strcat(new_string+j,"e");

		//replaced itoa (non standard) with sprintf
		char temp[64];
		memset(temp, 0, 64);
		sprintf(temp, "%ld", exp_power);

		strcat(new_string,temp);

		strcpy(parameter,new_string);
		if (exp_power<38) {
			return OK;
		} else {
			return OutOfRange;
		}
	}

	/* leave in decimal point */
	if (parameter[i]=='.') {
		new_string[j]=parameter[i];
		++i;
		++j;
	}

	/* leave in post-decimal zeros if no significant digits yet */
	while (parameter[i]=='0' && sig_digits==0) {
		new_string[j]=parameter[i];
		++i;
		++j;
	}

	/* leave in up to 8 post-decimal significant digits */
	while (isdigit(parameter[i]) && sig_digits<max_sig_dig) {
		new_string[j]=parameter[i];
		++i;
		++j;
		++sig_digits;
	}

	/* skip extraneous post-decimal digits */
	while (isdigit(parameter[i]) && sig_digits==max_sig_dig) {
		++i;
	}

	if (parameter[i]=='e') {
		new_string[j]=parameter[i];
		++i;
		++j;

		if (parameter[i]=='+') {
			sign=NO;
			new_string[j]=parameter[i];
			++i;
			++j;
		} else if (parameter[i]=='-') {
			sign=YES;
			new_string[j]=parameter[i];
			++i;
			++j;
		}

		if (i<strlen(parameter) && isdigit(parameter[i])) {
			start_of_exponent=j;
			new_string[j]=parameter[i];
			++i;
			++j;
		}

		while (i<strlen(parameter) && isdigit(parameter[i])) {
			new_string[j]=parameter[i];
			++i;
			++j;
		}

		new_string[j]=0;
		exp_power=atol(new_string+start_of_exponent);

		if (exp_power>37 && sign==NO) {
			g_free(new_string);
			return OutOfRange;
		}
		if (exp_power>37 && sign==YES) {
			strcpy(new_string,"0.0");
		}
	}

	new_string[j]=0;

	strcpy(parameter,new_string);
	g_free(new_string);
	return OK;
}


/*----------------------------------------------------------------------------------------------------------*/
int String_is_it_numeric(char *parameter)
{
	/* this function takes a parameter like "1e+6" or "on" and determines if it is numeric or not */
	/* it is similar to the Parser_get_unit function */

	int i;
	int j;
	int is_number;

	is_number=0;
	i=0;


	if (isdigit(parameter[0]) || parameter[0]=='+' || parameter[0] == '-' || parameter[0] == '.') {
		for (i=1; (i < strlen(parameter)) && isdigit(parameter[i]); ++i) {}

		if (i < strlen(parameter))
			if ( parameter[i]=='.' )
				for (++i; (i < strlen(parameter)) && isdigit(parameter[i]); ++i) {}

		/* suck out spaces */
		while ( (i<strlen(parameter)) && (isspace(parameter[i])) ) {
			for(j=i; j<strlen(parameter); ++j) {
				parameter[j]=parameter[j+1];
			}
			parameter[j]=0;
		}

		if (i < strlen(parameter))
			if (	  (parameter[i]=='e' && parameter[i+1]=='-')
			                || (parameter[i]=='e' && parameter[i+1]=='+') )
				for (i+=2; (i < strlen(parameter)) && isdigit(parameter[i]); ++i) {}
			else if (parameter[i]=='e' && isdigit(parameter[i+1]) )
				for (i+=2; (i < strlen(parameter)) && isdigit(parameter[i]); ++i) {}

		/* suck out spaces */
		while ( (i<strlen(parameter)) && (isspace(parameter[i])) ) {
			for(j=i; j<strlen(parameter); ++j) {
				parameter[j]=parameter[j+1];
			}
			parameter[j]=0;
		}

		if (i = strlen(parameter)) {
			is_number=1;
			parameter[i]=0;
		}
	}

	return is_number;
}