1 /* SWISSEPH
2
3 Authors: Dieter Koch and Alois Treindl, Astrodienst Z�rich
4
5 **************************************************************/
6 /* Copyright (C) 1997 - 2021 Astrodienst AG, Switzerland. All rights reserved.
7
8 License conditions
9 ------------------
10
11 This file is part of Swiss Ephemeris.
12
13 Swiss Ephemeris is distributed with NO WARRANTY OF ANY KIND. No author
14 or distributor accepts any responsibility for the consequences of using it,
15 or for whether it serves any particular purpose or works at all, unless he
16 or she says so in writing.
17
18 Swiss Ephemeris is made available by its authors under a dual licensing
19 system. The software developer, who uses any part of Swiss Ephemeris
20 in his or her software, must choose between one of the two license models,
21 which are
22 a) GNU Affero General Public License (AGPL)
23 b) Swiss Ephemeris Professional License
24
25 The choice must be made before the software developer distributes software
26 containing parts of Swiss Ephemeris to others, and before any public
27 service using the developed software is activated.
28
29 If the developer choses the AGPL software license, he or she must fulfill
30 the conditions of that license, which includes the obligation to place his
31 or her whole software project under the AGPL or a compatible license.
32 See https://www.gnu.org/licenses/agpl-3.0.html
33
34 If the developer choses the Swiss Ephemeris Professional license,
35 he must follow the instructions as found in http://www.astro.com/swisseph/
36 and purchase the Swiss Ephemeris Professional Edition from Astrodienst
37 and sign the corresponding license contract.
38
39 The License grants you the right to use, copy, modify and redistribute
40 Swiss Ephemeris, but only under certain conditions described in the License.
41 Among other things, the License requires that the copyright notices and
42 this notice be preserved on all copies.
43
44 Authors of the Swiss Ephemeris: Dieter Koch and Alois Treindl
45
46 The authors of Swiss Ephemeris have no control or influence over any of
47 the derived works, i.e. over software or services created by other
48 programmers which use Swiss Ephemeris functions.
49
50 The names of the authors or of the copyright holder (Astrodienst) must not
51 be used for promoting any software, product or service which uses or contains
52 the Swiss Ephemeris. This copyright notice is the ONLY place where the
53 names of the authors can legally appear, except in cases where they have
54 given special permission in writing.
55
56 The trademarks 'Swiss Ephemeris' and 'Swiss Ephemeris inside' may be used
57 for promoting such software, products or services.
58 */
59
60 # define SMOD_LUNAR 1
61 # define SMOD_HOW 2 /* an option for Lunar */
62 # define SMOD_SOLAR 4
63 # define SMOD_LOCAL 8 /* an option for Solar */
64 # define SMOD_TOTAL 16
65 # define SMOD_ANNULAR 32 /* count as penumbral for Lunar */
66 # define SMOD_ANNTOT 64
67 # define SMOD_PARTIAL 128
68 # define SMOD_ALL (SMOD_TOTAL| SMOD_ANNULAR|SMOD_PARTIAL|SMOD_ANNTOT)
69 # define SMOD_RISE 256
70 # define SMOD_METR 512
71 # define SMOD_HOCAL 1024
72
73
74 /* attention: Microsoft Compiler does not accept strings > 2048 char */
75 static char *infocmd0 = "\n\
76 Sweclips computes solar and lunar eclipses,\n\
77 rises, sets, and meridian transits for planets and fixed stars\n\
78 Input can either be a date or an absolute julian day number.\n\
79 \n";
80
81 static char *infocmd1 = "\n\
82 Command line options:\n\
83 -lunar lunar eclipse\n\
84 -solar solar eclipse\n\
85 -hocal hocallist format\n\
86 -local local solar eclipse\n\
87 -annular\n\
88 -total\n\
89 -partial\n\
90 -rise next rise and set\n\
91 -metr next meridian transits (culminations)\n\
92 -lon... geogr. longitude D.MMSS\n\
93 -lat... geogr. longitude D.MMSS\n\
94 -p. planet (like swetest.c)\n\
95 -edirPATH change the directory of the ephemeris files \n\
96 -head don\'t print the header before the planet data. This option\n\
97 is useful when you want to paste the output into a\n\
98 spreadsheet for displaying graphical ephemeris.\n\
99 +head header before every step (with -s..) \n\
100 -bDATE use this begin date instead of asking; use -b1.1.1992 if\n\
101 the begin date string contains blanks; use format -bj2400000.5\n\
102 to express the date as absolute Julian day number.\n\
103 Note: the date format is day month year (European style).\n\
104 \n";
105
106 static char *infocmd2 = "\
107 -eswe swiss ephemeris\n\
108 -ejpl jpl ephemeris (DE406), or with ephemeris file name\n\
109 -ejplDE200.cdrom \n\
110 -emos moshier ephemeris\n\
111 -?, -h display whole info\n\
112 -hcmd display commands\n\
113 -hdate display input date format\n";
114
115 static char *infodate = "\n\
116 Date entry:\n\
117 In the interactive mode, when you are asked for a start date,\n\
118 you can enter data in one of the following formats:\n\
119 \n\
120 1.2.1991 three integers separated by a nondigit character for\n\
121 day month year. Dates are interpreted as Gregorian\n\
122 after 4.10.1582 and as Julian Calender before.\n\
123 Time is always set to midnight.\n\
124 If the three letters jul are appended to the date,\n\
125 the Julian calendar is used even after 1582.\n\
126 If the four letters greg are appended to the date,\n\
127 the Gregorian calendar is used even before 1582.\n\
128 \n\
129 j2400123.67 the letter j followed by a real number, for\n\
130 the absolute Julian daynumber of the start date.\n\
131 Fraction .5 indicates midnight, fraction .0\n\
132 indicates noon, other times of the day can be\n\
133 chosen accordingly.\n\
134 \n";
135 /**************************************************************/
136
137 #include "sweodef.h"
138 #include "swephexp.h"
139
140 #if MSDOS
141 # include <direct.h>
142 # include <dos.h>
143 # ifdef _MSC_VER
144 # include <sys\types.h>
145 # endif
146 #endif
147
148 #ifdef MACOS
149 # include <console.h>
150 #endif
151
152
153 #define J2000 2451545.0 /* 2000 January 1.5 */
154 #define square_sum(x) (x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
155 #define SEFLG_EPHMASK (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH)
156
157 #define BIT_ROUND_SEC 1
158 #define BIT_ROUND_MIN 2
159 #define BIT_ZODIAC 4
160 #define BIT_LZEROES 8
161
162 # define ECL_LUN_PENUMBRAL 1 /* eclipse types for hocal list */
163 # define ECL_LUN_PARTIAL 2
164 # define ECL_LUN_TOTAL 3
165 # define ECL_SOL_PARTIAL 4
166 # define ECL_SOL_ANNULAR 5
167 # define ECL_SOL_TOTAL 6
168
169 static char *zod_nam[] = {"ar", "ta", "ge", "cn", "le", "vi",
170 "li", "sc", "sa", "cp", "aq", "pi"};
171
172 static char *dms(double xv, int32 iflg);
173 static char *hms(double x, int32 iflag);
174 static int do_calc(double tjd, int ipl, long iflag, double *x, char *serr);
175 static void do_printf(char *info);
176 static int make_ephemeris_path(long iflag, char *argv0);
177 static char *hms_from_tjd(double x);
178 static int cut_str_any(char *s, char *cutlist, char *cpos[], int nmax);
179 static int letter_to_ipl(int letter);
180
main(int argc,char * argv[])181 int main(int argc, char *argv[])
182 {
183 char saves[AS_MAXCH];
184 char s1[AS_MAXCH], s2[AS_MAXCH];
185 char serr[AS_MAXCH], serr_save[AS_MAXCH], serr_warn[AS_MAXCH],
186 sout[AS_MAXCH];
187 char *sp, *sp2;
188 char *fmt = "PLBRS";
189 int i, ii;
190 int smod = 0;
191 int ecl_type = 0;
192 int jmon, jday, jyear;
193 double jut = 0.0;
194 long nstep = 1;
195 double x[6];
196 char ephepath[AS_MAXCH];
197 char fname[AS_MAXCH];
198 char sdate[AS_MAXCH];
199 char *begindate = NULL;
200 long iflag = 0;
201 long eclflag;
202 double geopos[20], attr[20], tret[20];
203 double a, b, c;
204 int whicheph = SEFLG_SWIEPH;
205 short with_header = TRUE;
206 int gregflag = SE_GREG_CAL;
207 double tjd = 2415020.5, t_ut;
208 double dt;
209 int direction = 1;
210 AS_BOOL direction_flag = FALSE;
211 int32 ipl = 0;
212 char starname[AS_MAXCH];
213 int32 search_flag = 0;
214 char slon[30], slat[30];
215 serr[0] = serr_save[0] = serr_warn[0] = saves[0] = '\0';
216 starname[0] = '\0';
217 strcpy(ephepath, SE_EPHE_PATH);
218 strcpy(fname, SE_FNAME_DE406);
219 strcpy(slon, "8.33"); /* geographical position of Zurich */
220 strcpy(slat, "47.23");
221 /*
222 * command line
223 */
224 search_flag = SE_ECL_CENTRAL | SE_ECL_NONCENTRAL;
225 smod = SMOD_SOLAR;
226 for (i = 1; i < argc; i++) {
227 if (strncmp(argv[i], "-head", 5) == 0) {
228 with_header = FALSE;
229 } else if (strcmp(argv[i], "-lunar") == 0) {
230 smod |= SMOD_LUNAR;
231 smod &= ~SMOD_SOLAR;
232 } else if (strcmp(argv[i], "-hocal") == 0) {
233 smod |= SMOD_HOCAL;
234 } else if (strcmp(argv[i], "-solar") == 0) {
235 smod |= SMOD_SOLAR;
236 } else if (strcmp(argv[i], "-how") == 0) {
237 smod |= SMOD_HOW;
238 } else if (strcmp(argv[i], "-total") == 0) {
239 smod |= SMOD_TOTAL;
240 } else if (strcmp(argv[i], "-annular") == 0) {
241 smod |= SMOD_ANNULAR;
242 } else if (strcmp(argv[i], "-anntot") == 0) {
243 smod |= SMOD_ANNTOT;
244 } else if (strcmp(argv[i], "-partial") == 0) {
245 smod |= SMOD_PARTIAL;
246 } else if (strcmp(argv[i], "-noncentral") == 0) {
247 search_flag &= ~SE_ECL_CENTRAL;
248 search_flag |= SE_ECL_NONCENTRAL;
249 } else if (strcmp(argv[i], "-central") == 0) {
250 search_flag &= ~SE_ECL_NONCENTRAL;
251 search_flag |= SE_ECL_CENTRAL;
252 } else if (strcmp(argv[i], "-local") == 0) {
253 smod |= SMOD_LOCAL;
254 } else if (strcmp(argv[i], "-rise") == 0) {
255 smod |= SMOD_RISE;
256 smod &= ~SMOD_SOLAR;
257 } else if (strcmp(argv[i], "-metr") == 0) {
258 smod |= SMOD_METR;
259 smod &= ~SMOD_SOLAR;
260 } else if (strncmp(argv[i], "-j", 2) == 0) {
261 begindate = argv[i] + 1;
262 } else if (strncmp(argv[i], "-lon", 4) == 0) {
263 strcpy(slon, argv[i] + 4);
264 } else if (strncmp(argv[i], "-lat", 4) == 0) {
265 strcpy(slat, argv[i] + 4);
266 } else if (strncmp(argv[i], "-ejpl", 5) == 0) {
267 whicheph = SEFLG_JPLEPH;
268 strcpy(ephepath, SE_EPHE_PATH);
269 if (*(argv[i]+5) != '\0')
270 strcpy(fname, argv[i]+5);
271 } else if (strcmp(argv[i], "-eswe") == 0) {
272 whicheph = SEFLG_SWIEPH;
273 strcpy(ephepath, SE_EPHE_PATH);
274 } else if (strcmp(argv[i], "-emos") == 0) {
275 whicheph = SEFLG_MOSEPH;
276 } else if (strncmp(argv[i], "-edir", 5) == 0) {
277 if (*(argv[i]+5) != '\0')
278 strcpy(ephepath, argv[i]+5);
279 } else if (strncmp(argv[i], "-n", 2) == 0) {
280 nstep = atoi(argv[i]+2);
281 } else if (strcmp(argv[i], "-bwd") == 0) {
282 direction = -1;
283 direction_flag = TRUE;
284 } else if (strncmp(argv[i], "-b", 2) == 0) {
285 begindate = argv[i] + 2;
286 } else if (strncmp(argv[i], "-p", 2) == 0) {
287 sp = argv[i] + 2;
288 if (strlen(sp) == 1)
289 ipl = letter_to_ipl(*sp);
290 else
291 strcpy(starname, sp);
292 } else if (strncmp(argv[i], "-h", 2) == 0
293 || strncmp(argv[i], "-?", 2) == 0) {
294 sp = argv[i]+2;
295 if (*sp == 'c' || *sp == '\0') {
296 do_printf(infocmd0);
297 do_printf(infocmd1);
298 do_printf(infocmd2);
299 }
300 if (*sp == 'd' || *sp == '\0')
301 do_printf(infodate);
302 goto end_main;
303 } else {
304 sprintf(sout, "illegal option %s\n", argv[i]);
305 do_printf(sout);
306 exit(1);
307 }
308 }
309 if (smod & (SMOD_LUNAR | SMOD_SOLAR)) {
310 if ((smod & SMOD_ALL) == 0) /* no selective eclipse type set, set all */
311 smod |= SMOD_ALL;
312 if (smod & SMOD_TOTAL) search_flag |= SE_ECL_TOTAL;
313 if (smod & SMOD_ANNULAR) search_flag |= SE_ECL_ANNULAR | SE_ECL_PENUMBRAL;
314 if (smod & SMOD_PARTIAL) search_flag |= SE_ECL_PARTIAL;
315 if (smod & SMOD_ANNTOT) search_flag |= SE_ECL_ANNULAR_TOTAL;
316 }
317 if (with_header) {
318 for (i = 0; i < argc; i++) {
319 do_printf(argv[i]);
320 do_printf(" ");
321 }
322 do_printf("\n");
323 }
324 iflag = (iflag & ~SEFLG_EPHMASK) | whicheph;
325 if (strpbrk(fmt, "SsQ") != NULL)
326 iflag |= SEFLG_SPEED;
327 if (*ephepath != '\0')
328 swe_set_ephe_path(ephepath);
329 else if (make_ephemeris_path(iflag, argv[0]) == ERR) {
330 iflag = (iflag & ~SEFLG_EPHMASK) | SEFLG_MOSEPH;
331 whicheph = SEFLG_MOSEPH;
332 }
333 if (whicheph & SEFLG_JPLEPH)
334 swe_set_jpl_file(fname);
335 serr[0] = serr_save[0] = serr_warn[0] = '\0';
336 if (begindate == NULL) {
337 do_printf("\nDate ?");
338 sdate[0] = '\0';
339 gets(sdate);
340 } else {
341 strcpy(sdate, begindate);
342 begindate = "."; /* to exit afterwards */
343 }
344 sp = sdate;
345 if (*sp == 'j') { /* it's a day number */
346 if ((sp2 = strchr(sp, ',')) != NULL)
347 *sp2 = '.';
348 sscanf(sp+1,"%lf", &tjd);
349 if (tjd < 2299160.5)
350 gregflag = SE_JUL_CAL;
351 else
352 gregflag = SE_GREG_CAL;
353 if (strstr(sp, "jul") != NULL)
354 gregflag = SE_JUL_CAL;
355 else if (strstr(sp, "greg") != NULL)
356 gregflag = SE_GREG_CAL;
357 swe_revjul(tjd, gregflag, &jyear, &jmon, &jday, &jut);
358 } else {
359 if (sscanf (sp, "%d%*c%d%*c%d", &jday,&jmon,&jyear) < 1) exit(1);
360 if ((long) jyear * 10000L + (long) jmon * 100L + (long) jday <
361 15821015L)
362 gregflag = SE_JUL_CAL;
363 else
364 gregflag = SE_GREG_CAL;
365 if (strstr(sp, "jul") != NULL)
366 gregflag = SE_JUL_CAL;
367 else if (strstr(sp, "greg") != NULL)
368 gregflag = SE_GREG_CAL;
369 jut = 0;
370 tjd = swe_julday(jyear,jmon,jday,jut,gregflag);
371 }
372 if (with_header) {
373 sprintf(sout, "begin date (dmy) %d.%d.%d\n", jday, jmon, jyear);
374 do_printf(sout);
375
376 }
377 /*
378 * for local eclipses: set geographic position of observer
379 */
380 if (smod & (SMOD_LOCAL|SMOD_RISE|SMOD_METR)) {
381 sscanf(slon,"%lf", &a);
382 b = fmod(a * 10000, 100);
383 c = a - b / 10000;
384 c = fmod(c, 1) * 100;
385 geopos[0] = a - fmod( a, 1) + c / 60 + b / 3600;
386 sscanf(slat,"%lf", &a);
387 b = fmod(a * 10000, 100);
388 c = a - b / 10000;
389 c = fmod(c, 1) * 100;
390 geopos[1] = a - fmod( a, 1) + c / 60 + b / 3600;
391 swe_set_topo(geopos[0], geopos[1], 0);
392 }
393 t_ut = tjd;
394 for (ii = 0; ii < nstep; ii++) {
395 *sout = '\0';
396 if ((smod & SMOD_LUNAR) && (smod & SMOD_HOW)) {
397 if ((eclflag = swe_lun_eclipse_how(t_ut, whicheph, geopos, attr, serr)) ==
398 ERR) {
399 do_printf(serr);
400 exit(0);
401 } else {
402 ecl_type = 0;
403 if (eclflag & SE_ECL_TOTAL) {
404 sprintf(sout, "total lunar eclipse: %f o/o \n", attr[0]);
405 ecl_type = ECL_LUN_TOTAL;
406 } else if (eclflag & SE_ECL_PARTIAL) {
407 sprintf(sout, "partial lunar eclipse: %f o/o \n", attr[0]);
408 ecl_type = ECL_LUN_PARTIAL;
409 } else if (eclflag & SE_ECL_PENUMBRAL) {
410 sprintf(sout, "penumbral lunar eclipse: %f o/o \n", attr[0]);
411 ecl_type = ECL_LUN_PENUMBRAL;
412 } else {
413 sprintf(sout, "no lunar eclipse \n");
414 }
415 do_printf(sout);
416 }
417 }
418 if ((smod & SMOD_LUNAR) && ! (smod & SMOD_HOW)) {
419 if ((eclflag = swe_lun_eclipse_when(t_ut, whicheph, search_flag,
420 tret, direction_flag, serr)) == ERR) {
421 do_printf(serr);
422 exit(0);
423 }
424 t_ut = tret[0];
425 if ((eclflag & SE_ECL_TOTAL)) {
426 strcpy(sout, "total ");
427 ecl_type = ECL_LUN_TOTAL;
428 }
429 if ((eclflag & SE_ECL_PENUMBRAL)) {
430 strcpy(sout, "penumb. ");
431 ecl_type = ECL_LUN_PENUMBRAL;
432 }
433 if ((eclflag & SE_ECL_PARTIAL)) {
434 strcpy(sout, "partial ");
435 ecl_type = ECL_LUN_PARTIAL;
436 }
437 strcat(sout, "lunar eclipse ");
438 swe_revjul(t_ut, gregflag, &jyear, &jmon, &jday, &jut);
439 if ((eclflag = swe_lun_eclipse_how(t_ut, whicheph, geopos, attr, serr)) ==
440 ERR) {
441 do_printf(serr);
442 exit(0);
443 }
444 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s\t%f o/o\n",
445 /* eclipse times, penumbral, partial, total begin and end */
446 jday, jmon, jyear, hms(jut,0), attr[0]);
447 sprintf(sout + strlen(sout), " %s ", hms_from_tjd(tret[6]));
448 if (tret[2] != 0)
449 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[2]));
450 else
451 strcat(sout, " - ");
452 if (tret[4] != 0)
453 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
454 else
455 strcat(sout, " - ");
456 if (tret[5] != 0)
457 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[5]));
458 else
459 strcat(sout, " - ");
460 if (tret[3] != 0)
461 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[3]));
462 else
463 strcat(sout, " - ");
464 sprintf(sout + strlen(sout), "%s\n", hms_from_tjd(tret[7]));
465 if (smod & SMOD_HOCAL) {
466 int ihou, imin, isec, isgn;
467 double dfrc;
468 swe_split_deg(jut, SE_SPLIT_DEG_ROUND_MIN, &ihou, &imin, &isec, &dfrc, &isgn);
469 #if 0
470 sprintf(sout, "\"%04d %02d %02d %02d.%02d %d\",\n", jyear, jmon, jday, ihou, imin, ecl_type);
471 #else
472 sprintf(sout, "%f, %.0f, /* %04d %02d %02d %02d.%02d %d */,\n", t_ut, (double) ecl_type, jyear, jmon, jday, ihou, imin, ecl_type);
473 #endif
474 }
475 do_printf(sout);
476 }
477 if ((smod & SMOD_SOLAR) && (smod & SMOD_LOCAL)) {
478 if ((eclflag = swe_sol_eclipse_when_loc(t_ut, whicheph, geopos, tret,
479 attr, direction_flag, serr)) == ERR) {
480 do_printf(serr);
481 exit(0);
482 } else {
483 AS_BOOL has_found = FALSE;
484 t_ut = tret[0];
485 if ((smod & SMOD_TOTAL) && (eclflag & SE_ECL_TOTAL)) {
486 strcpy(sout, "total ");
487 has_found = TRUE;
488 ecl_type = ECL_SOL_TOTAL;
489 }
490 if ((smod & SMOD_ANNULAR) && (eclflag & SE_ECL_ANNULAR)) {
491 strcpy(sout, "annular ");
492 has_found = TRUE;
493 ecl_type = ECL_SOL_ANNULAR;
494 }
495 if ((smod & SMOD_PARTIAL) && (eclflag & SE_ECL_PARTIAL)) {
496 strcpy(sout, "partial ");
497 has_found = TRUE;
498 ecl_type = ECL_SOL_PARTIAL;
499 }
500 if (!has_found) {
501 ii--;
502 } else {
503 i = do_calc(t_ut + swe_deltat(t_ut), SE_ECL_NUT, 0, x, serr);
504 swe_revjul(t_ut, gregflag, &jyear, &jmon, &jday, &jut);
505 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s\t%fo/o\n", jday, jmon, jyear, hms(jut,0), attr[0]);
506 dt = (tret[3] - tret[2]) * 24 * 60;
507 sprintf(sout + strlen(sout), "\t%d min %4.2f sec\t",
508 (int) dt, fmod(dt, 1) * 60);
509 if (eclflag & SE_ECL_1ST_VISIBLE)
510 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[1]));
511 else
512 strcat(sout, " - ");
513 if (eclflag & SE_ECL_2ND_VISIBLE)
514 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[2]));
515 else
516 strcat(sout, " - ");
517 if (eclflag & SE_ECL_3RD_VISIBLE)
518 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[3]));
519 else
520 strcat(sout, " - ");
521 if (eclflag & SE_ECL_4TH_VISIBLE)
522 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
523 else
524 strcat(sout, " - ");
525 #if 0
526 sprintf(sout + strlen(sout), "\t%d min %4.2f sec %s %s %s %s",
527 (int) dt, fmod(dt, 1) * 60,
528 strcpy(s1, hms(fmod(tret[1] + 0.5, 1) * 24, 0)),
529 strcpy(s3, hms(fmod(tret[2] + 0.5, 1) * 24, 0)),
530 strcpy(s4, hms(fmod(tret[3] + 0.5, 1) * 24, 0)),
531 strcpy(s2, hms(fmod(tret[4] + 0.5, 1) * 24, 0)));
532 #endif
533 strcat(sout, "\n");
534 do_printf(sout);
535 }
536 }
537 } /* endif search_local */
538 if ((smod & SMOD_SOLAR) && ! (smod & SMOD_LOCAL)) {
539 /* * global search for eclipses */
540 if ((eclflag = swe_sol_eclipse_when_glob(t_ut, whicheph, search_flag,
541 tret, direction_flag, serr)) == ERR) {
542 do_printf(serr);
543 exit(0);
544 }
545 t_ut = tret[0];
546 if ((eclflag & SE_ECL_TOTAL)) {
547 strcpy(sout, "total ");
548 ecl_type = ECL_SOL_TOTAL;
549 }
550 if ((eclflag & SE_ECL_ANNULAR)) {
551 strcpy(sout, "annular ");
552 ecl_type = ECL_SOL_ANNULAR;
553 }
554 if ((eclflag & SE_ECL_ANNULAR_TOTAL)) {
555 strcpy(sout, "ann-tot ");
556 ecl_type = ECL_SOL_ANNULAR; /* by Alois: what is this ? */
557 }
558 if ((eclflag & SE_ECL_PARTIAL)) {
559 strcpy(sout, "partial ");
560 ecl_type = ECL_SOL_PARTIAL;
561 }
562 if ((eclflag & SE_ECL_NONCENTRAL) && !(eclflag & SE_ECL_PARTIAL))
563 strcat(sout, "non-central ");
564 swe_sol_eclipse_where(t_ut, whicheph, geopos, attr, serr);
565 swe_revjul(t_ut, gregflag, &jyear, &jmon, &jday, &jut);
566 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s\t%f km\t%f o/o\n",
567 jday, jmon, jyear, hms(jut,0), attr[3], attr[0]);
568 sprintf(sout + strlen(sout), "\t%s ", hms_from_tjd(tret[2]));
569 if (tret[4] != 0)
570 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
571 else
572 strcat(sout, " - ");
573 if (tret[5] != 0)
574 sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[5]));
575 else
576 strcat(sout, " - ");
577 sprintf(sout + strlen(sout), "%s\n", hms_from_tjd(tret[3]));
578 #if 0
579 swe_revjul(tret[1], gregflag, &jyear, &jmon, &jday, &jut);
580 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s\t%f km\n",
581 jday, jmon, jyear, hms(jut,0), attr[3]);
582 #endif
583 sprintf(sout + strlen(sout), "\t%s\t%s",
584 strcpy(s1, dms(geopos[0], BIT_ROUND_MIN)),
585 strcpy(s2, dms(geopos[1], BIT_ROUND_MIN)));
586 if (!(eclflag & SE_ECL_PARTIAL) && !(eclflag & SE_ECL_NONCENTRAL)) {
587 if ((eclflag = swe_sol_eclipse_when_loc(t_ut - 10, whicheph,
588 geopos, tret, attr, 0, serr)) == ERR) {
589 do_printf(serr);
590 exit(0);
591 }
592 if (fabs(tret[0] - t_ut) > 1)
593 do_printf("when_loc returns wrong date\n");
594 dt = (tret[3] - tret[2]) * 24 * 60;
595 sprintf(sout + strlen(sout), "\t%d min %4.2f sec\t",
596 (int) dt, fmod(dt, 1) * 60);
597 }
598 strcat(sout, "\n");
599 if (smod & SMOD_HOCAL) {
600 int ihou, imin, isec, isgn;
601 double dfrc;
602 swe_split_deg(jut, SE_SPLIT_DEG_ROUND_MIN, &ihou, &imin, &isec, &dfrc, &isgn);
603 #if 0
604 sprintf(sout, "\"%04d %02d %02d %02d.%02d %d\",\n", jyear, jmon, jday, ihou, imin, ecl_type);
605 #else
606 sprintf(sout, "%f, %.0f, /* %04d %02d %02d %02d.%02d %d */\n", t_ut, (double) ecl_type, jyear, jmon, jday, ihou, imin, ecl_type);
607 #endif
608 }
609 do_printf(sout);
610 }
611 if (smod & SMOD_RISE) {
612 if (swe_rise_trans(t_ut, ipl, starname, whicheph, SE_CALC_RISE, geopos, 1013.25, 10, &(tret[0]), serr) != OK) {
613 do_printf(serr);
614 exit(0);
615 }
616 if (swe_rise_trans(t_ut, ipl, starname, whicheph, SE_CALC_SET, geopos, 1013.25, 10, &(tret[1]), serr) != OK) {
617 do_printf(serr);
618 exit(0);
619 }
620 strcpy(sout, "rise ");
621 if (tret[0] == 0) strcat(sout, " - ");
622 else {
623 swe_revjul(tret[0], gregflag, &jyear, &jmon, &jday, &jut);
624 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s ",
625 jday, jmon, jyear, hms(jut,0));
626 }
627 strcat(sout, "set ");
628 if (tret[1] == 0) strcat(sout, " - \n");
629 else {
630 swe_revjul(tret[1], gregflag, &jyear, &jmon, &jday, &jut);
631 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s\n",
632 jday, jmon, jyear, hms(jut,0));
633 }
634 do_printf(sout);
635 }
636 if (smod & SMOD_METR) {
637 if (swe_rise_trans(t_ut, ipl, starname, whicheph, SE_CALC_MTRANSIT, geopos, 1013.25, 10, &(tret[0]), serr) != OK) {
638 do_printf(serr);
639 exit(0);
640 }
641 if (swe_rise_trans(t_ut, ipl, starname, whicheph, SE_CALC_ITRANSIT, geopos, 1013.25, 10, &(tret[1]), serr) != OK) {
642 do_printf(serr);
643 exit(0);
644 }
645 strcpy(sout, "mtransit ");
646 if (tret[0] == 0) strcat(sout, " - ");
647 else {
648 swe_revjul(tret[0], gregflag, &jyear, &jmon, &jday, &jut);
649 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s ",
650 jday, jmon, jyear, hms(jut,0));
651 }
652 strcat(sout, "itransit ");
653 if (tret[1] == 0) strcat(sout, " - \n");
654 else {
655 swe_revjul(tret[1], gregflag, &jyear, &jmon, &jday, &jut);
656 sprintf(sout + strlen(sout), "%2d.%2d.%4d\t%s\n",
657 jday, jmon, jyear, hms(jut,0));
658 }
659 do_printf(sout);
660 }
661 if ((smod & (SMOD_RISE | SMOD_METR)) && tret[1] > 0)
662 t_ut = tret[1] + 0.1;
663 else
664 t_ut += direction;
665 }
666 if (*serr_warn != '\0') {
667 do_printf("\nwarning: ");
668 do_printf(serr_warn);
669 do_printf("\n");
670 }
671 /* close open files and free allocated space */
672 end_main:
673 swe_close();
674 return OK;
675 }
676
hms_from_tjd(double x)677 static char *hms_from_tjd(double x)
678 {
679 static char s[AS_MAXCH];
680 sprintf(s, "%s ", hms(fmod(x + 1000000.5, 1) * 24, 0));
681 return s;
682 }
683
hms(double x,int32 iflag)684 static char *hms(double x, int32 iflag)
685 {
686 static char s[AS_MAXCH], s2[AS_MAXCH], *sp;
687 char *c = ODEGREE_STRING;
688 x += 0.5 / 36000.0; /* round to 0.1 sec */
689 strcpy(s, dms(x, iflag));
690 sp = strstr(s, c);
691 if (sp != NULL) {
692 *sp = ':';
693 if (strlen(ODEGREE_STRING) > 1)
694 strcpy(s2, sp + strlen(ODEGREE_STRING));
695 strcpy(sp + 1, s2);
696 *(sp + 3) = ':';
697 *(sp + 8) = '\0';
698 }
699 return s;
700 }
701
dms(double xv,int32 iflg)702 static char *dms(double xv, int32 iflg)
703 {
704 int izod;
705 int32 k, kdeg, kmin, ksec;
706 char *c = ODEGREE_STRING;
707 char *sp, s1[50];
708 static char s[50];
709 int sgn;
710 *s = '\0';
711 if (iflg & SEFLG_EQUATORIAL)
712 c = "h";
713 if (xv < 0) {
714 xv = -xv;
715 sgn = -1;
716 } else
717 sgn = 1;
718 if (iflg & BIT_ROUND_MIN)
719 xv = swe_degnorm(xv + 0.5/60);
720 if (iflg & BIT_ROUND_SEC)
721 xv = swe_degnorm(xv + 0.5/3600);
722 if (iflg & BIT_ZODIAC) {
723 izod = (int) (xv / 30);
724 xv = fmod(xv, 30);
725 kdeg = (int32) xv;
726 sprintf(s, "%2d %s ", kdeg, zod_nam[izod]);
727 } else {
728 kdeg = (int32) xv;
729 sprintf(s, " %3d%s", kdeg, c);
730 }
731 xv -= kdeg;
732 xv *= 60;
733 kmin = (int32) xv;
734 if ((iflg & BIT_ZODIAC) && (iflg & BIT_ROUND_MIN))
735 sprintf(s1, "%2d", kmin);
736 else
737 sprintf(s1, "%2d'", kmin);
738 strcat(s, s1);
739 if (iflg & BIT_ROUND_MIN)
740 goto return_dms;
741 xv -= kmin;
742 xv *= 60;
743 ksec = (int32) xv;
744 if (iflg & BIT_ROUND_SEC)
745 sprintf(s1, "%2d\"", ksec);
746 else
747 sprintf(s1, "%2d", ksec);
748 strcat(s, s1);
749 if (iflg & BIT_ROUND_SEC)
750 goto return_dms;
751 xv -= ksec;
752 k = (int32) (xv * 10000);
753 sprintf(s1, ".%04d", k);
754 strcat(s, s1);
755 return_dms:;
756 if (sgn < 0) {
757 sp = strpbrk(s, "0123456789");
758 *(sp-1) = '-';
759 }
760 if (iflg & BIT_LZEROES) {
761 while ((sp = strchr(s+2, ' ')) != NULL) *sp = '0';
762 }
763 return(s);
764 }
765
766 /* make_ephemeris_path().
767 * ephemeris path includes
768 * current working directory
769 * + program directory
770 * + default path from swephexp.h on current drive
771 * + on program drive
772 * + on drive C:
773 */
make_ephemeris_path(long iflag,char * argv0)774 static int make_ephemeris_path(long iflag, char *argv0)
775 {
776 char path[AS_MAXCH], s[AS_MAXCH];
777 char *sp;
778 char *dirglue = DIR_GLUE;
779 size_t pathlen = 0;
780 /* moshier needs no ephemeris path */
781 if (iflag & SEFLG_MOSEPH)
782 return OK;
783 /* current working directory */
784 sprintf(path, ".%c", *PATH_SEPARATOR);
785 /* program directory */
786 sp = strrchr(argv0, *dirglue);
787 if (sp != NULL) {
788 pathlen = sp - argv0;
789 if (strlen(path) + pathlen < AS_MAXCH-1) {
790 strcpy(s, argv0);
791 *(s+pathlen) = '\0';
792 sprintf(path + strlen(path), "%s%c", s, *PATH_SEPARATOR);
793 }
794 }
795 #if MSDOS
796 {
797 char *cpos[20];
798 char s[2 * AS_MAXCH], *s1 = s + AS_MAXCH;
799 char *sp[3];
800 int i, j, np;
801 strcpy(s1, SE_EPHE_PATH);
802 np = cut_str_any(s1, PATH_SEPARATOR, cpos, 20);
803 /*
804 * default path from swephexp.h
805 * - current drive
806 * - program drive
807 * - drive C
808 */
809 *s = '\0';
810 /* current working drive */
811 sp[0] = getcwd(NULL, 0);
812 if (sp[0] == NULL) {
813 do_printf("error in getcwd()\n");
814 exit(1);
815 }
816 if (*sp[0] == 'C')
817 sp[0] = NULL;
818 /* program drive */
819 if (*argv0 != 'C' && (sp[0] == NULL || *sp[0] != *argv0))
820 sp[1] = argv0;
821 else
822 sp[1] = NULL;
823 /* drive C */
824 sp[2] = "C";
825 for (i = 0; i < np; i++) {
826 strcpy(s, cpos[i]);
827 if (*s == '.') /* current directory */
828 continue;
829 if (s[1] == ':') /* drive already there */
830 continue;
831 for (j = 0; j < 3; j++) {
832 if (sp[j] != NULL && strlen(path) + 2 + strlen(s) < AS_MAXCH-1)
833 sprintf(path + strlen(path), "%c:%s%c", *sp[j], s, *PATH_SEPARATOR);
834 }
835 }
836 }
837 #else
838 if (strlen(path) + pathlen < AS_MAXCH-1)
839 strcat(path, SE_EPHE_PATH);
840 #endif
841 return OK;
842 }
843
do_calc(double tjd,int ipl,long iflag,double * x,char * serr)844 static int do_calc(double tjd, int ipl, long iflag, double *x, char *serr)
845 {
846 return swe_calc(tjd, ipl, iflag, x, serr);
847 }
848
do_printf(char * info)849 static void do_printf(char *info)
850 {
851 #ifdef _WINDOWS
852 fprintf(fp, info);
853 #else
854 printf(info);
855 #endif
856 }
857
858 /**************************************************************
859 cut the string s at any char in cutlist; put pointers to partial strings
860 into cpos[0..n-1], return number of partial strings;
861 if less than nmax fields are found, the first empty pointer is
862 set to NULL.
863 More than one character of cutlist in direct sequence count as one
864 separator only! cut_str_any("word,,,word2",","..) cuts only two parts,
865 cpos[0] = "word" and cpos[1] = "word2".
866 If more than nmax fields are found, nmax is returned and the
867 last field nmax-1 rmains un-cut.
868 **************************************************************/
cut_str_any(char * s,char * cutlist,char * cpos[],int nmax)869 static int cut_str_any(char *s, char *cutlist, char *cpos[], int nmax)
870 {
871 int n = 1;
872 cpos [0] = s;
873 while (*s != '\0') {
874 if ((strchr(cutlist, (int) *s) != NULL) && n < nmax) {
875 *s = '\0';
876 while (*(s + 1) != '\0' && strchr (cutlist, (int) *(s + 1)) != NULL) s++;
877 cpos[n++] = s + 1;
878 }
879 if (*s == '\n' || *s == '\r') { /* treat nl or cr like end of string */
880 *s = '\0';
881 break;
882 }
883 s++;
884 }
885 if (n < nmax) cpos[n] = NULL;
886 return (n);
887 } /* cutstr */
888
letter_to_ipl(int letter)889 static int letter_to_ipl(int letter)
890 {
891 if (letter >= '0' && letter <= '9')
892 return letter - '0' + SE_SUN;
893 if (letter >= 'A' && letter <= 'I')
894 return letter - 'A' + SE_MEAN_APOG;
895 if (letter >= 'J' && letter <= 'X')
896 return letter - 'J' + SE_CUPIDO;
897 switch (letter) {
898 case 'm': return SE_MEAN_NODE;
899 case 'n':
900 case 'o': return SE_ECL_NUT;
901 case 't': return SE_TRUE_NODE;
902 case 'f': return SE_FIXSTAR;
903 }
904 return -1;
905 }
906