]> granicus.if.org Git - postgresql/blob - src/test/regress/regress.c
Make functions static where possible, enclose unused functions in #ifdef NOT_USED.
[postgresql] / src / test / regress / regress.c
1 /*
2  * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.9 1997/08/19 21:40:56 momjian Exp $
3  */
4
5 #include <float.h>              /* faked on sunos */
6 #include <stdio.h>
7 #include <string.h>   /* for memset() */
8
9 #include <postgres.h>
10
11 #include "utils/geo_decls.h"    /* includes <math.h> */
12 #include "executor/executor.h"  /* For GetAttributeByName */
13
14 #define P_MAXDIG 12
15 #define LDELIM          '('
16 #define RDELIM          ')'
17 #define DELIM           ','
18
19 typedef void *TUPLE;
20
21 extern double *regress_dist_ptpath (Point *pt, PATH *path);
22 extern double *regress_path_dist (PATH *p1, PATH *p2);
23 extern PATH *poly2path (POLYGON *poly);
24 extern Point *interpt_pp (PATH *p1, PATH *p2);
25 extern void regress_lseg_construct (LSEG *lseg, Point *pt1, Point *pt2);
26 extern char overpaid (TUPLE tuple);
27 extern int boxarea (BOX *box);
28 extern char *reverse_c16 (char *string);
29
30 /*
31 ** Distance from a point to a path 
32 */
33  double *
34 regress_dist_ptpath(pt, path)
35     Point *pt;
36     PATH *path;
37 {
38     double *result;
39     double *tmp;
40     int i;
41     LSEG lseg;
42
43     switch (path->npts) {
44     case 0:
45         result = PALLOCTYPE(double);
46         *result = Abs((double) DBL_MAX);        /* +infinity */
47         break;
48     case 1:
49         result = point_distance(pt, &path->p[0]);
50         break;
51     default:
52         /*
53          * the distance from a point to a path is the smallest distance
54          * from the point to any of its constituent segments.
55          */
56         Assert(path->npts > 1);
57         result = PALLOCTYPE(double);
58         for (i = 0; i < path->npts - 1; ++i) {
59             regress_lseg_construct(&lseg, &path->p[i], &path->p[i+1]);
60             tmp = dist_ps(pt, &lseg);
61             if (i == 0 || *tmp < *result)
62                 *result = *tmp;
63             PFREE(tmp);
64
65         }
66         break;
67     }
68     return(result);
69 }
70
71 /* this essentially does a cartesian product of the lsegs in the
72    two paths, and finds the min distance between any two lsegs */
73  double *
74 regress_path_dist(p1, p2)
75     PATH *p1;
76     PATH *p2;
77 {
78     double *min, *tmp;
79     int i,j;
80     LSEG seg1, seg2;
81
82     regress_lseg_construct(&seg1, &p1->p[0], &p1->p[1]);
83     regress_lseg_construct(&seg2, &p2->p[0], &p2->p[1]);
84     min = lseg_distance(&seg1, &seg2);
85
86     for (i = 0; i < p1->npts - 1; i++)
87       for (j = 0; j < p2->npts - 1; j++)
88        {
89            regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
90            regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
91
92            if (*min < *(tmp = lseg_distance(&seg1, &seg2)))
93              *min = *tmp;
94            PFREE(tmp);
95        }
96
97     return(min);
98 }
99
100  PATH *
101 poly2path(poly)
102     POLYGON *poly;
103 {
104     int i;
105     char *output = (char *)PALLOC(2*(P_MAXDIG + 1)*poly->npts + 64);
106     char buf[2*(P_MAXDIG)+20];
107
108     sprintf(output, "(1, %*d", P_MAXDIG, poly->npts);
109
110     for (i=0; i<poly->npts; i++)
111      {
112          sprintf(buf, ",%*g,%*g", P_MAXDIG, poly->p[i].x, P_MAXDIG, poly->p[i].y);
113          strcat(output, buf);
114      }
115
116     sprintf(buf, "%c", RDELIM);
117     strcat(output, buf);
118     return(path_in(output));
119 }
120
121 /* return the point where two paths intersect.  Assumes that they do. */
122  Point *
123 interpt_pp(p1,p2)
124     PATH *p1;
125     PATH *p2;
126 {
127         
128     Point *retval;
129     int i,j;
130     LSEG seg1, seg2;
131 #if FALSE
132     LINE *ln;
133 #endif
134     bool found;  /* We've found the intersection */
135
136     found = false;  /* Haven't found it yet */
137
138     for (i = 0; i < p1->npts - 1 && !found; i++)
139       for (j = 0; j < p2->npts - 1 && !found; j++)
140        {
141            regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
142            regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
143            if (lseg_intersect(&seg1, &seg2)) found = true;
144        }
145
146 #if FALSE
147     ln = line_construct_pp(&seg2.p[0], &seg2.p[1]);
148     retval = interpt_sl(&seg1, ln);
149 #endif
150     retval = lseg_interpt( &seg1, &seg2);
151     
152     return(retval);
153 }
154
155
156 /* like lseg_construct, but assume space already allocated */
157  void
158 regress_lseg_construct(lseg, pt1, pt2)
159     LSEG *lseg;
160     Point *pt1;
161     Point *pt2;
162 {
163     lseg->p[0].x = pt1->x;
164     lseg->p[0].y = pt1->y;
165     lseg->p[1].x = pt2->x;
166     lseg->p[1].y = pt2->y;
167     lseg->m = point_sl(pt1, pt2);
168 }
169
170
171  char overpaid(tuple)
172     TUPLE tuple;
173 {
174     bool isnull;
175     long salary;
176
177     salary = (long)GetAttributeByName(tuple, "salary", &isnull);
178     return(salary > 699);
179 }
180
181 /* New type "widget"
182  * This used to be "circle", but I added circle to builtins,
183  *  so needed to make sure the names do not collide. - tgl 97/04/21
184  */
185
186 typedef struct {
187         Point   center;
188         double  radius;
189 } WIDGET;
190
191  WIDGET *widget_in (char *str);
192  char *widget_out (WIDGET *widget);
193  int pt_in_widget (Point *point, WIDGET *widget);
194
195 #define NARGS   3
196
197  WIDGET *
198 widget_in(str)
199 char    *str;
200 {
201         char    *p, *coord[NARGS], buf2[1000];
202         int     i;
203         WIDGET  *result;
204
205         if (str == NULL)
206                 return(NULL);
207         for (i = 0, p = str; *p && i < NARGS && *p != RDELIM; p++)
208                 if (*p == ',' || (*p == LDELIM && !i))
209                         coord[i++] = p + 1;
210         if (i < NARGS - 1)
211                 return(NULL);
212         result = (WIDGET *) palloc(sizeof(WIDGET));
213         result->center.x = atof(coord[0]);
214         result->center.y = atof(coord[1]);
215         result->radius = atof(coord[2]);
216
217         sprintf(buf2, "widget_in: read (%f, %f, %f)\n", result->center.x,
218         result->center.y,result->radius);
219         return(result);
220 }
221
222  char *
223 widget_out(widget)
224     WIDGET      *widget;
225 {
226     char        *result;
227
228     if (widget == NULL)
229         return(NULL);
230
231     result = (char *) palloc(60);
232     sprintf(result, "(%g,%g,%g)",
233                    widget->center.x, widget->center.y, widget->radius);
234     return(result);
235 }
236
237  int
238 pt_in_widget(point, widget)
239         Point   *point;
240         WIDGET  *widget;
241 {
242         extern double   point_dt();
243
244         return( point_dt(point, &widget->center) < widget->radius );
245 }
246
247 #define ABS(X) ((X) > 0 ? (X) : -(X))
248
249  int
250 boxarea(box)
251
252 BOX *box;
253
254 {
255         int width, height;
256
257         width  = ABS(box->high.x - box->low.x);
258         height = ABS(box->high.y - box->low.y);
259         return (width * height);
260 }
261
262  char *
263 reverse_c16(string)
264     char *string;
265 {
266     register i;
267     int len;
268     char *new_string;
269
270     if (!(new_string = palloc(16))) {
271         fprintf(stderr, "reverse_c16: palloc failed\n");
272         return(NULL);
273     }
274     memset(new_string, 0, 16);
275     for (i = 0; i < 16 && string[i]; ++i)
276         ;
277     if (i == 16 || !string[i])
278         --i;
279     len = i;
280     for (; i >= 0; --i)
281         new_string[len-i] = string[i];
282     return(new_string);
283 }