1 /*************************************************************************
2  *
3  *N  Module VPFMISC
4  *
5  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
6  *
7  *   Purpose:
8  *P
9  *     This module contains miscellaneous routines used (potentially) by
10  *     several other VPF modules.
11  *E
12  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
13  *
14  *   Parameters:
15  *A
16  *    N/A
17  *E
18  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
19  *
20  *   History:
21  *H
22  *    Barry Michaels    April 1991                     DOS Turbo C
23  *E
24  *************************************************************************/
25 
26 #ifdef __MSDOS__
27 #  include <graphics.h>
28 #  include <alloc.h>
29 #else
30 #  ifdef __APPLE__
31 #    include <sys/types.h>
32 #    include <sys/malloc.h>
33 #  else
34 #if !defined(__OpenBSD__) && !defined( __FreeBSD__)
35 #      include <malloc.h>
36 #      include <string.h>
37 #    endif
38 #  endif
39 #endif
40 
41 
42 #include <ctype.h> /* For toupper function. */
43 
44 #include <ossim/vpfutil/vpftidx.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <stdio.h>
48 
49 #include <fcntl.h>
50 #ifdef __MSDOS__
51 #  include <sys\stat.h>
52 #  include <io.h>
53 #  include <conio.h>
54 #  include <dos.h>
55 #  include <dir.h>
56 #else
57 #  include <sys/stat.h>
58 #endif
image_builder_client_factory(cli_ctx, _)59 #include <math.h>
60 #include <errno.h>
61 #include <stdarg.h>
62 #ifdef __MSDOS__
63 #  include <process.h>
64 #  include <bios.h>
65 #  include "gui.h"
66 #endif
67 #include <ossim/vpfutil/vpfmisc.h>
68 #include <ossim/vpfutil/vpftable.h>
69 #include <ossim/vpfutil/vpfview.h>
70 
71 
72 #ifdef __MSDOS__
73   extern color_type menucolor, menubordercolor, menutextcolor;
74 #endif
75 
76 #if !defined(__MSDOS__) && !defined(_MSC_VER)
77 char* strrev(char* str)
_require_defer(cmd)78 {
79   register int i,len;
80   char *copy;
81 
82   len = strlen(str);
83   copy = (char *) malloc(sizeof(char)*(len+1));
84   (void) strcpy(copy,str);
85   for(i=0;i<len;i++)
86     str[i]=copy[(len-1)-i];
87   free(copy);
88   return str;
89 }
90 
91 char* strupr(char* str)
92 {
93   char* s = str;
94   while (*s)
95   {
96 	  *s = toupper(*s);
97 	  ++s;
98   }
99   return str;
100 }
101 #endif /* #ifndef __MSDOS__ */
_parse_image_destination(cmd, rg, destination, is_shared_image)102 
103 /*************************************************************************
104  *
105  *N  vpfmalloc
106  *
107  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
108  *
109  *   Purpose:
110  *P
111  *     This function allocates memory off of the heap and checks for
112  *     success.  If not enough memory is available, this routine will abort
113  *     the program with an error message.  Can be in graphics mode to call
114  *     this procedure, not a necessity.
115  *E
116  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
117  *
118  *   Parameters:
119  *A
120  *    size    <input> == (unsigned long) number of bytes to allocate.
121  *    return <output> == (void *) pointer to the allocated memory.
122  *E
123  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
124  *
125  *   History:
126  *H
127  *    Barry Michaels    April 1990    Original Version    DOS Turbo C
128  *    Ronald Rozensky   Sept 1991 check for no memory, graphics mode
129  *E
130  *************************************************************************/
131 void *vpfmalloc( unsigned long size )
132 {
133    void *p;
134 #ifdef __MSDOS__
135    p = farmalloc( size );
136    if (!p)
137    {
138       printf("Out of memory  %ld  %ld\n",size,farcoreleft());
139       getch();
140 
141       if (graphic_mode())
142 	 closegraph();
143       exit(1);
144    }
145 #else
146    p = malloc(size);
147    if (!p)
148    {
149      printf("Out of memory %ld\n", size);
150      exit(1);
151    }
152 #endif
153    return p;
154 }
155 #ifdef __MSDOS__
156 /*************************************************************************
157  *
process_image_template_create_namespace(cmd, namespace)158  *N  get_display_position
159  *
160  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
161  *
162  *   Purpose:
163  *P
164  *     This function finds a suitable position to display a new window on
165  *     the screen.  If the window fits, its upper left hand corner will be
166  *     the current mouse position.  If not, it will be adjusted so that it
167  *     will fit on the screen.  Should be in graphics mode to call this
168  *     function.
169  *E
170  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
171  *
172  *   Parameters:
173  *A
174  *    x     <output> == (int *) pointer to the x display position.
175  *    y     <output> == (int *) pointer to the y display position.
176  *    window <input> == (window_type) window to be displayed.
177  *E
178  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
179  *
180  *   History:
181  *H
182  *    Barry Michaels    April 1990    Original Version    DOS Turbo C
183  *E
184  *************************************************************************/
185 void get_display_position( int *x, int *y, window_type window )
186 {
187    int mbutton, delta;
188 
189    getmouseposition( x, y, &mbutton );
190    delta = window.x2 - window.x1;
191    if ((*x) + delta > getmaxx()-2)
192       (*x) = getmaxx()-delta-10;
193    if ((*x) < 2)
194       (*x) = 2;
195    delta = window.y2 - window.y1;
196    if ((*y) + delta > getmaxy()-2)
197       (*y) = getmaxy()-delta-10;
198    if ((*y) < 2)
199       (*y) = 2;
200 }
201 
202 
203 /*************************************************************************
204  *
205  *N  displayinfo
206  *
207  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
208  *
209  *   Purpose:
210  *P
211  *     This function displays an array of text strings in a
212  *     popup text window.  Must be in graphics mode to call this function.
213  *E
214  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
215  *
216  *   Parameters:
217  *A
218  *    text[] <input> == (char *) array of text strings to be displayed.
219  *    nlines <input> == (int) number of text lines.
220  *E
221  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
222  *
223  *   History:
224  *H
225  *    Barry Michaels    June 1990    Original Version    DOS Turbo C
226  *E
227  *************************************************************************/
228 void displayinfo( char *text[],
229 		  int  nlines )
230 {
231    int         i,maxw,height,x,y,pad;
232    panel_type  panel;
233 
234    arrow_cursor();
235    settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
236    maxw = 0;
237    height = 0;
238    for (i=0;i<nlines;i++) {
239       if (textwidth(text[i]) > maxw) maxw = textwidth(text[i]);
240       height = height + textheight(text[i]) + 5;
241    }
242    if (maxw < (textwidth("Continue") + 10))
243       maxw = textwidth("Continue") + 10;
244    pad = (maxw*10)/100;
245    maxw = maxw + (2*pad);
246    if (maxw > getmaxx())
247      maxw = getmaxx() - 8;
248    height = height + 2*(textheight("Continue") + 10);
249 
250    create_panel( &panel, maxw, height, menucolor, menubordercolor );
251    x = pad;
252    y = 0;
253    for (i=0;i<nlines;i++) {
254       y = y + textheight(text[i]) + 3;
255       create_label( text[i], x, y, SMALL_FONT, 4, menutextcolor, &panel );
256    }
257    y = height - (textheight("Continue") + 6);
258    x = (maxw - (textwidth("Continue") + 10))/2;
259    create_button( 27, "Continue", x, y, SMALL_FONT, 4,
260 		  menutextcolor, menucolor, menubordercolor, RELIEVED,
261 		  &panel );
262 
263    get_display_position( &x, &y, panel.window );
264 
265    display_panel( &panel, x, y );
266    i = process_panel( &panel, i );
267 
268    destroy_panel( &panel );
269    close_panel( &panel );
270 }
271 
272 
273 
274 /*************************************************************************
275  *
276  *N  displaymessage
277  *
278  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
279  *
280  *   Purpose:
281  *P
282  *     This function displays a list of text strings in a
283  *     popup text window.  The list must be NULL-terminated.  Must be in
284  *     graphics mode to call this function.
285  *E
286  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
287  *
288  *   Parameters:
289  *A
290  *    string <input> == (char *) first text string to be displayed.
291  *    ... <input> == (char *) variable list of text strings to be displayed.
292  *E
293  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
294  *
295  *   History:
296  *H
297  *    Barry Michaels    August 1991                        DOS Turbo C
298  *E
299  *************************************************************************/
300 void displaymessage( char *string, ... )
301 {
302    int         i,maxw,height,x,y,pad, nlines;
303    panel_type  panel;
304    char **text;
305    va_list arglist;
process_img_tmpl_customizer_add_namespace(cmd, namespace)306 
307    va_start(arglist,string);
308    nlines = 1;
309    while (va_arg(arglist,char *)) nlines++;
310    va_end(arglist);
311 
312    text = (char **)vpfmalloc((nlines+1)*sizeof(char *));
313    text[0] = string;
314    va_start(arglist,string);
315    for (i=1;i<nlines;i++) {
316       text[i] = va_arg(arglist,char *);
317    }
318    va_end(arglist);
319 
320    settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
process_img_tmpl_output_add_namespace(cmd, namespace)321    maxw = 0;
322    height = 0;
323    for (i=0;i<nlines;i++) {
324       if (textwidth(text[i]) > maxw) maxw = textwidth(text[i]);
325       height = height + textheight(text[i]) + 5;
326 
327    }
328    if (maxw < (textwidth("Continue") + 10))
329       maxw = textwidth("Continue") + 10;
330    pad = (maxw*10)/100;
331    maxw = maxw + (2*pad);
332    if (maxw > getmaxx())
333      maxw = getmaxx() - 8;
334    height = height + 2*(textheight("Continue") + 5) + 5;
335 
336    create_panel( &panel, maxw, height, menucolor, menubordercolor );
337    x = pad;
338    y = 0;
339    for (i=0;i<nlines;i++) {
340       y = y + textheight(text[i]) + 5;
341       create_label( text[i], x, y, SMALL_FONT, 4, menutextcolor, &panel );
342    }
343    y = height - (textheight("Continue") + 6);
344    x = (maxw - (textwidth("Continue") + 10))/2;
345    create_button( 27, "Continue", x, y, SMALL_FONT, 4,
346 		  menutextcolor, menucolor, menubordercolor, RELIEVED,
347 		  &panel );
348 
349    get_display_position( &x, &y, panel.window );
350 
351    display_panel( &panel, x, y );
352    i = process_panel( &panel, i );
353 
354    destroy_panel( &panel );
355    close_panel( &panel );
356 
357    free(text);
358 }
359 
360 
361 
362 /*************************************************************************
363  *
364  *N  display_message
365  *
366  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
367  *
368  *   Purpose:
369  *P
370  *     This function displays a one-line informational message to the
371  *     screen and waits for the user to continue.  Must be in graphics mode
372  *     to call this function.
373  *E
374  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
375  *
376  *   Parameters:
377  *A
378  *    str <input> == (char *) message to be displayed.
379  *E
create_image_template( cmd, client, resource_group_name, image_template_name, location=None, source_dict=None, scripts_list=None, destinations_lists=None, build_timeout=None, tags=None, source=None, scripts=None, checksum=None, managed_image_destinations=None, shared_image_destinations=None, no_wait=False, image_template=None, identity=None, vm_size=None, os_disk_size=None, vnet=None, subnet=None)380  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
381  *
382  *   History:
383  *H
384  *    Barry Michaels    July 1990    Original Version    DOS Turbo C
385  *E
386  *************************************************************************/
387 void display_message(char *str)
388 {
389    char **txt;
390 
391    txt = (char **)vpfmalloc( (unsigned long)(1*sizeof(char **)) );
392    txt[0] = strdup(str);
393    displayinfo( txt, 1 );
394    free(txt[0]);
395    free(txt);
396 }
397 
398 #else
399 
400 void displaymessage( char *s, ... )
401 {
402    int         i, nlines;
403    char **text;
404    va_list arglist;
405 
406    va_start(arglist,s);
407    nlines = 1;
408    while (va_arg(arglist,char *)) nlines++;
409    va_end(arglist);
410 
411    text = (char **)vpfmalloc((nlines+1)*sizeof(char *));
412    text[0] = s;
413    va_start(arglist,s);
414    for (i=1;i<nlines;i++) {
415       text[i] = va_arg(arglist,char *);
416    }
417    va_end(arglist);
418    for (i=0;i<nlines;i++) {
419        fprintf(stderr, "%s", text[i]);
420    }
421    free(text);
422 }
423 
424 void display_message(char *str)
425 {
426    fprintf(stderr, "%s", str);
427 }
428 
429 
430 #endif
431 
432 
433 /*************************************************************************
434  *
435  *N  float_to_dms
436  *
437  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
438  *
439  *   Purpose:
440  *P
441  *     This function converts a floating point lat lon coordinate to
442  *     degrees-minutes-seconds format.
443  *E
444  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
445  *
446  *   Parameters:
447  *A
448  *    coord   <input> == (double) floating point lat lon coordinate.
449  *    return <output> == (dms_type) degrees-minutes-seconds coordinate.
450  *E
451  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
452  *
453  *   History:
454  *H
455  *    Barry Michaels    April 1990    Original Version    DOS Turbo C
456  *E
457  *************************************************************************/
458 dms_type float_to_dms( double coord )
459 {
460    dms_type dms_coord;
461 
462    dms_coord.degrees = (int)coord;
463    dms_coord.minutes = (int)((double)(coord-(int)coord)*60.0);
464    dms_coord.seconds = (float)((((double)(coord-(int)coord)* 60.0) -
465 			(double)dms_coord.minutes) * 60.0);
466    dms_coord.minutes = abs(dms_coord.minutes);
467    dms_coord.seconds = (float)(fabs(dms_coord.seconds));
468 
469    if (dms_coord.minutes == 60) {
470       if (dms_coord.degrees > 0)
471 	 dms_coord.degrees++;
472       else
473 	 dms_coord.degrees--;
474       dms_coord.minutes = 0;
475    }
476 
477    if ((dms_coord.degrees == 0)&&(coord < 0.0)) dms_coord.minutes *= -1;
478 
479    return dms_coord;
480 }
481 
482 
483 /*************************************************************************
484  *
485  *N  dms_to_float
486  *
487  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
488  *
489  *   Purpose:
490  *P
491  *     This function converts a coordinate in degrees-minutes-seconds format
492  *     to a floating point coordinate.
493  *E
494  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
495  *
496  *   Parameters:
list_image_templates(client, resource_group_name=None)497  *A
498  *    coord   <input> == (dms_type) degrees-minutes-seconds coordinate.
499  *    return <output> == (double) floating point lat lon coordinate.
500  *E
501  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
502  *
503  *   History:
504  *H
505  *    Barry Michaels    April 1990    Original Version    DOS Turbo C
506  *E
507  *************************************************************************/
508 double dms_to_float( dms_type coord )
509 {
510    return ( (double)coord.degrees +
511 	    ((double)coord.minutes / 60.0) +
512 	    (coord.seconds/3600.0) );
513 }
514 
515 
516 
517 /*************************************************************************
518  *
519  *N  dms_string
520  *
521  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
522  *
523  *   Purpose:
524  *P
525  *     This function converts a coordinate in degrees-minutes-seconds format
526  *     to a character string.
527  *E
528  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
529  *
530  *   Parameters:
531  *A
532  *    coord   <input> == (dms_type) degrees-minutes-seconds coordinate.
533  *    seconds <input> == (int) flag to indicate if seconds are to be
534  *                       displayed.
535  *    return <output> == (char *) character string.
536  *E
537  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
538  *
539  *   History:
540  *H
541  *    Barry Michaels    April 1990    Original Version    DOS Turbo C
542  *E
543  *************************************************************************/
544 char *dms_string( dms_type coord, int seconds )
545 {
546    char *str,deg[5],min[3],sec[3];
547 
548    str = (char *)vpfmalloc( (20*sizeof(char))+
549 			    sizeof(deg)+sizeof(min)+sizeof(sec) );
550 
551    itoa( coord.degrees, deg, 10 );
552    itoa( abs(coord.minutes), min, 10 );
553    if (seconds) itoa( ((int)floor(coord.seconds)), sec, 10 );
remove_template_output(cmd, client, resource_group_name, image_template_name, output_name)554    if ((coord.degrees==0)&&(coord.minutes < 0)) {
555       strcpy(str,"-0");
556       coord.minutes *= -1;
557    } else {
558       strcpy(str,deg);
559    }
560    strcat(str," deg ");
561    strcat(str,min);
562    strcat(str," min ");
563    if (seconds) {
564       strcat(str,sec);
565       strcat(str," sec");
566    }
567 
568    return(str);
569 }
570 #ifdef __MSDOS__
571 /*************************************************************************
572  *
573  *N  out_dms
574  *
575  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
576  *
577  *   Purpose:
clear_template_output(cmd, client, resource_group_name, image_template_name)578  *P
579  *     This function displays the given degree-minutes-seconds coordinate
580  *     at the specified location on the screen.  The direction is given
581  *     for placement along the edges of the screen.  Must be in graphics
582  *     mode to call this function.  User must make sure that all text will
583  *     fit on the screen; this program will not adjust size, but will adjust
584  *     location to make sure that all text that CAN fit on the screen WILL
585  *     fit on the screen.
586  *E
587  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
588  *
589  *   Parameters:
590  *A
591  *    coord   <input> == (dms_type) degrees-minutes-seconds coordinate.
592  *    x       <input> == (int) x location.
593  *    y       <input> == (int) y location.
594  *    dir     <input> == (int) dir.  HORIZ_DIR=0, VERT_DIR=1
595  *    seconds <input> == (int) flag indicating whether to display seconds.
596  *E
597  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
598  *
599  *   History:
600  *H
601  *    Barry Michaels    October 1990    Original Version    DOS Turbo C
602  *    Ronald Rozensky   Sept 1991 x,y adjustments to make text fit on screen
603  *E
604  *************************************************************************/
605 void out_dms( dms_type coord, int x, int y, int dir, int seconds )
606 {
607    char deg[8],min[8],sec[8];
608    int x1,x2,y1,y2, width, adjust, minutes;
609 
610    settextjustify(LEFT_TEXT,BOTTOM_TEXT);
611 
612    itoa( coord.degrees, deg, 10 );
613    if ((coord.seconds >= 30.0)&&(!seconds)) {
614       /* Round up */
615       minutes = abs(coord.minutes)+1;
616       if (minutes == 60) {
617 	 /* Rounded up to next degree */
618 	 strcpy(min,"0");
619 	 if (coord.degrees > 0)
620 	    coord.degrees++;
621 	 else if (coord.degrees < 0)
622 	    coord.degrees--;
623 	 else {
624 	    if (coord.minutes < 0 || coord.seconds < 0.0)
625 	       coord.degrees++;
626 	    else
627 	       coord.degrees--;
628 	 }
629       } else {
630 	 itoa( minutes, min, 10 );
631       }
632       itoa( coord.degrees, deg, 10 );
633    } else {
634       itoa( abs(coord.minutes), min, 10 );
635    }
636    if (seconds) itoa( floor(abs(coord.seconds+0.5)), sec, 10 );
637    if ((coord.degrees==0)&&(coord.minutes < 0)) {
638       strcpy(deg,"-0");
639    }
640    if ((coord.degrees==0)&&(coord.minutes==0)&&(coord.seconds<0)) {
641       strcpy(deg,"-0");
642    }
643    strcat(min,"'");
644    if (seconds) strcat(sec,"''");
645 
646    if (dir==HORIZ_DIR) {
647       width = textwidth(deg)+3;
648       if ((coord.minutes > 0)||(seconds)) {
649 	 width += textwidth(min)+3;
650       }
651       if (seconds) {
652 	 width += textwidth(sec)+3;
653       }
654       x1 = x - width/2;
655       x2 = x1 + width;
656       y1 = y-textheight(deg)-1;
657       y2 = y+1;
658    } else {
659       width = textwidth(deg)+3;
660       if ((coord.minutes > 0)||(seconds)) {
661 	 width += textwidth(min)+3;
662       }
663       if (seconds) {
664 	 width += textwidth(sec)+3;
665       }
666       x1 = x;
667       x2 = x1 + width;
668       y1 = y - (textheight(deg)+4)/2;
669       y2 = y + (textheight(deg)+4)/2;
670    }
671 
672    setfillstyle(SOLID_FILL,DARKGRAY);
673    if (x1 <0)
674      {
675      adjust = 0-x1;
676      x1 = 0;
677      x2 = x2 += adjust;
678      }
679    if (y1 <0)
680      {
681      adjust = 0-y1;
682      y1 = 0;
683      y2 = y2 += adjust;
684      }
685    if ((y1-y2 < getmaxy()) && (y2 > getmaxy()))
686      {
687      adjust = y2-getmaxy();
688      y2 = getmaxy();
689      y1 -= adjust;
690      }
691    if ((x1-x2 < getmaxx()) && (x2 > getmaxx()))
692      {
693      adjust = x2-getmaxx();
694      x2 = getmaxx();
695      x1 -= adjust;
696      }
697    bar(x1,y1,x2,y2);
698    outtextxy(x1,y2,deg);
699    circle(x1+textwidth(deg)+1, y2-textheight(deg), 2);
700    if ((coord.minutes > 0)||(seconds))
701       outtextxy(x1+textwidth(deg)+5,y2-1,min);
702    if (seconds)
703       outtextxy(x1+textwidth(deg)+3+textwidth(min)+3,y2-1,sec);
704 
705 }
706 #endif
707 
708 
709 /*************************************************************************
710  *
711  *N  strpos
712  *
713  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
714  *
715  *   Purpose:
716  *P
717  *     This function returns the character array position of the first
718  *     occurrence of the given character. (-1 if not present)
719  *E
720  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
721  *
722  *   Parameters:
723  *A
724  *    str     <input> == (char *) character string to be searched.
725  *    ch      <input> == (char) character to search for.
726  *    return <output> == (int) position of character (-1 if not present).
727  *E
728  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
729  *
730  *   History:
731  *H
732  *    Barry Michaels    April 1990    Original Version    DOS Turbo C
733  *E
734  *************************************************************************/
735 int strpos( char *str, char ch )
736 {
737    register int i;
738 
739    for (i=0;(unsigned int)i<strlen(str);i++)
740       if (str[i] == ch) return i;
741    return -1;
742 }
743 
744 
745 
746 
747 /*************************************************************************
748  *
749  *N  fwithin
750  *
751  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
752  *
753  *   Purpose:
754  *P
755  *     This function determines whether the input (x,y) coordinate lies
756  *     within the given rectangular extent.  It returns either TRUE or FALSE.
757  *E
758  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
759  *
760  *   Parameters:
761  *A
762  *    x        <input> == (float) x coordinate of the test point.
763  *    y        <input> == (float) y coordinate of the test point.
764  *    extent   <input> == (extent_type) rectangular area to be tested.
765  *    fwithin <output> == (VPF_BOOLEAN) VPF_BOOLEAN:
766  *                               TRUE if (x,y) lies within area
767  *                               FALSE if (x,y) lies outside of area
768  *E
769  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
770  *
771  *   History:
772  *H
773  *    Barry Michaels   May 1990   Original Version   DOS Turbo C
774  *E
775  *************************************************************************/
776 VPF_BOOLEAN fwithin( float x,
777 		 float y,
778 		 extent_type extent )
779 {
780    if ((x >= extent.x1) && (x <= extent.x2) &&
781       (y >= extent.y1) && (y <= extent.y2))
782       return TRUE;
783    else
784       return FALSE;
785 }
786 
787 
788 
789 /*************************************************************************
790  *
791  *N  contained
792  *
793  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
794  *
795  *   Purpose:
796  *P
797  *     This function determines whether an input rectangular 'extent1' is
798  *     contained within another rectangular 'extent2'.  It returns either
799  *     TRUE or FALSE.
800  *E
801  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
802  *
803  *   Parameters:
804  *A
805  *    extent1 <input> == (extent_type) rectangular area to be tested within.
806  *    extent2 <input> == (extent_type) rectangular area to be tested against.
807  *    contained <output> == (VPF_BOOLEAN) VPF_BOOLEAN:
808  *                               TRUE if extent2 contains extent1
809  *                               FALSE if extent2 does not contain extent1
810  *E
811  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
812  *
813  *   History:
814  *H
815  *    Barry Michaels   May 1990   Original Version   DOS Turbo C
816  *E
817  *************************************************************************/
818 VPF_BOOLEAN contained( extent_type extent1,
819 		   extent_type extent2 )
820 {
821    /* Test each of the four corners of extent1 */
822    /*   	  ____________
823 		  |          |
824 		  |  2       |
825 		  |    ______+___
826 		  |    |     |
827 		  |    |     |
828 		  |    |  1  |
829 		  |    |     |
830 		  ------------
831 		       |
832 		       |
833    */
834    if ((extent1.x1 >= extent2.x1) && (extent1.x1 <= extent2.x2) &&
835       (extent1.y1 >= extent2.y1) && (extent1.y1 <= extent2.y2))
836       return TRUE;
837    /*             ____________
838 		  |          |
839 		  |  2       |
840 		  |          |
841 	       ---+------    |
842 		  |     |    |
843 		  |  1  |    |
844 		  |     |    |
845 		  ------------
846 			|
847 			|
848    */
849    if ((extent1.x2 >= extent2.x1) && (extent1.x2 <= extent2.x2) &&
850       (extent1.y1 >= extent2.y1) && (extent1.y1 <= extent2.y2))
851       return TRUE;
852    /*
853 		       |
854 		  _____|______
855 		  |    |     |
856 		  |  1 |     |
857 		  |    |     |
858 		--+-----     |
859 		  |          |
860 		  |    2     |
861 		  |__________|
862    */
863    if ((extent1.x2 >= extent2.x1) && (extent1.x2 <= extent2.x2) &&
864       (extent1.y2 >= extent2.y1) && (extent1.y2 <= extent2.y2))
865       return TRUE;
866    /*			|
867 			|
868 		  ______|_____
869 		  |     |    |
870 		  |     | 1  |
871 		  |     |    |
872 		  | 2   -----+--
873 		  |          |
874 		  |          |
875 		  ------------
876    */
877    if ((extent1.x1 >= extent2.x1) && (extent1.x1 <= extent2.x2) &&
878       (extent1.y2 >= extent2.y1) && (extent1.y2 <= extent2.y2))
879       return TRUE;
880 
881 
882    /* Test for overlaps */
883    /*	 ________             --------------
884 	 |      |             |     2      |
885 	 |  1   |             | ---------- |
886      ----+------+----         | |        | |
887      | 2 |      |   |         | |        | |
888      |   |      |   |         | |   1    | |
889      ----+------+----         | |        | |
890 	 |      |             | |        | |
891 	 |      |             | ---------- |
892 	 --------             |            |
893 			      --------------
894    */
895    if ((extent1.y1 >= extent2.y1) && (extent1.y2 <= extent2.y2) &&
896        (extent1.x1 <= extent2.x2) && (extent1.x2 >= extent2.x1))
897       return TRUE;
898    /*	 ________             --------------
899 	 |      |             |     1      |
900 	 |  2   |             | ---------- |
901      ----+------+----         | |        | |
902      | 1 |      |   |         | |        | |
903      |   |      |   |         | |   2    | |
904      ----+------+----         | |        | |
905 	 |      |             | |        | |
906 	 |      |             | ---------- |
907 	 --------             |            |
908 			      --------------
909    */
910    if ((extent1.x1 >= extent2.x1) && (extent1.x2 <= extent2.x2) &&
911        (extent1.y1 <= extent2.y2) && (extent1.y2 >= extent2.y1))
912       return TRUE;
913    return FALSE;
914 }
915 
916 
917 #ifdef __MSDOS__
918 /*************************************************************************
919  *
920  *N  info_window
921  *
922  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
923  *
924  *   Purpose:
925  *P
926  *     This function displays a temporary window to the screen with a
927  *     single string of text.  Must be in graphics mode to call this
928  *     function.
929  *E
930  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
931  *
932  *   Parameters:
933  *A
934  *    text    <input> == (char *)message to display.
935  *    return <output> == (window_type) window created and displayed.
936  *                       [Will need to be deleted]
937  *E
938  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
939  *
940  *   History:
941  *H
942  *    Barry Michaels   July 1990   Original Version   DOS Turbo C
943  *E
944  *************************************************************************/
945 window_type info_window( char *text )
946 {
947    window_type w;
948    int x,y;
949 
950    settextstyle(SMALL_FONT,HORIZ_DIR,4);
951    settextjustify(LEFT_TEXT,BOTTOM_TEXT);
952    if (textwidth(text) > getmaxx())
953      x = getmaxx()-20;
954     else
955      x = textwidth(text) + 20;
956    create_window( &w, x, textheight(text)+10,
957 		  menucolor,menubordercolor );
958    get_display_position( &x, &y, w );
959    open_window( &w, x,y );
960    setcolor(menutextcolor);
961    hidemousecursor();
962    outtextxy( 10,textheight(text)+5,text );
963    showmousecursor();
964    return w;
965 }
966 #endif
967 
968 
969 /*************************************************************************
970  *
971  *N  rightjust
972  *
973  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
974  *
975  *   Purpose:
976  *P
977  *     This function right justifies the given string and removes the
978  *     trailing newline character (if one exists).
979  *E
980  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
981  *
982  *   Parameters:
983  *A
984  *    str <inout> == (char *) string to be justified.
985  *E
986  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
987  *
988  *   History:
989  *H
990  *    Barry Michaels   November 1990   Original Version   DOS Turbo C
991  *E
992  *************************************************************************/
993 char *rightjust( char *str )
994 {
995    return strrev(leftjust(strrev(str)));
996 }
997 
998 /*************************************************************************
999  *
1000  *N  leftjust
1001  *
1002  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1003  *
1004  *   Purpose:
1005  *P
1006  *     This function left justifies the given string and removes the
1007  *     trailing newline character (if one exists)
1008  *E
1009  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1010  *
1011  *   Parameters:
1012  *A
1013  *    str <inout> == (char *) string to be justified.
1014  *E
1015  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1016  *
1017  *   History:
1018  *H
1019  *    Barry Michaels   November 1990   Original Version   DOS Turbo C
1020  *E
1021  *************************************************************************/
1022 char *leftjust(char * str)
1023 {
1024    register char * eol;
1025 
1026    strcpy(str, str + strspn(str, " \t\n\b"));
1027 
1028    if ((eol = strchr(str, '\n')) != NULL)
1029      *eol = 0;
1030 
1031    return str;
1032 }
1033 
1034 #ifdef __MSDOS__
1035 /*************************************************************************
1036  *
1037  *N  displayerror
1038  *
1039  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1040  *
1041  *   Purpose:
1042  *P
1043  *     This function displays an error message when a disk error is detected.
1044  *     It displays the given lines of text in a popup panel and waits for
1045  *     the user to click on either retry or cancel.  It returns 1 for retry
1046  *     and 0 for cancel.  Must be in graphics mode to call this function.
1047  *
1048  *     text strings may contain embedded newlines, in which case text to the
1049  *     right of the newline will be displayed on (what else?) a new line.
1050  *E
1051  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1052  *
1053  *   Parameters:
1054  *A
1055  *    text[]  <input> == (char *) array of text strings to be displayed.
1056  *    nlines  <input> == (int) number of lines of text (this count ignores
1057  *                             newline characters embedded in the text
1058  *                             strings
1059  *    return <output> == (VPF_BOOLEAN) 1 => retry,
1060  *                                 0 => cancel.
1061  *E
1062  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1063  *
1064  *   History:
1065  *H
1066  *    Barry Michaels    July 1990    Prototype 3    DOS Turbo C
1067  *E
1068  *************************************************************************/
1069 VPF_BOOLEAN displayerror( char *text[],
1070 		      int  nlines )
1071 {
1072    register int i;
1073    int          maxw,
1074 		height,
1075 		x,
1076 		y,
1077 		pad,
1078 		choice,
1079 		n_real_lines;
1080    panel_type   panel;
1081    int          retry_button  = 'r',
1082 		cancel_button = 'c',
1083 		msg_ar_sz     = 10;
1084    char       * walker,
1085 	     ** msgs;
1086    struct viewporttype view;
1087 
1088    getviewsettings( &view );
1089    setviewport(0,0,getmaxx(),getmaxy(),1);
1090 
1091 
1092    settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
1093    msgs = (char **) vpfmalloc(msg_ar_sz * sizeof(char *));
1094    maxw = height = 0;
1095 
1096    for (n_real_lines = i = 0; i < nlines; i++) {
1097      walker = text[i];
1098      while (1) {
1099 	size_t substr_len = strcspn(walker, "\n");
1100 	char   plug;
1101 
1102 	maxw                 = max(maxw, textwidth(walker));
1103 	height               = height + textheight(walker) + 5;
1104 	plug                 = walker[substr_len];
1105 	walker[substr_len]   = '\0';
1106 	msgs[n_real_lines++] = strdup(walker);
1107 
1108 	if (n_real_lines == msg_ar_sz)
1109 	  msgs = (char **) realloc(msgs, (msg_ar_sz += 5) * sizeof(char *));
1110 	if (plug == 0)
1111 	  break;
1112 
1113 	walker[substr_len] = plug;
1114 	walker            += substr_len + 1;
1115      }
1116    }
1117 
1118    if (maxw < (textwidth("Retry") + textwidth("Cancel") + 20))
1119       maxw = textwidth("Retry") + textwidth("Cancel") + 20;
1120 
1121    pad    = (maxw*10)/100;
1122    maxw   = maxw + (2*pad);
1123    height = height + 2*(textheight("Retry") + 5) + 1;
1124    maxw   = min(getmaxx(), maxw);
1125    height = min(getmaxy()-10, height);
1126 
1127    create_panel( &panel, maxw, height, menucolor, menubordercolor );
1128 
1129    for (y = i = 0; i < n_real_lines; i++) {
1130      create_label(msgs[i], pad, y, SMALL_FONT, 4, menutextcolor, &panel );
1131      y += textheight(msgs[i]) + 3;
1132    }
1133 
1134    y = height-15;
1135 
1136    create_button( retry_button,
1137 		  "Retry",
1138 		  3,
1139 		  y,
1140 		  SMALL_FONT,
1141 		  4,
1142 		  menutextcolor,
1143 		  menucolor,
1144 		  menubordercolor,
1145 		  RELIEVED,
1146 		  &panel );
1147    create_button( cancel_button,
1148 		  "Cancel",
1149 		  maxw - (textwidth("Cancel") + 13),
1150 		  y,
1151 		  SMALL_FONT,
1152 		  4,
1153 		  menutextcolor,
1154 		  menucolor,
1155 		  menubordercolor,
1156 		  RELIEVED,
1157 		  &panel );
1158 
1159    get_display_position( &x, &y, panel.window );
1160 
1161    display_panel( &panel, x,y );
1162    showmousecursor();
1163    arrow_cursor();
1164    choice = process_panel( &panel, 0 );
1165    hidemousecursor();
1166 
1167    destroy_panel( &panel );
1168    close_panel( &panel );
1169 
1170    setviewport(view.left,view.top,view.right,view.bottom,view.clip);
1171 
1172    for (i = 0; i < n_real_lines; i++)
1173      free(msgs[i]);
1174    free(msgs);
1175 
1176    return (choice == retry_button) ? 1 : 0;
1177 }
1178 
1179 
1180 
1181 /*************************************************************************
1182  *
1183  *N  getcursorposition
1184  *
1185  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1186  *
1187  *   Purpose:
1188  *P
1189  *     This function returns the cursor position when either the mouse
1190  *     has been moved or an arrow key has been pressed.  Must have called
1191  *     showmousecursor() before calling this routine.
1192  *E
1193  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1194  *
1195  *   Parameters:
1196  *A
1197  *    x       <inout> == (int *) x position of the cursor.
1198  *    y       <inout> == (int *) y position of the cursor.
1199  *    button  <inout> == (int *) mouse button pressed (or simulated with
1200  *                               the keyboard).
1201  *    return <output> == (int) escape status:
1202  *                             FALSE -> escape pressed
1203  *                             TRUE  -> escape not pressed
1204  *E
1205  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1206  *
1207  *   History:
1208  *H
1209  *    Barry Michaels   November 1990   Original Version   DOS Turbo C
1210  *E
1211  *************************************************************************/
1212 int getcursorposition( int *x,
1213 		       int *y,
1214 		       int *button )
1215 {
1216    char ch,ch2;
1217    int  xpos,ypos, ok = TRUE;
1218 
1219    if (kbhit()) {
1220       xpos = *x;
1221       ypos = *y;
1222       ch = getch();
1223       switch (ch) {
1224 	 case 13:                         /* Enter key */
1225 	    *button = LEFT_BUTTON_DOWN;
1226 	    break;
1227 	 case '8':
1228 	    ypos -= 10;
1229 	    break;
1230 	 case '2':
1231 	    ypos += 10;
1232 	    break;
1233 	 case '4':
1234 	    xpos -= 10;
1235 	    break;
1236 	 case '6':
1237 	    xpos += 10;
1238 	    break;
1239 	 case 27:
1240 	    ok = FALSE;
1241 	    break;
1242       }
1243       if (ch==0) {
1244 	 ch2 = getch();
1245 	 switch (ch2) {
1246 	    case 72:
1247 	       ypos--;
1248 	       break;
1249 	    case 80:
1250 	       ypos++;
1251 	       break;
1252 	    case 75:
1253 	       xpos--;
1254 	       break;
1255 	    case 77:
1256 	       xpos++;
1257 	       break;
1258 	    case 59: /* F1 key */
1259 	       *button = RIGHT_BUTTON_DOWN;
1260 	       break;
1261 	 }
1262       }
1263       setmouseposition(xpos,ypos);
1264       *x = xpos;
1265       *y = ypos;
1266    } else getmouseposition(x,y,button);
1267    return ok;
1268 }
1269 
1270 
1271 
1272 /*************************************************************************
1273  *
1274  *N  yes_no
1275  *
1276  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1277  *
1278  *   Purpose:
1279  *P
1280  *     This function displays a panel asking the user a yes or no
1281  *     question and returns the response.  Must be in graphics mode to call
1282  *     this function.
1283  *E
1284  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1285  *
1286  *   Parameters:
1287  *A
1288  *    text     <input>==(char *) question string.
1289  *    return  <output>==(int) yes (TRUE) or no (FALSE).
1290  *E
1291  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1292  *
1293  *   History:
1294  *H
1295  *    Barry Michaels   May 1991                    DOS Turbo C
1296  *E
1297  *************************************************************************/
1298 int yes_no( char *text )
1299 {
1300    panel_type  panel;
1301    int         no_id = 27;
1302    int         yes_id = 13;
1303    int         x,y,width,height,maxheight,id=0;
1304 
1305    settextstyle( SMALL_FONT, HORIZ_DIR, 4 );
1306 
1307    width = 0;
1308    maxheight = 0;
1309    width = textwidth(text);
1310    maxheight = textheight(text);
1311 
1312    width = width + 50;
1313    if (width > getmaxx())
1314       width = getmaxx()-10;
1315    height = maxheight * 5;
1316 
1317    create_panel( &panel,width,height,menucolor,menubordercolor );
1318 
1319    y = maxheight;
1320    create_label( text,CENTER,y,SMALL_FONT,4,menutextcolor,&panel );
1321    y += maxheight;
1322 
1323    create_button( yes_id, "Yes",
1324 		  3, height-textheight("Y")-6,
1325 		  SMALL_FONT, 4,
1326 		  menutextcolor, menucolor, menubordercolor, RELIEVED,
1327 		  &panel );
1328    create_button( no_id, "No",
1329 		  width-textwidth("No")-13,
1330 		  height-textheight("No")-6,
1331 		  SMALL_FONT, 4,
1332 		  menutextcolor, menucolor, menubordercolor, RELIEVED,
1333 		  &panel );
1334 
1335    get_display_position( &x, &y, panel.window );
1336 
1337    display_panel( &panel, x,y );
1338 
1339    id = process_panel(&panel, id);
1340 
1341    destroy_panel( &panel );
1342    close_panel( &panel );
1343 
1344    if (id == yes_id)
1345       return TRUE;
1346    else
1347       return FALSE;
1348 }
1349 
1350 
1351 
1352 /*************************************************************************
1353  *
1354  *N  printer_ready
1355  *
1356  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1357  *
1358  *   Purpose:
1359  *P
1360  *     This function determines whether or not the attached
1361  *     printer is ready.
1362  *E
1363  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1364  *
1365  *   Parameters:
1366  *A
1367  *    return <output> == (int) TRUE if ready, FALSE if not.
1368  *E
1369  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1370  *
1371  *   History:
1372  *H
1373  *    Barry Michaels   November 1990   Original Version   DOS Turbo C
1374  *E
1375  *************************************************************************/
1376 int printer_ready( void )
1377 {
1378    union REGS reg;
1379 
1380    reg.h.ah = 2;
1381    reg.x.dx = 0;
1382    int86(0x17, &reg, &reg);
1383 
1384    /* this is not busy           not an io error      not out of paper */
1385    return (reg.h.ah & 0x80) && (!(reg.h.ah & 8)) && (!(reg.h.ah & 32));
1386 }
1387 
1388 
1389 /*************************************************************************
1390  *
1391  *N  printer_ok
1392  *
1393  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1394  *
1395  *   Purpose:
1396  *P
1397  *     This function determines whether the printer is ready and allows
1398  *     the user to keep retrying or cancel.  Must be in graphics mode to call
1399  *     this function.
1400  *E
1401  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1402  *
1403  *   Parameters:
1404  *A
1405  *    return <output> == (int) TRUE if ready, FALSE if cancel.
1406  *E
1407  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1408  *
1409  *   History:
1410  *H
1411  *    Barry Michaels   November 1990   Original Version   DOS Turbo C
1412  *E
1413  *************************************************************************/
1414 int printer_ok( void )
1415 {
1416    int retry;
1417    char *msg[] = {"Printer not ready"};
1418 
1419    while (!printer_ready()) {
1420       hidemousecursor();
1421       retry = displayerror(msg,1);
1422       showmousecursor();
1423       if (!retry) return FALSE;
1424    }
1425    return TRUE;
1426 }
1427 
1428 
1429 
1430 
1431 /*************************************************************************
1432  *
1433  *N  coprocessor_present
1434  *
1435  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1436  *
1437  *   Purpose:
1438  *P
1439  *     This function determines whether a math coprocessor chip is present
1440  *     on the current computer configuration.
1441  *E
1442  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1443  *
1444  *   Parameters:
1445  *A
1446  *    return <output> == (int) TRUE if present, FALSE if not.
1447  *E
1448  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1449  *
1450  *   History:
1451  *H
1452  *    Barry Michaels   July 1991                          DOS Turbo C
1453  *E
1454  *************************************************************************/
1455 int coprocessor_present( void )
1456 {
1457    int stat;
1458 
1459    stat = biosequip();
1460 
1461    /* If bit 1 of stat is on, a coprocessor is present */
1462    if (stat & 2)
1463       return TRUE;
1464    else
1465       return FALSE;
1466 }
1467 #endif
1468 
1469 
1470 
1471 
1472 /*************************************************************************
1473  *
1474  *N  is_primitive
1475  *
1476  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1477  *
1478  *   Purpose:
1479  *P
1480  *     This function determines whether the given file name specifies a
1481  *     VPF primitive table (Edge, Face, Entity Node, or Text).
1482  *E
1483  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1484  *
1485  *   Parameters:
1486  *A
1487  *    name    <input> == (char *) file name to be tested.
1488  *    return <output> == (int) TRUE if primitive, FALSE if not.
1489  *E
1490  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1491  *
1492  *   History:
1493  *H
1494  *    Barry Michaels   May 1991                           DOS Turbo C
1495  *E
1496  *************************************************************************/
1497 int is_primitive( char *name )
1498 {
1499    strupr(name);
1500    if (strstr(name,"END")) return TRUE;
1501    if (strstr(name,"CND")) return TRUE;
1502    if (strstr(name,"EDG")) return TRUE;
1503    if (strstr(name,"FAC")) return TRUE;
1504    if (strstr(name,"TXT")) return TRUE;
1505    return FALSE;
1506 }
1507 
1508 
1509 
1510 /*************************************************************************
1511  *
1512  *N  is_simple_feature
1513  *
1514  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1515  *
1516  *   Purpose:
1517  *P
1518  *     This function determines whether the given file name specifies a
1519  *     VPF simple feature table (Point, Line, or Area feature table).
1520  *E
1521  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1522  *
1523  *   Parameters:
1524  *A
1525  *    name    <input> == (char *) file name to be tested.
1526  *    return <output> == (int) TRUE if simple feature, FALSE if not.
1527  *E
1528  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1529  *
1530  *   History:
1531  *H
1532  *    Barry Michaels   May 1991                           DOS Turbo C
1533  *E
1534  *************************************************************************/
1535 int is_simple_feature( char *name )
1536 {
1537    strupr(name);
1538    if (strstr(name,"PFT")) return TRUE;
1539    if (strstr(name,"LFT")) return TRUE;
1540    if (strstr(name,"AFT")) return TRUE;
1541    return FALSE;
1542 }
1543 
1544 
1545 
1546 /*************************************************************************
1547  *
1548  *N  is_complex_feature
1549  *
1550  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1551  *
1552  *   Purpose:
1553  *P
1554  *     This function determines whether the given file name specifies a
1555  *     VPF complex feature table.
1556  *E
1557  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1558  *
1559  *   Parameters:
1560  *A
1561  *    name    <input> == (char *) file name to be tested.
1562  *    return <output> == (int) TRUE if complex feature, FALSE if not.
1563  *E
1564  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1565  *
1566  *   History:
1567  *H
1568  *    Barry Michaels   May 1991                           DOS Turbo C
1569  *E
1570  *************************************************************************/
1571 int is_complex_feature( char *name )
1572 {
1573    strupr(name);
1574    if (strstr(name,"CFT")) return TRUE;
1575    return FALSE;
1576 }
1577 
1578 
1579 
1580 
1581 /*************************************************************************
1582  *
1583  *N  is_feature
1584  *
1585  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1586  *
1587  *   Purpose:
1588  *P
1589  *     This function determines whether the given file name specifies a
1590  *     VPF feature table (Point, Line, Area, or Complex feature table).
1591  *E
1592  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1593  *
1594  *   Parameters:
1595  *A
1596  *    name    <input> == (char *) file name to be tested.
1597  *    return <output> == (int) TRUE if feature, FALSE if not.
1598  *E
1599  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1600  *
1601  *   History:
1602  *H
1603  *    Barry Michaels   May 1991                           DOS Turbo C
1604  *E
1605  *************************************************************************/
1606 int is_feature( char *name )
1607 {
1608    strupr(name);
1609    if (strstr(name,"PFT")) return TRUE;
1610    if (strstr(name,"LFT")) return TRUE;
1611    if (strstr(name,"AFT")) return TRUE;
1612    if (strstr(name,"TFT")) return TRUE;
1613    if (strstr(name,"CFT")) return TRUE;
1614    return FALSE;
1615 }
1616 
1617 
1618 
1619 
1620 /*************************************************************************
1621  *
1622  *N  feature_type
1623  *
1624  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1625  *
1626  *   Purpose:
1627  *P
1628  *     This function returns the type of feature the given table name
1629  *     refers to (POINT, LINE, AREA, ANNO, or COMPLEX_FEATURE).  If the table
1630  *     name does not specify a feature type, the function returns FALSE.
1631  *E
1632  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1633  *
1634  *   Parameters:
1635  *A
1636  *    name    <input> == (char *) file name to be tested.
1637  *    return <output> == (int) feature type (FALSE if invalid name).
1638  *E
1639  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1640  *
1641  *   History:
1642  *H
1643  *    Barry Michaels   May 1991                           DOS Turbo C
1644  *E
1645  *************************************************************************/
1646 int feature_type( char *name )
1647 {
1648    strupr(name);
1649    if (strstr(name,"PFT")) return VPF_POINT;
1650    if (strstr(name,"LFT")) return VPF_LINE;
1651    if (strstr(name,"AFT")) return VPF_AREA;
1652    if (strstr(name,"TXT")) return VPF_ANNO;
1653    if (strstr(name,"TFT")) return VPF_ANNO;
1654    if (strstr(name,"CFT")) return VPF_COMPLEX_FEATURE;
1655    return FALSE;
1656 }
1657 
1658 
1659 
1660 
1661 /*************************************************************************
1662  *
1663  *N  is_join
1664  *
1665  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1666  *
1667  *   Purpose:
1668  *P
1669  *     This function determines whether the given file name specifies a
1670  *     VPF join table.
1671  *E
1672  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1673  *
1674  *   Parameters:
1675  *A
1676  *    name    <input> == (char *) file name to be tested.
1677  *    return <output> == (int) TRUE if join, FALSE if not.
1678  *E
1679  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1680  *
1681  *   History:
1682  *H
1683  *    Barry Michaels   May 1991                           DOS Turbo C
1684  *E
1685  *************************************************************************/
1686 int is_join( char *name )
1687 {
1688    char *ptr;
1689 
1690    strupr(name);
1691    ptr = strstr(name,".");
1692    if (strstr(ptr,"JT")) return TRUE;
1693    return FALSE;
1694 }
1695 
1696 
1697 
1698 /*************************************************************************
1699  *
1700  *N  primitive_class
1701  *
1702  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1703  *
1704  *   Purpose:
1705  *P
1706  *     This function returns the feature type the given primitive table
1707  *     name refers to (POINT, LINE, AREA, or ANNO).  If the table
1708  *     name is not a valid primitive table name, the function returns NULL.
1709  *E
1710  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1711  *
1712  *   Parameters:
1713  *A
1714  *    name    <input> == (char *) file name to be tested.
1715  *    return <output> == (int) feature type (NULL if invalid primitive
1716  *                             name).
1717  *E
1718  *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1719  *
1720  *   History:
1721  *H
1722  *    Barry Michaels   May 1991                           DOS Turbo C
1723  *E
1724  *************************************************************************/
1725 int primitive_class( char *name )
1726 {
1727    strupr(name);
1728    if (strstr(name,"END")) return VPF_ENTITY_NODE;
1729    if (strstr(name,"CND")) return VPF_CONNECTED_NODE;
1730    if (strstr(name,"EDG")) return VPF_EDGE;
1731    if (strstr(name,"FAC")) return VPF_FACE;
1732    if (strstr(name,"TXT")) return VPF_TEXT;
1733 #ifdef __MSDOS__
1734    return NULL;
1735 #else
1736    return 0;
1737 #endif
1738 }
1739 
1740 int ossim_strcasecmp(const char *s1, const char *s2)
1741 {
1742    size_t s1_size;
1743    size_t s2_size;
1744    unsigned int i;
1745 
1746    /* Check for one string being null, one not. */
1747    if (!s1 && s2)
1748    {
1749       return -1;
1750    }
1751    else if (s1 && !s2)
1752    {
1753       return 1;
1754    }
1755 
1756    /* Check for both strings being null.  Consider this equal? */
1757    if (!s1 && !s2)
1758    {
1759       return 0;
1760    }
1761 
1762    /* Check for size differences. */
1763    s1_size = strlen(s1);
1764    s2_size = strlen(s2);
1765    if (s1_size < s2_size)
1766    {
1767       return -1;
1768    }
1769    else if (s1_size > s2_size)
1770    {
1771       return 1;
1772    }
1773 
1774    /* Check the strings. */
1775    for (i=0; i<s1_size; i++)
1776    {
1777       if ( toupper(s1[i]) != toupper(s2[i]) )
1778       {
1779          return ( (toupper(s1[i]) < toupper(s2[i]) ) ? -1 : 1);
1780       }
1781    }
1782 
1783       /* Equal */
1784    return 0;
1785 }
1786 
1787 int ossim_strncasecmp(const char *s1, const char *s2, unsigned int n)
1788 {
1789    size_t s1_size;
1790    size_t s2_size;
1791    unsigned int i;
1792 
1793    /* Check for one string being null, one not. */
1794    if (!s1 && s2)
1795    {
1796       return -1;
1797    }
1798    else if (s1 && !s2)
1799    {
1800       return 1;
1801    }
1802 
1803    /* Check for both strings being null.  Consider this equal? */
1804    if (!s1 && !s2)
1805    {
1806       return 0;
1807    }
1808 
1809    /* Check for size. */
1810    if (n == 0)
1811    {
1812       return 0;
1813    }
1814 
1815    s1_size = strlen(s1);
1816    s2_size = strlen(s2);
1817    if (n > s1_size)
1818    {
1819       return -1;
1820    }
1821    else if (n > s2_size )
1822    {
1823       return 1;
1824    }
1825 
1826    /* Check the strings. */
1827    for (i=0; i<n; i++)
1828    {
1829       if ( toupper(s1[i]) != toupper(s2[i]) )
1830       {
1831          return ( (toupper(s1[i]) < toupper(s2[i]) ) ? -1 : 1);
1832       }
1833    }
1834 
1835       /* Equal */
1836    return 0;
1837 }
1838