Ignore:
Timestamp:
Jun 15, 2004, 6:54:12 PM (21 years ago)
Author:
cmv
Message:

nouvelle version de xephem/libastro (3.6) cmv 15/6/04

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaExt/XephemAstroLib/formats.c

    r1719 r2551  
    55#include <string.h>
    66
    7 #include "P_.h"
    87#include "astro.h"
    98#include "preferences.h"
     
    1716 *      600:    <w>:mm.m
    1817 *      60:     <w>:mm
    19  */
    20 void
    21 fs_sexa (out, a, w, fracbase)
    22 char *out;
    23 double a;
    24 int w;
    25 int fracbase;
    26 {
     18 * return number of characters written to out, not counting final '\0'.
     19 */
     20int
     21fs_sexa (char *out, double a, int w, int fracbase)
     22{
     23        char *out0 = out;
    2724        unsigned long n;
    2825        int d;
     
    4441        /* form the whole part; "negative 0" is a special case */
    4542        if (isneg && d == 0)
    46             (void) sprintf (out, "%*s-0", w-2, "");
     43            out += sprintf (out, "%*s-0", w-2, "");
    4744        else
    48             (void) sprintf (out, "%*d", w, isneg ? -d : d);
    49         out += w;
     45            out += sprintf (out, "%*d", w, isneg ? -d : d);
    5046
    5147        /* do the rest */
     
    5349        case 60:        /* dd:mm */
    5450            m = f/(fracbase/60);
    55             (void) sprintf (out, ":%02d", m);
     51            out += sprintf (out, ":%02d", m);
    5652            break;
    5753        case 600:       /* dd:mm.m */
    58             (void) sprintf (out, ":%02d.%1d", f/10, f%10);
     54            out += sprintf (out, ":%02d.%1d", f/10, f%10);
    5955            break;
    6056        case 3600:      /* dd:mm:ss */
    6157            m = f/(fracbase/60);
    6258            s = f%(fracbase/60);
    63             (void) sprintf (out, ":%02d:%02d", m, s);
     59            out += sprintf (out, ":%02d:%02d", m, s);
    6460            break;
    6561        case 36000:     /* dd:mm:ss.s*/
    6662            m = f/(fracbase/60);
    6763            s = f%(fracbase/60);
    68             (void) sprintf (out, ":%02d:%02d.%1d", m, s/10, s%10);
     64            out += sprintf (out, ":%02d:%02d.%1d", m, s/10, s%10);
    6965            break;
    7066        case 360000:    /* dd:mm:ss.ss */
    7167            m = f/(fracbase/60);
    7268            s = f%(fracbase/60);
    73             (void) sprintf (out, ":%02d:%02d.%02d", m, s/100, s%100);
     69            out += sprintf (out, ":%02d:%02d.%02d", m, s/100, s%100);
    7470            break;
    7571        default:
    7672            printf ("fs_sexa: unknown fracbase: %d\n", fracbase);
    77             exit(1);
     73            abort();
    7874        }
     75
     76        return (out - out0);
    7977}
    8078
    8179/* put the given modified Julian date, jd, in out[] according to preference
    8280 * format.
    83  */
    84 void
    85 fs_date (out, jd)
    86 char out[];
    87 double jd;
     81 * return number of characters written to out, not counting final '\0'.
     82 */
     83int
     84fs_date (char out[], double jd)
    8885{
    8986        int p = pref_get (PREF_DATE_FORMAT);
     87        char *out0 = out;
    9088        int m, y;
    9189        double d;
     
    10098        switch (p) {
    10199        case PREF_YMD:
    102             (void) sprintf (out, "%4d/%02d/%02.6g", y, m, d);
     100            out += sprintf (out, "%4d/%02d/%02.6g", y, m, d);
    103101            break;
    104102        case PREF_DMY:
    105             (void) sprintf (out, "%2.6g/%02d/%-4d", d, m, y);
     103            out += sprintf (out, "%2.6g/%02d/%-4d", d, m, y);
    106104            break;
    107105        case PREF_MDY:
    108             (void) sprintf (out, "%2d/%02.6g/%-4d", m, d, y);
     106            out += sprintf (out, "%2d/%02.6g/%-4d", m, d, y);
    109107            break;
    110108        default:
    111109            printf ("fs_date: bad date pref: %d\n", p);
    112             exit (1);
     110            abort();
    113111        }
    114 }
    115 
    116 /* scan a sexagesimal string and update a double. the string is of the form
    117  *   H:M:S. a negative value may be indicated by a '-' char before any
    118  *   component. All components may be integral or real. In addition to ':' the
    119  *    separator may also be '/' or ';' or ',' or '-'.
    120  * any components not specified in bp[] are copied from old's.
    121  *   eg:  ::10  only changes S
    122  *        10    only changes H
    123  *        10:0  changes H and M
    124  */
    125 void
    126 f_scansex (o, bp, np)
    127 double o;       /* old value */
    128 char bp[];      /* input string */
    129 double *np;     /* new value */
    130 {
    131         double oh, om, os;
    132         double nh, nm, ns;
    133         int nneg;
    134         double tmp;
    135         char c;
    136 
    137         /* fast macro to scan each segment of bp */
    138 #define SCANSEX(new,old)                                                \
    139         if (*bp == '-') {nneg = 1; bp++;}                               \
    140         if (sscanf (bp, "%lf", &new) != 1) new = old;                   \
    141         while ((c=(*bp)) != '\0') {                                     \
    142             bp++;                                                       \
    143             if (c==':' || c=='/' || c==';' || c==',' || c=='-')         \
    144                 break;                                                  \
    145         }
    146 
    147         /* get h:m:s components of o in case bp[] defers.
    148          * and constrain to positive for now.
    149          */
    150         if (o < 0.0)
    151             o = -o;
    152         oh = floor(o);
    153         tmp = (o - oh)*60.0;
    154         om = floor(tmp);
    155         os = (tmp - om)*60.0;
    156        
    157         /* round to small portion of a second to reduce differencing errors. */
    158         if (os > 59.99999) {
    159             os = 0.0;
    160             if ((om += 1.0) >= 60.0) {
    161                 om = 0.0;
    162                 oh += 1.0;
    163             }
    164         }
    165 
    166         /* scan each component of the buffer */
    167         while (*bp == ' ') bp++;
    168         nneg = 0;
    169         SCANSEX (nh, oh)
    170         SCANSEX (nm, om)
    171         SCANSEX (ns, os)
    172 
    173         /* back to hours */
    174         tmp = ns/3600.0 + nm/60.0 + nh;
    175         if (nneg)
    176             tmp = -tmp;
    177 
    178         *np = tmp;
     112
     113        return (out - out0);
     114}
     115
     116
     117/* convert sexagesimal string str AxBxC to double.
     118 *   x can be anything non-numeric. Any missing A, B or C will be assumed 0.
     119 *   optional - and + can be anywhere.
     120 * return 0 if ok, -1 if can't find a thing.
     121 */
     122int
     123f_scansexa (
     124const char *str0,       /* input string */
     125double *dp)             /* cracked value, if return 0 */
     126{
     127        double a = 0, b = 0, c = 0;
     128        char str[128];
     129        char *neg;
     130        int r;
     131
     132        /* copy str0 so we can play with it */
     133        strncpy (str, str0, sizeof(str)-1);
     134        str[sizeof(str)-1] = '\0';
     135
     136        neg = strchr(str, '-');
     137        if (neg)
     138            *neg = ' ';
     139        r = sscanf (str, "%lf%*[^0-9]%lf%*[^0-9]%lf", &a, &b, &c);
     140        if (r < 1)
     141            return (-1);
     142        *dp = a + b/60 + c/3600;
     143        if (neg)
     144            *dp *= -1;
     145        return (0);
    179146}
    180147
     
    182149 *   PREF_DATE_FORMAT preference into its components. allow the day to be a
    183150 *   floating point number,
    184  * a lone component is always a year if it contains a decimal point or pref
    185  *   is MDY or DMY and it is not a reasonable month or day value, respectively.
    186  * leave any unspecified component unchanged.
    187  * actually, the slashes may be anything but digits or a decimal point.
     151 * actually the slashes may be anything but digits.
     152 * a lone component with a decimal point is considered a year.
    188153 */
    189154void
    190 f_sscandate (bp, pref, m, d, y)
    191 char *bp;
    192 int pref;       /* one of PREF_X for PREF_DATE_FORMAT */
    193 int *m, *y;
    194 double *d;
    195 {
    196         double comp[3]; /* the three components */
    197         int set[3];     /* set[i] is 1 if component i is present */
    198         int in;         /* scan state: 1 while we are in a component */
    199         int ncomp;      /* incremented as each component is discovered */
    200         int ndp;        /* number of decimal points in last component */
    201         char *bp0 = NULL, c;
    202 
    203         set[0] = set[1] = set[2] = 0;
    204         ncomp = 0;
    205         in = 0;
    206         ndp = 0;
    207 
    208         /* scan the input string.
    209          * '\0' counts as a component terminator too.
    210          */
    211         do {
    212             /* here, *bp is the next character to be investigated */
    213             c = *bp;
    214             if (c == '.' || isdigit(c) || (c == '-' && !in)) {
    215                 /* found what passes for a floating point number */
    216                 if (in == 0) {
    217                     /* save the beginning of it in bp0 and init ndp */
    218                     bp0 = bp;
    219                     in = 1;
    220                     ndp = 0;
    221                 }
    222                 if (c == '.')
    223                     ndp++;
    224             } else if (c != ' ') {
    225                 /* not in a number now ... */
    226                 if (in) {
    227                     /* ... but we *were* in a number, so it counts */
    228                     if (ncomp >= 3)
    229                         return; /* too many components.. just bail */
    230                     comp[ncomp] = atod (bp0);
    231                     set[ncomp] = 1;
    232                     in = 0;
    233                 }
    234 
    235                 /* regardless, a non-blank non-float means another component */
    236                 ncomp++;
     155f_sscandate (
     156char *bp,
     157int pref,       /* one of PREF_X for PREF_DATE_FORMAT */
     158int *m,
     159double *d,
     160int *y)
     161{
     162        double c[3]; /* the three components */
     163        int n;
     164
     165        memset (c, 0, sizeof(c));
     166        n = sscanf (bp, "%lf%*[^0-9]%lf%*[^0-9]%lf", &c[0], &c[1], &c[2]);
     167        if (n == 1 && (strchr(bp, '.')
     168                        || (pref == PREF_MDY && (c[0] < 1 || c[0] > 12))
     169                        || (pref == PREF_DMY && (c[0] < 1 || c[0] > 31)))) {
     170            double Mjd;
     171            year_mjd (c[0], &Mjd);
     172            mjd_cal (Mjd, m, d, y);
     173        } else {
     174            switch (pref) {
     175            case PREF_MDY:
     176                if (n > 0 && c[0] != 0)
     177                    *m = (int)c[0];
     178                if (n > 1 && c[1] != 0)
     179                    *d = c[1];
     180                if (n > 2 && c[2] != 0)
     181                    *y = (int)c[2];
     182                break;
     183            case PREF_YMD:
     184                if (n > 0 && c[0] != 0)
     185                    *y = (int)c[0];
     186                if (n > 1 && c[1] != 0)
     187                    *m = (int)c[1];
     188                if (n > 2 && c[2] != 0)
     189                    *d = c[2];
     190                break;
     191            case PREF_DMY:
     192                if (n > 1 && c[0] != 0)
     193                    *d = c[0];
     194                if (n > 2 && c[1] != 0)
     195                    *m = (int)c[1];
     196                if (n > 3 && c[2] != 0)
     197                    *y = (int)c[2];
     198                break;
    237199            }
    238             bp++;
    239         } while (c);
    240 
    241         /* it's a decimal year if there is exactly one component and
    242          *   it contains a decimal point
    243          *   or we are in MDY format and it's not in the range 1..12
    244          *   or we are in DMY format and it's not int the rangle 1..31
    245          */
    246         if (ncomp == 1 &&
    247                 (ndp > 0
    248                  || (pref == PREF_MDY && !(comp[0] >= 1 && comp[0] <= 12))
    249                  || (pref == PREF_DMY && !(comp[0] >= 1 && comp[0] <= 31)))) {
    250             double Mjd;
    251             year_mjd (comp[0], &Mjd);
    252             mjd_cal (Mjd, m, d, y);
    253             return;
    254200        }
    255 
    256         switch (pref) {
    257         case PREF_MDY:
    258             if (set[0]) *m = (int)comp[0];
    259             if (set[1]) *d = comp[1];
    260             if (set[2]) *y = (int)comp[2];
    261             break;
    262         case PREF_YMD:
    263             if (set[0]) *y = (int)comp[0];
    264             if (set[1]) *m = (int)comp[1];
    265             if (set[2]) *d = comp[2];
    266             break;
    267         case PREF_DMY:
    268             if (set[0]) *d = comp[0];
    269             if (set[1]) *m = (int)comp[1];
    270             if (set[2]) *y = (int)comp[2];
    271             break;
    272         }
    273 }
    274 
    275 /* given a string of the form xx:mm[:ss] or xx:mm.dd, convert it to a double at
    276  * *dp. actually, ':' may also be ';', '/' or ',' too. all components may be
    277  * floats.
    278  * return -1 if trouble, else 0
    279  */
    280 int
    281 scansex (str, dp)
    282 char *str;
    283 double *dp;
    284 {
    285         double x, m = 0.0, s = 0.0;
    286         int isneg;
    287         int nf;
    288 
    289         while (isspace(*str))
    290             str++;
    291         if (*str == '-') {
    292             isneg = 1;
    293             str++;
    294         } else
    295             isneg = 0;
    296 
    297         nf = sscanf (str, "%lf%*[:;/,]%lf%*[:;/,]%lf", &x, &m, &s);
    298         if (nf < 1)
    299             return (-1);
    300         *dp = x + m/60.0 + s/3600.0;
    301         if (isneg)
    302             *dp = - *dp;
    303         return (0);
    304201}
    305202
    306203/* For RCS Only -- Do Not Edit */
    307 static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: formats.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
     204static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: formats.c,v $ $Date: 2004-06-15 16:52:38 $ $Revision: 1.3 $ $Name: not supported by cvs2svn $"};
Note: See TracChangeset for help on using the changeset viewer.