@swisseph/node 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,905 @@
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
+
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
+
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
+
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
+
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
+ */
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
+
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
+
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
+ **************************************************************/
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
+
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
+ }