home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume8 / gnuplot1.10A / part05 / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-09  |  8.2 KB  |  429 lines

  1. /*
  2.  *
  3.  *    G N U P L O T  --  util.c
  4.  *
  5.  *  Copyright (C) 1986, 1987  Thomas Williams, Colin Kelley
  6.  *
  7.  *  You may use this code as you wish if credit is given and this message
  8.  *  is retained.
  9.  *
  10.  *  Please e-mail any useful additions to vu-vlsi!plot so they may be
  11.  *  included in later releases.
  12.  *
  13.  *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
  14.  */
  15.  
  16. #include <ctype.h>
  17. #include <setjmp.h>
  18. #include <stdio.h>
  19. #include <errno.h>
  20. #include "plot.h"
  21.  
  22. extern BOOLEAN screen_ok;
  23.     /* TRUE if command just typed; becomes FALSE whenever we
  24.         send some other output to screen.  If FALSE, the command line
  25.         will be echoed to the screen before the ^ error message. */
  26.  
  27. char *malloc();
  28.  
  29. #ifndef vms
  30. extern int errno, sys_nerr;
  31. extern char *sys_errlist[];
  32. #endif /* vms */
  33.  
  34. extern char input_line[];
  35. extern struct lexical_unit token[];
  36. extern jmp_buf env;    /* from plot.c */
  37.  
  38.  
  39. /*
  40.  * equals() compares string value of token number t_num with str[], and
  41.  *   returns TRUE if they are identical.
  42.  */
  43. equals(t_num, str)
  44. int t_num;
  45. char *str;
  46. {
  47. register int i;
  48.  
  49.     if (!token[t_num].is_token)
  50.         return(FALSE);                /* must be a value--can't be equal */
  51.     for (i = 0; i < token[t_num].length; i++) {
  52.         if (input_line[token[t_num].start_index+i] != str[i])
  53.             return(FALSE);
  54.         }
  55.     /* now return TRUE if at end of str[], FALSE if not */
  56.     return(str[i] == '\0');
  57. }
  58.  
  59.  
  60.  
  61. /*
  62.  * almost_equals() compares string value of token number t_num with str[], and
  63.  *   returns TRUE if they are identical up to the first $ in str[].
  64.  */
  65. almost_equals(t_num, str)
  66. int t_num;
  67. char *str;
  68. {
  69. register int i;
  70. register int after = 0;
  71. register start = token[t_num].start_index;
  72. register length = token[t_num].length;
  73.  
  74.     if (!token[t_num].is_token)
  75.         return(FALSE);                /* must be a value--can't be equal */
  76.     for (i = 0; i < length + after; i++) {
  77.         if (str[i] != input_line[start + i]) {
  78.             if (str[i] != '$')
  79.                 return(FALSE);
  80.             else {
  81.                 after = 1;
  82.                 start--;    /* back up token ptr */
  83.                 }
  84.             }
  85.         }
  86.  
  87.     /* i now beyond end of token string */
  88.  
  89.     return(after || str[i] == '$' || str[i] == '\0');
  90. }
  91.  
  92.  
  93.  
  94. isstring(t_num)
  95. int t_num;
  96. {
  97.     
  98.     return(token[t_num].is_token &&
  99.            (input_line[token[t_num].start_index] == '\'' ||
  100.            input_line[token[t_num].start_index] == '\"'));
  101. }
  102.  
  103.  
  104. isnumber(t_num)
  105. int t_num;
  106. {
  107.     return(!token[t_num].is_token);
  108. }
  109.  
  110.  
  111. isletter(t_num)
  112. int t_num;
  113. {
  114.     return(token[t_num].is_token &&
  115.             (isalpha(input_line[token[t_num].start_index])));
  116. }
  117.  
  118.  
  119. /*
  120.  * is_definition() returns TRUE if the next tokens are of the form
  121.  *   identifier =
  122.  *        -or-
  123.  *   identifier ( identifer ) =
  124.  */
  125. is_definition(t_num)
  126. int t_num;
  127. {
  128.     return (isletter(t_num) &&
  129.             (equals(t_num+1,"=") ||            /* variable */
  130.             (equals(t_num+1,"(") &&        /* function */
  131.              isletter(t_num+2)   &&
  132.              equals(t_num+3,")") &&
  133.              equals(t_num+4,"=") )
  134.         ));
  135. }
  136.  
  137.  
  138.  
  139. /*
  140.  * copy_str() copies the string in token number t_num into str, appending
  141.  *   a null.  No more than MAX_ID_LEN chars are copied.
  142.  */
  143. copy_str(str, t_num)
  144. char str[];
  145. int t_num;
  146. {
  147. register int i = 0;
  148. register int start = token[t_num].start_index;
  149. register int count;
  150.  
  151.     if ((count = token[t_num].length) > MAX_ID_LEN)
  152.         count = MAX_ID_LEN;
  153.     do {
  154.         str[i++] = input_line[start++];
  155.         } while (i != count);
  156.     str[i] = '\0';
  157. }
  158.  
  159.  
  160. /*
  161.  * quote_str() does the same thing as copy_str, except it ignores the
  162.  *   quotes at both ends.  This seems redundant, but is done for
  163.  *   efficency.
  164.  */
  165. quote_str(str, t_num)
  166. char str[];
  167. int t_num;
  168. {
  169. register int i = 0;
  170. register int start = token[t_num].start_index + 1;
  171. register int count;
  172.  
  173.     if ((count = token[t_num].length - 2) > MAX_ID_LEN)
  174.         count = MAX_ID_LEN;
  175.     do {
  176.         str[i++] = input_line[start++];
  177.         } while (i != count);
  178.     str[i] = '\0';
  179. }
  180.  
  181.  
  182. /*
  183.  *    capture() copies into str[] the part of input_line[] which lies between
  184.  *    the begining of token[start] and end of token[end].
  185.  */
  186. capture(str,start,end)
  187. char str[];
  188. int start,end;
  189. {
  190. register int i,e;
  191.  
  192.     e = token[end].start_index + token[end].length;
  193.     for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  194.         *str++ = input_line[i];
  195.     *str = '\0';
  196. }
  197.  
  198.  
  199. /*
  200.  *    m_capture() is similar to capture(), but it mallocs storage for the
  201.  *  string.
  202.  */
  203. m_capture(str,start,end)
  204. char **str;
  205. int start,end;
  206. {
  207. register int i,e;
  208. register char *s;
  209.  
  210.     if (*str)        /* previous pointer to malloc'd memory there */
  211.         free(*str);
  212.     e = token[end].start_index + token[end].length;
  213.     if (*str = malloc((unsigned int)(e - token[start].start_index + 1))) {
  214.         s = *str;
  215.         for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  216.             *s++ = input_line[i];
  217.         *s = '\0';
  218.     }
  219. }
  220.  
  221.  
  222. convert(val_ptr, t_num)
  223. struct value *val_ptr;
  224. int t_num;
  225. {
  226.     *val_ptr = token[t_num].l_val;
  227. }
  228.  
  229.  
  230.  
  231. disp_value(fp,val)
  232. FILE *fp;
  233. struct value *val;
  234. {
  235.         switch(val->type) {
  236.             case INT:
  237.                 fprintf(fp,"%d",val->v.int_val);
  238.                 break;
  239.             case CMPLX:
  240.                 if (val->v.cmplx_val.imag != 0.0 )
  241.                     fprintf(fp,"{%g, %g}",
  242.                         val->v.cmplx_val.real,val->v.cmplx_val.imag);
  243.                 else
  244.                     fprintf(fp,"%g", val->v.cmplx_val.real);
  245.                 break;
  246.             default:
  247.                 int_error("unknown type in disp_value()",NO_CARET);
  248.         }
  249. }
  250.  
  251.  
  252. double
  253. real(val)        /* returns the real part of val */
  254. struct value *val;
  255. {
  256.     switch(val->type) {
  257.         case INT:
  258.             return((double) val->v.int_val);
  259.             break;
  260.         case CMPLX:
  261.             return(val->v.cmplx_val.real);
  262.     }
  263.     int_error("unknown type in real()",NO_CARET);
  264.     /* NOTREACHED */
  265. }
  266.  
  267.  
  268. double
  269. imag(val)        /* returns the imag part of val */
  270. struct value *val;
  271. {
  272.     switch(val->type) {
  273.         case INT:
  274.             return(0.0);
  275.             break;
  276.         case CMPLX:
  277.             return(val->v.cmplx_val.imag);
  278.     }
  279.     int_error("unknown type in real()",NO_CARET);
  280.     /* NOTREACHED */
  281. }
  282.  
  283.  
  284.  
  285. double
  286. magnitude(val)        /* returns the magnitude of val */
  287. struct value *val;
  288. {
  289.     double sqrt();
  290.  
  291.     switch(val->type) {
  292.         case INT:
  293.             return((double) abs(val->v.int_val));
  294.             break;
  295.         case CMPLX:
  296.             return(sqrt(val->v.cmplx_val.real*
  297.                     val->v.cmplx_val.real +
  298.                     val->v.cmplx_val.imag*
  299.                     val->v.cmplx_val.imag));
  300.     }
  301.     int_error("unknown type in magnitude()",NO_CARET);
  302.     /* NOTREACHED */
  303. }
  304.  
  305.  
  306.  
  307. double
  308. angle(val)        /* returns the angle of val */
  309. struct value *val;
  310. {
  311.     double atan2();
  312.  
  313.     switch(val->type) {
  314.         case INT:
  315.             return((val->v.int_val > 0) ? 0.0 : Pi);
  316.             break;
  317.         case CMPLX:
  318.             if (val->v.cmplx_val.imag == 0.0) {
  319.                 if (val->v.cmplx_val.real >= 0.0)
  320.                     return(0.0);
  321.                 else
  322.                     return(Pi);
  323.             }
  324.             return(atan2(val->v.cmplx_val.imag,
  325.                      val->v.cmplx_val.real));
  326.     }
  327.     int_error("unknown type in angle()",NO_CARET);
  328.     /* NOTREACHED */
  329. }
  330.  
  331.  
  332. struct value *
  333. complex(a,realpart,imagpart)
  334. struct value *a;
  335. double realpart, imagpart;
  336. {
  337.     a->type = CMPLX;
  338.     a->v.cmplx_val.real = realpart;
  339.     a->v.cmplx_val.imag = imagpart;
  340.     return(a);
  341. }
  342.  
  343.  
  344. struct value *
  345. integer(a,i)
  346. struct value *a;
  347. int i;
  348. {
  349.     a->type = INT;
  350.     a->v.int_val = i;
  351.     return(a);
  352. }
  353.  
  354.  
  355.  
  356. os_error(str,t_num)
  357. char str[];
  358. int t_num;
  359. {
  360. #ifdef vms
  361. static status[2] = {1, 0};        /* 1 is count of error msgs */
  362. #endif
  363.  
  364. register int i;
  365.  
  366.     /* reprint line if screen has been written to */
  367.  
  368.     if (t_num != NO_CARET) {        /* put caret under error */
  369.         if (!screen_ok)
  370.             fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
  371.  
  372.         for (i = 0; i < sizeof(PROMPT) - 1; i++)
  373.             (void) putc(' ',stderr);
  374.         for (i = 0; i < token[t_num].start_index; i++) {
  375.             (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
  376.             }
  377.         (void) putc('^',stderr);
  378.         (void) putc('\n',stderr);
  379.     }
  380.  
  381.     for (i = 0; i < sizeof(PROMPT) - 1; i++)
  382.         (void) putc(' ',stderr);
  383.     fprintf(stderr,"%s\n",str);
  384.  
  385.     for (i = 0; i < sizeof(PROMPT) - 1; i++)
  386.         (void) putc(' ',stderr);
  387. #ifdef vms
  388.     status[1] = vaxc$errno;
  389.     sys$putmsg(status);
  390.     (void) putc('\n',stderr);
  391. #else
  392.     if (errno >= sys_nerr)
  393.         fprintf(stderr, "unknown errno %d\n\n", errno);
  394.     else
  395.         fprintf(stderr,"(%s)\n\n",sys_errlist[errno]);
  396. #endif
  397.  
  398.     longjmp(env, TRUE);    /* bail out to command line */
  399. }
  400.  
  401.  
  402. int_error(str,t_num)
  403. char str[];
  404. int t_num;
  405. {
  406. register int i;
  407.  
  408.     /* reprint line if screen has been written to */
  409.  
  410.     if (t_num != NO_CARET) {        /* put caret under error */
  411.         if (!screen_ok)
  412.             fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
  413.  
  414.         for (i = 0; i < sizeof(PROMPT) - 1; i++)
  415.             (void) putc(' ',stderr);
  416.         for (i = 0; i < token[t_num].start_index; i++) {
  417.             (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
  418.             }
  419.         (void) putc('^',stderr);
  420.         (void) putc('\n',stderr);
  421.     }
  422.  
  423.     for (i = 0; i < sizeof(PROMPT) - 1; i++)
  424.         (void) putc(' ',stderr);
  425.     fprintf(stderr,"%s\n\n",str);
  426.  
  427.     longjmp(env, TRUE);    /* bail out to command line */
  428. }
  429.