File: grap.h

package info (click to toggle)
grap 1.41-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 832 kB
  • ctags: 601
  • sloc: cpp: 3,064; yacc: 1,063; lex: 1,046; makefile: 163; sh: 153; awk: 5
file content (238 lines) | stat: -rw-r--r-- 5,940 bytes parent folder | download
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
// -*-c++-*-
#ifndef GRAP_H
#define GRAP_H
// This file is (c) 1998-2001 Ted Faber (faber@lunabase.org) see COPYRIGHT
// for the full copyright and limitations of liabilities.
#ifndef DEFINES
#define DEFINES "/usr/share/grap/grap.defines"
#endif

#ifndef STDC_HEADERS
extern "C" {
#ifndef __GNUC__
    size_t strlen(const char*);
    char *strcpy(char *, const char *);
    int strcmp(const char *, const char *);
#endif
    char *strcat(char *, const char *);
    char *strncpy(char *, const char *, const size_t);
    int strncmp(const char *, const char *, const size_t);
};
#endif

#ifndef HAVE_SNPRINTF
// This is the only signature that snprintf is called with in grap.
// It's concievable that someone could smash the stack here, but
// there's not much privlege to gain, and I'd be impressed enough if
// you could print a float that caused a stack overflow and error that
// you can break the code.
inline int snprintf(char *s, int lim, const char *fmt, double d) {
    int tot;

#ifdef SPRINTF_NOT_INT
    // For some reason some old versions of SunOS have an sprintf that
    // doesn't return an int.  In this case, we can't bounds check at all.
    
    sprintf(s,fmt,d);
    tot = lim;
#else    
    if ( (tot = sprintf(s,fmt,d)) > lim ) {
	cerr << "Bad format to internal sprintf crashed the stack" << endl;
	abort();
    }
#endif

    return tot;
}
#else
// AIX seems to have snprintf, but not prototype it..
#ifndef SNPRINTF_DECLARED
extern "C" {
    int snprintf(char *, size_t, const char *, ...);
}
#endif
#endif

using namespace std;

#include <vector>
#include <string>
#include <list>
#include <algorithm>

class DisplayString;
class line;
class coord;
class macro;
class plot;
class tick;
class grid;
class circle;
class shiftdesc;
class keyword;


#if HAVE_HASH_MAP||HAVE_EXT_HASH_MAP||HAVE_UNORDERED_MAP

#ifdef HAVE_UNORDERED_MAP
#include <unordered_map>
#define HASH_MAP unordered_map
#else
#define HASH_MAP hash_map
#ifdef HAVE_HASH_MAP
#include <hash_map>
#else
#include <ext/hash_map>
#endif
#endif

// A functor for hashing strings - it is an adapter to get to the
// standard library char * hash function.
class Strhash : public unary_function<const string&, size_t> {
private:
    HASH_SPACE::hash<const char *> h;
public:
    size_t operator()(const string& s) const {
	return h(s.c_str());
    }
};

typedef HASH_SPACE::HASH_MAP<string, double *, Strhash> doubleDictionary;
typedef HASH_SPACE::HASH_MAP<string, coord *, Strhash> coordinateDictionary;
typedef HASH_SPACE::HASH_MAP<string, line *, Strhash> lineDictionary;
typedef HASH_SPACE::HASH_MAP<string, macro *, Strhash> macroDictionary;
typedef HASH_SPACE::HASH_MAP<string, keyword, Strhash> keywordDictionary;
#else
#include <map>
typedef less<string> Strcmp;

typedef map<string, double *, Strcmp> doubleDictionary;
typedef map<string, coord *, Strcmp> coordinateDictionary;
typedef map<string, line *, Strcmp> lineDictionary;
typedef map<string, macro *, Strcmp> macroDictionary;
typedef map<string, keyword, Strcmp> keywordDictionary;
#endif

typedef list<plot *> plotSequence;
typedef vector<double> doublevec;
typedef list<double> doublelist;
typedef list<tick *> ticklist;
typedef list<grid *> gridlist;
typedef list<string *> linelist;
typedef list<string *> stringSequence;
typedef list<circle *> circleSequence;
typedef list<struct grap_buffer_state*> lexStack;
typedef list<DisplayString *> stringlist;
typedef list<shiftdesc *> shiftlist;

// number of functions taking 0,1,2 args.  The names of those
// functions are in grap_lex.l and the implementations in the
// jumptables in grap.y
const int NVF1=1;
const int NF0=2;
const int NF1=8;
const int NF2=3;

enum size { ht = 0, wid};

typedef struct {
    int op;
    double expr;
} bydesc;

// this is complex enough to need a constructor/destructor
class for_descriptor {
 public:
    double *loop_var;
    int dir;
    double limit;
    double by;
    int by_op;
    string *anything;
    for_descriptor() : 
	loop_var(0), dir(0), limit(0.0), by(0.0), by_op(0), anything(0) { }
    for_descriptor(double *lv, int d, double l, int b, int bo, string *a) :
	loop_var(lv), dir(d), limit(l), by(b), by_op(bo), anything(a) { }
    ~for_descriptor() {
	if ( anything) {
	    delete anything;
	    anything = 0;
	}
    }
};

typedef enum { GFILE=1,  GMACRO, GINTERNAL } grap_input;

class grap_buffer_state {
 public:
    struct yy_buffer_state *yy;
    for_descriptor *f;
    string *name;
    int line;
    int report_start;
    grap_input type;
    int tokenpos;
    grap_buffer_state() :
	yy(0), f(0), name(0), line(0), report_start(0), type(GFILE),
	tokenpos(0) { }
    grap_buffer_state(struct yy_buffer_state *yyb, for_descriptor *fo,
		      string *n, int l, int rs, grap_input t, int tp=0) :
	yy(yyb), f(fo), name(n), line(l), report_start(rs), type(t),
	tokenpos(tp) { }
    // this does *not* call yy_delete_buffer
    ~grap_buffer_state() {
        if ( f ) {
	    delete f;
	    f = 0;
	}
	if ( name ) {
	    delete name;
	    name = 0;
	}
    }
};


extern lexStack lexstack;

// Set the coarse and fine limits for double comparisons.  COARSE comparisons
// are always within one millionth.  If fine comarisons are requested, either
// the values in limits are used or one trillionth (1e-12).
#ifdef HAVE_LIMITS
#include <limits>
#define FINE_EPSILON numeric_limits<double>::epsilon()
#define FINE_MIN_DOUBLE numeric_limits<double>::min()
#define COARSE_EPSILON		1e-6
#define COARSE_MIN_DOUBLE	1e-6
#else
#define FINE_EPSILON		1e-12
#define FINE_MIN_DOUBLE		1e-12
#define COARSE_EPSILON		1e-6
#define COARSE_MIN_DOUBLE	1e-6
#endif

extern double epsilon;
extern double min_double;


#ifdef HAVE_RANDOM
#ifndef RANDOM_DECLARED
extern "C" {
    long random();
    void srandom(unsigned long);
}
#endif
#else 
#ifdef HAVE_RAND
#define random rand
#define srandom srand
#ifndef RAND_DECLARED
extern "C" {
    long rand();
    void srand(unsigned);
}
#endif
#endif 
#endif

#endif