Disable menu items not valid in current mode (Bug #499625). Clean up bitcalculating...
[gcalctool.git] / gcalctool / get.c
blob0d354b278d6f33602c97a067e7e128bd6a699b20
2 /* $Header$
4 * Copyright (c) 1987-2007 Sun Microsystems, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
22 #include <stdio.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <langinfo.h>
28 #include <locale.h>
29 #include <sys/types.h>
30 #include <sys/file.h>
31 #include <sys/param.h>
32 #include <assert.h>
33 #include <gconf/gconf-client.h>
35 #include "get.h"
36 #include "display.h"
37 #include "mp.h"
39 #define EQUAL(a, b) (strlen(a)==strlen(b)) & !strcmp(a, b)
41 /* Various string values read/written as X resources. */
43 char *Rbstr[MAXBASES] = { "BIN", "OCT", "DEC", "HEX" };
44 char *Rdstr[MAXDISPMODES] = { "ENG", "FIX", "SCI" };
45 char *Rmstr[MAXMODES] = { "BASIC", "ADVANCED", "FINANCIAL",
46 "SCIENTIFIC" };
47 char *Rtstr[MAXTRIGMODES] = { "DEG", "GRAD", "RAD" };
48 char *Rsstr[MAXSYNTAX] = { "ARITHMETIC", "ARITHMETIC_PRECEDENCE" };
50 static GConfClient *client = NULL;
53 char *
54 get_resource(char *key)
56 char key_name[MAXLINE];
57 SNPRINTF(key_name, MAXLINE, "/apps/%s/%s", v->appname, key);
58 return(gconf_client_get_string(client, key_name, NULL));
62 void
63 set_resource(char *key, char *value)
65 char key_name[MAXLINE];
66 SNPRINTF(key_name, MAXLINE, "/apps/%s/%s", v->appname, key);
67 gconf_client_set_string(client, key_name, value, NULL);
71 void
72 set_int_resource(char *key, int value)
74 char intvalue[MAXLINE];
75 SNPRINTF(intvalue, MAXLINE, "%d", value);
76 set_resource(key, intvalue);
80 void
81 set_boolean_resource(char *key, int value)
83 if (value) {
84 set_resource(key, "true");
85 } else {
86 set_resource(key, "false");
91 char *
92 convert(char *line) /* Convert .gcalctoolcf line to ascii values. */
94 static char output[MAXLINE]; /* Converted output record. */
95 int i; /* Position within input line. */
96 int len;
97 int n = 0; /* Position within output line. */
99 len = strlen(line);
100 for (i = 0; i < len; i++) {
101 if (line[i] == ' ') {
102 continue;
103 } else {
104 output[n++] = line[i];
107 output[n] = '\0';
109 return(output);
114 get_boolean_resource(char *key, int *boolval)
116 char *val, tempstr[MAXLINE];
117 int len, n;
119 if ((val = get_resource(key)) == NULL) {
120 g_free(val);
121 return(0);
123 STRNCPY(tempstr, val, MAXLINE - 1);
124 g_free(val);
125 len = strlen(tempstr);
126 for (n = 0; n < len; n++) {
127 if (isupper((int) tempstr[n])) {
128 tempstr[n] = tolower((int) tempstr[n]);
131 if (EQUAL(tempstr, "true")) {
132 *boolval = TRUE;
133 } else {
134 *boolval = FALSE;
137 return(1);
141 /* Get integer resource from database. */
144 get_int_resource(char *key, int *intval)
146 char *val;
148 if ((val = get_resource(key)) == NULL) {
149 g_free(val);
150 return(0);
152 *intval = atoi(val);
154 g_free(val);
155 return(1);
159 /* Return the radix character. For most locales, this is a period.
160 * If nl_langinfo(RADIXCHAR) returns an empty string, return ",".
163 const char *
164 get_radix()
166 char *radix;
168 setlocale(LC_NUMERIC, "");
169 if ((radix = nl_langinfo(RADIXCHAR)) != NULL) {
170 radix = g_locale_to_utf8(radix, -1, NULL, NULL, NULL);
173 if (radix == NULL || radix[0] == '\0') {
174 return(".");
175 } else {
176 return(radix);
181 /* Get a string resource from database. */
183 static int
184 get_str_resource(char *key, char *strval)
186 char *val;
187 int i, len;
189 if ((val = get_resource(key)) == NULL) {
190 g_free(val);
191 return(0);
193 STRNCPY(strval, val, MAXLINE - 1);
194 g_free(val);
195 len = strlen(strval);
196 for (i = 0; i < len; i++) {
197 if (islower((int) strval[i])) {
198 strval[i] = toupper((int) strval[i]);
202 return(1);
206 /* Return the thousands separator string. For most locales, this is a
207 * comma.
210 const char *
211 get_tsep()
213 char *tsep;
215 setlocale(LC_NUMERIC, "");
216 if ((tsep = nl_langinfo(THOUSEP)) != NULL) {
217 tsep = g_locale_to_utf8(tsep, -1, NULL, NULL, NULL);
220 if (tsep == NULL) {
221 return(",");
222 } else {
223 return(tsep);
228 void
229 read_resources() /* Read all possible resources from the database. */
231 int boolval, i, intval;
232 char key[MAXLINE], str[MAXLINE];
234 if (get_int_resource(R_ACCURACY, &intval)) {
235 v->accuracy = intval;
236 if (v->accuracy < 0 || v->accuracy > MAXACC) {
237 FPRINTF(stderr, _("%s: accuracy should be in the range 0-%d\n"),
238 v->progname, MAXACC);
239 v->accuracy = 9;
243 for (i = 0; i < MAX_REGISTERS; i++) {
244 SNPRINTF(key, MAXLINE, "register%d", i);
245 if (get_str_resource(key, str)) {
246 MPstr_to_num(str, DEC, v->MPmvals[i]);
250 if (get_str_resource(R_BASE, str)) {
251 for (i = 0; i < MAXBASES; i++) {
252 if (EQUAL(str, Rbstr[i])) {
253 break;
257 if (i == MAXBASES) {
258 FPRINTF(stderr, _("%s: base should be 2, 8, 10 or 16\n"),
259 v->progname);
260 } else {
261 v->base = (enum base_type) i;
265 if (get_str_resource(R_DISPLAY, str)) {
266 for (i = 0; i < MAXDISPMODES; i++) {
267 if (EQUAL(str, Rdstr[i])) {
268 break;
272 if (i == MAXDISPMODES) {
273 FPRINTF(stderr, _("%s: invalid display mode [%s]\n"),
274 v->progname, str);
275 } else {
276 v->dtype = (enum num_type) i;
280 if (get_str_resource(R_MODE, str)) {
281 for (i = 0; i < MAXMODES; i++) {
282 if (EQUAL(str, Rmstr[i])) {
283 break;
287 if (i == MAXMODES) {
288 FPRINTF(stderr, _("%s: invalid mode [%s]\n"), v->progname, str);
289 } else {
290 v->modetype = (enum mode_type) i;
294 if (get_str_resource(R_TRIG, str)) {
295 for (i = 0; i < MAXTRIGMODES; i++) {
296 if (EQUAL(str, Rtstr[i])) {
297 break;
301 if (i == MAXTRIGMODES) {
302 FPRINTF(stderr, _("%s: invalid trigonometric mode [%s]\n"),
303 v->progname, str);
304 } else {
305 v->ttype = (enum trig_type) i;
309 /* Set expression (arithmetic precedence) mode as default. */
310 v->syntax = EXPRS;
312 if (get_str_resource(R_SYNTAX, str)) {
313 for (i = 0; i < MAXSYNTAX; i++) {
314 if (EQUAL(str, Rsstr[i])) {
315 break;
319 if (i == MAXSYNTAX) {
320 FPRINTF(stderr, _("%s: invalid syntax mode [%s]\n"),
321 v->progname, str);
322 } else {
323 v->syntax = i;
327 if (get_boolean_resource(R_ZEROES, &boolval)) {
328 v->show_zeroes = boolval;
331 if (get_boolean_resource(R_TSEP, &boolval)) {
332 v->show_tsep = boolval;
337 void
338 read_str(char **str, char *value)
340 if (*str != NULL) {
341 (void) free(*str);
343 if (value != NULL && strlen(value)) {
344 *str = (char *) malloc((unsigned) (strlen(value) + 1));
345 STRCPY(*str, value);
346 } else {
347 *str = NULL;
352 void
353 resources_init() /* Load gconf configuration database for gcalctool. */
355 char str[MAXLINE];
357 assert(client == NULL);
358 SNPRINTF(str, MAXLINE, "/apps/%s", v->appname);
359 client = gconf_client_get_default();
360 gconf_client_add_dir(client, str, GCONF_CLIENT_PRELOAD_NONE, NULL);