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
|
/*
* units, a program for units conversion
* Copyright (C) 1996, 1997, 1999, 2000, 2001, 2014, 2017
* Free Software Foundation, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* This program was written by Adrian Mariano (adrianm@gnu.org)
*/
#include <math.h>
#include <errno.h>
/* Apparently popen and pclose require leading _ under windows */
#if defined(_MSC_VER) || defined(__MINGW32__)
# define popen _popen
# define pclose _pclose
#endif
#ifdef NO_ISFINITE
# if defined _WIN32 && defined _MSC_VER
# define isfinite(x) (!_isnan(x) && _finite(x))
# else
# define isfinite(x) ( -DBL_MAX <= (x) && (x) <= DBL_MAX )
# endif
#endif
#ifdef STRINGS_H
# include <strings.h>
#else
# include <string.h>
#endif
#ifndef NO_STDLIB_H
# include <stdlib.h>
#else
char *malloc(), *realloc(), *getenv();
#endif
#ifndef strchr
# ifdef NO_STRCHR
# define strchr(a,b) index((a),(b))
# else
char *strchr();
# endif
#endif /* !strchr */
#define E_NORMAL 0
#define E_PARSE 1
#define E_PRODOVERFLOW 2
#define E_REDUCE 3
#define E_BADSUM 4
#define E_NOTANUMBER 5
#define E_NOTROOT 6
#define E_UNKNOWNUNIT 7
#define E_FUNC 8 /* If errno is set after calling a function */
#define E_BADFUNCTYPE 9
#define E_BADFUNCARG 10
#define E_NOTINDOMAIN 11
#define E_BADFUNCDIMEN 12
#define E_NOINVERSE 13
#define E_PARSEMEM 14
#define E_FUNARGDEF 15
#define E_FILE 16
#define E_BADFILE 17
#define E_MEMORY 18
#define E_BADNUM 19
#define E_UNITEND 20
#define E_LASTUNSET 21
#define E_IRRATIONAL_EXPONENT 22
#define E_BASE_NOTROOT 23
#define E_DIMEXPONENT 24
#define E_NOTAFUNC 25
extern char *errormsg[];
/*
Data type used to store a single unit being operated on.
The numerator and denominator arrays contain lists of units
(strings) which are terminated by a null pointer. The special
string NULLUNIT is used to mark blank units that occur in the
middle of the list.
*/
extern char *NULLUNIT;
#define MAXSUBUNITS 100 /* Size of internal unit reduction buffer */
struct unittype {
char *numerator[MAXSUBUNITS];
char *denominator[MAXSUBUNITS];
double factor;
};
struct functype {
char *param;
char *def;
char *dimen;
double *domain_min, *domain_max;
int domain_min_open, domain_max_open;
};
struct pair {
double location, value;
};
struct func {
char *name;
struct functype forward;
struct functype inverse;
struct pair *table;
int tablelen;
char *tableunit;
struct func *next;
int skip_error_check; /* do not check for errors when running units -c */
int linenumber;
char *file; /* file where defined */
};
struct parseflag {
int oldstar; /* Does '*' have higher precedence than '/' */
int minusminus; /* Does '-' character give subtraction */
};
extern struct parseflag parserflags;
extern struct unittype *parameter_value;
extern char *function_parameter;
extern int lastunitset;
extern struct unittype lastunit;
void *mymalloc(int bytes, const char *mesg);
int hassubscript(const char *str);
void initializeunit(struct unittype *theunit);
void freeunit(struct unittype *theunit);
void unitcopy(struct unittype *dest,struct unittype *src);
int divunit(struct unittype *left, struct unittype *right);
void invertunit(struct unittype *theunit);
int multunit(struct unittype *left, struct unittype *right);
int expunit(struct unittype *theunit, int power);
int addunit(struct unittype *unita, struct unittype *unitb);
int rootunit(struct unittype *inunit,int n);
int unitpower(struct unittype *base, struct unittype *exponent);
char *dupstr(const char *str);
char *dupnstr(const char *string, int length);
int unit2num(struct unittype *input);
struct func *fnlookup(const char *str);
int evalfunc(struct unittype *theunit, struct func *infunc, int inverse,
int allerror);
int parseunit(struct unittype *output, const char *input, char **errstr,
int *errloc);
|