blob: 11c3091e17e60d849c58ea1ce378a2cd272d3714 [file] [log] [blame]
swissChili729acd52024-03-05 11:52:45 -05001/*
2 * units, a program for units conversion
3 * Copyright (C) 1996, 1997, 1999, 2000, 2001, 2014, 2017
4 * Free Software Foundation, Inc
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 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * This program was written by Adrian Mariano (adrianm@gnu.org)
21 */
22
23#include <math.h>
24#include <errno.h>
25
26/* Apparently popen and pclose require leading _ under windows */
27#if defined(_MSC_VER) || defined(__MINGW32__)
28# define popen _popen
29# define pclose _pclose
30#endif
31
32
33#ifdef NO_ISFINITE
34# if defined _WIN32 && defined _MSC_VER
35# define isfinite(x) (!_isnan(x) && _finite(x))
36# else
37# define isfinite(x) ( -DBL_MAX <= (x) && (x) <= DBL_MAX )
38# endif
39#endif
40
41#ifdef STRINGS_H
42# include <strings.h>
43#else
44# include <string.h>
45#endif
46
47#ifndef NO_STDLIB_H
48# include <stdlib.h>
49#else
50 char *malloc(), *realloc(), *getenv();
51#endif
52
53#ifndef strchr
54# ifdef NO_STRCHR
55# define strchr(a,b) index((a),(b))
56# else
57 char *strchr();
58# endif
59#endif /* !strchr */
60
61#define E_NORMAL 0
62#define E_PARSE 1
63#define E_PRODOVERFLOW 2
64#define E_REDUCE 3
65#define E_CIRCULARDEF 4
66#define E_BADSUM 5
67#define E_NOTANUMBER 6
68#define E_NOTROOT 7
69#define E_UNKNOWNUNIT 8
70#define E_FUNC 9 /* If errno is set after calling a function */
71#define E_BADFUNCTYPE 10
72#define E_BADFUNCARG 11
73#define E_NOTINDOMAIN 12
74#define E_BADFUNCDIMEN 13
75#define E_NOINVERSE 14
76#define E_PARSEMEM 15
77#define E_FUNARGDEF 16
78#define E_FILE 17
79#define E_BADFILE 18
80#define E_MEMORY 19
81#define E_BADNUM 20
82#define E_UNITEND 21
83#define E_LASTUNSET 22
84#define E_IRRATIONAL_EXPONENT 23
85#define E_BASE_NOTROOT 24
86#define E_DIMEXPONENT 25
87#define E_NOTAFUNC 26
88#define E_OVERFLOW 27
89#define E_UNDERFLOW 28
90
91extern char *errormsg[];
92
93/*
94 Data type used to store a single unit being operated on.
95
96 The numerator and denominator arrays contain lists of units
97 (strings) which are terminated by a null pointer. The special
98 string NULLUNIT is used to mark blank units that occur in the
99 middle of the list.
100*/
101
102extern char *NULLUNIT;
103
104#define MAXSUBUNITS 100 /* Size of internal unit reduction buffer */
105
106struct unittype {
107 char *numerator[MAXSUBUNITS];
108 char *denominator[MAXSUBUNITS];
109 double factor;
110};
111
112
113struct functype {
114 char *param;
115 char *def;
116 char *dimen;
117 double *domain_min, *domain_max;
118 int domain_min_open, domain_max_open;
119};
120
121struct pair {
122 double location, value;
123};
124
125struct func {
126 char *name;
127 struct functype forward;
128 struct functype inverse;
129 struct pair *table;
130 int tablelen;
131 char *tableunit;
132 struct func *next;
133 int skip_error_check; /* do not check for errors when running units -c */
134 int linenumber;
135 char *file; /* file where defined */
136};
137
138struct parseflag {
139 int oldstar; /* Does '*' have higher precedence than '/' */
140 int minusminus; /* Does '-' character give subtraction */
141};
142extern struct parseflag parserflags;
143
144extern struct unittype *parameter_value;
145extern char *function_parameter;
146
147extern int lastunitset;
148extern struct unittype lastunit;
149
150void *mymalloc(int bytes, const char *mesg);
151int hassubscript(const char *str);
152void initializeunit(struct unittype *theunit);
153void freeunit(struct unittype *theunit);
154void unitcopy(struct unittype *dest,struct unittype *src);
155int divunit(struct unittype *left, struct unittype *right);
156void invertunit(struct unittype *theunit);
157int multunit(struct unittype *left, struct unittype *right);
158int expunit(struct unittype *theunit, int power);
159int addunit(struct unittype *unita, struct unittype *unitb);
160int rootunit(struct unittype *inunit,int n);
161int unitpower(struct unittype *base, struct unittype *exponent);
162char *dupstr(const char *str);
163char *dupnstr(const char *string, int length);
164int unit2num(struct unittype *input);
165struct func *fnlookup(const char *str);
166int evalfunc(struct unittype *theunit, struct func *infunc, int inverse,
167 int allerror);
168int parseunit(struct unittype *output, const char *input, char **errstr,
169 int *errloc);
170