blob: 11c3091e17e60d849c58ea1ce378a2cd272d3714 [file] [log] [blame]
/*
* 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_CIRCULARDEF 4
#define E_BADSUM 5
#define E_NOTANUMBER 6
#define E_NOTROOT 7
#define E_UNKNOWNUNIT 8
#define E_FUNC 9 /* If errno is set after calling a function */
#define E_BADFUNCTYPE 10
#define E_BADFUNCARG 11
#define E_NOTINDOMAIN 12
#define E_BADFUNCDIMEN 13
#define E_NOINVERSE 14
#define E_PARSEMEM 15
#define E_FUNARGDEF 16
#define E_FILE 17
#define E_BADFILE 18
#define E_MEMORY 19
#define E_BADNUM 20
#define E_UNITEND 21
#define E_LASTUNSET 22
#define E_IRRATIONAL_EXPONENT 23
#define E_BASE_NOTROOT 24
#define E_DIMEXPONENT 25
#define E_NOTAFUNC 26
#define E_OVERFLOW 27
#define E_UNDERFLOW 28
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);