home *** CD-ROM | disk | FTP | other *** search
- /* basic formating routines.
- * all the screen oriented printing should go through here.
- */
-
- #include <stdio.h>
- #include <math.h>
- #ifdef VMS
- #include <stdlib.h>
- #endif
- #include "astro.h"
- #include "screen.h"
-
- extern char *strcpy();
-
- /* suppress screen io if this is true, but always flog stuff.
- */
- static int f_scrnoff;
- f_on ()
- {
- f_scrnoff = 0;
- }
- f_off ()
- {
- f_scrnoff = 1;
- }
-
- /* draw n blanks at the given cursor position. */
- f_blanks (r, c, n)
- int r, c, n;
- {
- if (f_scrnoff)
- return;
- c_pos (r, c);
- while (--n >= 0)
- putchar (' ');
- }
-
- /* print the given value, v, in "sexadecimal" format at [r,c]
- * ie, in the form A:m.P, where A is a digits wide, P is p digits.
- * if p == 0, then no decimal point either.
- */
- f_sexad (r, c, a, p, mod, v)
- int r, c;
- int a, p; /* left space, min precision */
- int mod; /* don't let whole portion get this big */
- double v;
- {
- char astr[32], str[32];
- long dec;
- double frac;
- int visneg;
- double vsav = v;
-
- if (v >= 0.0)
- visneg = 0;
- else {
- if (v <= -0.5/60.0*pow(10.0,-1.0*p)) {
- v = -v;
- visneg = 1;
- } else {
- /* don't show as negative if less than the precision showing */
- v = 0.0;
- visneg = 0;
- }
- }
-
- dec = v;
- frac = (v - dec)*60.0;
- (void) sprintf (str, "59.%.*s5", p, "999999999");
- if (frac >= atof (str)) {
- dec += 1;
- frac = 0.0;
- }
- dec %= mod;
- if (dec == 0 && visneg)
- (void) strcpy (str, "-0");
- else
- (void) sprintf (str, "%ld", visneg ? -dec : dec);
-
- /* would just do this if Turbo-C 2.0 %?.0f" worked:
- * sprintf (astr, "%*s:%0*.*f", a, str, p == 0 ? 2 : p+3, p, frac);
- */
- if (p == 0)
- (void) sprintf (astr, "%*s:%02d", a, str, (int)(frac+0.5));
- else
- (void) sprintf (astr, "%*s:%0*.*f", a, str, p+3, p, frac);
-
- (void) flog_log (r, c, vsav, astr);
-
- f_string (r, c, astr);
- }
-
- /* print the given value, t, in sexagesimal format at [r,c]
- * ie, in the form T:mm:ss, where T is nd digits wide.
- * N.B. we assume nd >= 2.
- */
- f_sexag (r, c, nd, t)
- int r, c, nd;
- double t;
- {
- char tstr[32];
- int h, m, s;
- int tisneg;
-
- dec_sex (t, &h, &m, &s, &tisneg);
- if (h == 0 && tisneg)
- (void) sprintf (tstr, "%*s-0:%02d:%02d", nd-2, "", m, s);
- else
- (void) sprintf (tstr, "%*d:%02d:%02d", nd, tisneg ? -h : h, m, s);
-
- (void) flog_log (r, c, t, tstr);
- f_string (r, c, tstr);
- }
-
- /* print angle ra, in radians, in ra hours as hh:mm.m at [r,c]
- * N.B. we assume ra is >= 0.
- */
- f_ra (r, c, ra)
- int r, c;
- double ra;
- {
- f_sexad (r, c, 2, 1, 24, radhr(ra));
- }
-
- /* print time, t, as hh:mm:ss */
- f_time (r, c, t)
- int r, c;
- double t;
- {
- f_sexag (r, c, 2, t);
- }
-
- /* print time, t, as +/-hh:mm:ss (don't show leading +) */
- f_signtime (r, c, t)
- int r, c;
- double t;
- {
- f_sexag (r, c, 3, t);
- }
-
- /* print time, t, as hh:mm */
- f_mtime (r, c, t)
- int r, c;
- double t;
- {
- f_sexad (r, c, 2, 0, 24, t);
- }
-
- /* print angle, a, in rads, as degress at [r,c] in form ddd:mm */
- f_angle(r, c, a)
- int r, c;
- double a;
- {
- f_sexad (r, c, 3, 0, 360, raddeg(a));
- }
-
- /* print angle, a, in rads, as degress at [r,c] in form dddd:mm:ss */
- f_gangle(r, c, a)
- int r, c;
- double a;
- {
- f_sexag (r, c, 4, raddeg(a));
- }
-
- /* print the given modified Julian date, jd, as the starting date at [r,c]
- * in the form mm/dd/yyyy.
- */
- f_date (r, c, jd)
- int r, c;
- double jd;
- {
- char dstr[32];
- int m, y;
- double d, tmp;
-
- mjd_cal (jd, &m, &d, &y);
- (void) sprintf (dstr, "%2d/%02d/%04d", m, (int)(d), y);
-
- /* shadow to the plot subsystem as years. */
- mjd_year (jd, &tmp);
- (void) flog_log (r, c, tmp, dstr);
- f_string (r, c, dstr);
- }
-
- /* print the given double as a rounded int, with the given format.
- * this is used to plot full precision, but display far less.
- * N.B. caller beware that we really do expect fmt to refer to an int, not
- * a long for example. also beware of range that implies.
- */
- f_int (row, col, fmt, f)
- int row, col;
- char fmt[];
- double f;
- {
- char str[80];
- int i;
-
- i = (f < 0) ? (int)(f-0.5) : (int)(f+0.5);
- (void) sprintf (str, fmt, i);
-
- (void) flog_log (row, col, f, str);
- f_string (row, col, str);
- }
-
- f_char (row, col, c)
- int row, col;
- char c;
- {
- if (f_scrnoff)
- return;
- c_pos (row, col);
- putchar (c);
- }
-
- f_string (r, c, s)
- int r, c;
- char *s;
- {
- if (f_scrnoff)
- return;
- c_pos (r, c);
- (void) fputs (s, stdout);
- }
-
- f_double (r, c, fmt, f)
- int r, c;
- char *fmt;
- double f;
- {
- char str[80];
- (void) sprintf (str, fmt, f);
- (void) flog_log (r, c, f, str);
- f_string (r, c, str);
- }
-
- /* print prompt line */
- f_prompt (p)
- char *p;
- {
- c_pos (R_PROMPT, C_PROMPT);
- c_eol ();
- c_pos (R_PROMPT, C_PROMPT);
- (void) fputs (p, stdout);
- }
-
- /* clear from [r,c] to end of line, if we are drawing now. */
- f_eol (r, c)
- int r, c;
- {
- if (!f_scrnoff) {
- c_pos (r, c);
- c_eol();
- }
- }
-
- /* print a message and wait for op to hit any key */
- f_msg (m)
- char *m;
- {
- f_prompt (m);
- (void) read_char();
- }
-
- /* crack a line of the form X?X?X into its components,
- * where X is an integer and ? can be any character except '0-9' or '-',
- * such as ':' or '/'.
- * only change those fields that are specified:
- * eg: ::10 only changes *s
- * 10 only changes *d
- * 10:0 changes *d and *m
- * if see '-' anywhere, first non-zero component will be made negative.
- */
- f_sscansex (bp, d, m, s)
- char *bp;
- int *d, *m, *s;
- {
- char c;
- int *p = d;
- int *nonzp = 0;
- int sawneg = 0;
- int innum = 0;
-
- while (c = *bp++)
- if (c >= '0' && c <= '9') {
- if (!innum) {
- *p = 0;
- innum = 1;
- }
- *p = *p*10 + (c - '0');
- if (*p && !nonzp)
- nonzp = p;
- } else if (c == '-') {
- sawneg = 1;
- } else if (c != ' ') {
- /* advance to next component */
- p = (p == d) ? m : s;
- innum = 0;
- }
-
- if (sawneg && nonzp)
- *nonzp = -*nonzp;
- }
-
- /* crack a floating date string, bp, of the form m/d/y, where d may be a
- * floating point number, into its components.
- * leave any component unspecified unchanged.
- * actually, the slashes may be anything but digits or a decimal point.
- * this is functionally the same as f_sscansex() exept we allow for
- * the day portion to be real, and we don't handle negative numbers.
- * maybe someday we could make a combined one and use it everywhere.
- */
- f_sscandate (bp, m, d, y)
- char *bp;
- int *m, *y;
- double *d;
- {
- char *bp0, c;
-
- bp0 = bp;
- while ((c = *bp++) && (c >= '0' && c <= '9'))
- continue;
- if (bp > bp0+1)
- *m = atoi (bp0);
- if (c == '\0')
- return;
- bp0 = bp;
- while ((c = *bp++) && (c >= '0' && c <= '9' || c == '.'))
- continue;
- if (bp > bp0+1)
- *d = atof (bp0);
- if (c == '\0')
- return;
- bp0 = bp;
- while (c = *bp++)
- continue;
- if (bp > bp0+1)
- *y = atoi (bp0);
- }
-
- /* just like dec_sex() but makes the first non-zero element negative if
- * x is negative (instead of returning a sign flag).
- */
- f_dec_sexsign (x, h, m, s)
- double x;
- int *h, *m, *s;
- {
- int n;
- dec_sex (x, h, m, s, &n);
- if (n) {
- if (*h)
- *h = -*h;
- else if (*m)
- *m = -*m;
- else
- *s = -*s;
- }
- }
-
- /* return 1 if bp looks like a decimal year; else 0.
- * any number greater than 12 or less than 0 is assumed to be a year, or any
- * string with exactly one decimal point, an optional minus sign, and nothing
- * else but digits.
- */
- decimal_year (bp)
- char *bp;
- {
- char c;
- int ndig = 0, ndp = 0, nneg = 0, nchar = 0;
- double y = atof(bp);
-
- while (c = *bp++) {
- nchar++;
- if (c >= '0' && c <= '9')
- ndig++;
- else if (c == '.')
- ndp++;
- else if (c == '-')
- nneg++;
- }
-
- return (y > 12 || y < 0
- || (ndp == 1 && nneg <= 1 && nchar == ndig+ndp+nneg));
- }
-