@swisseph/node 1.0.1 → 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,4079 @@
1
+ /*
2
+ swetest.c A test program
3
+
4
+ Authors: Dieter Koch and Alois Treindl, Astrodienst Zuerich
5
+
6
+ **************************************************************/
7
+
8
+ /* Copyright (C) 1997 - 2021 Astrodienst AG, Switzerland. All rights reserved.
9
+
10
+ License conditions
11
+ ------------------
12
+
13
+ This file is part of Swiss Ephemeris.
14
+
15
+ Swiss Ephemeris is distributed with NO WARRANTY OF ANY KIND. No author
16
+ or distributor accepts any responsibility for the consequences of using it,
17
+ or for whether it serves any particular purpose or works at all, unless he
18
+ or she says so in writing.
19
+
20
+ Swiss Ephemeris is made available by its authors under a dual licensing
21
+ system. The software developer, who uses any part of Swiss Ephemeris
22
+ in his or her software, must choose between one of the two license models,
23
+ which are
24
+ a) GNU Affero General Public License (AGPL)
25
+ b) Swiss Ephemeris Professional License
26
+
27
+ The choice must be made before the software developer distributes software
28
+ containing parts of Swiss Ephemeris to others, and before any public
29
+ service using the developed software is activated.
30
+
31
+ If the developer choses the AGPL software license, he or she must fulfill
32
+ the conditions of that license, which includes the obligation to place his
33
+ or her whole software project under the AGPL or a compatible license.
34
+ See https://www.gnu.org/licenses/agpl-3.0.html
35
+
36
+ If the developer choses the Swiss Ephemeris Professional license,
37
+ he must follow the instructions as found in http://www.astro.com/swisseph/
38
+ and purchase the Swiss Ephemeris Professional Edition from Astrodienst
39
+ and sign the corresponding license contract.
40
+
41
+ The License grants you the right to use, copy, modify and redistribute
42
+ Swiss Ephemeris, but only under certain conditions described in the License.
43
+ Among other things, the License requires that the copyright notices and
44
+ this notice be preserved on all copies.
45
+
46
+ Authors of the Swiss Ephemeris: Dieter Koch and Alois Treindl
47
+
48
+ The authors of Swiss Ephemeris have no control or influence over any of
49
+ the derived works, i.e. over software or services created by other
50
+ programmers which use Swiss Ephemeris functions.
51
+
52
+ The names of the authors or of the copyright holder (Astrodienst) must not
53
+ be used for promoting any software, product or service which uses or contains
54
+ the Swiss Ephemeris. This copyright notice is the ONLY place where the
55
+ names of the authors can legally appear, except in cases where they have
56
+ given special permission in writing.
57
+
58
+ The trademarks 'Swiss Ephemeris' and 'Swiss Ephemeris inside' may be used
59
+ for promoting such software, products or services.
60
+ */
61
+
62
+ /* attention: Microsoft Compiler does not accept strings > 2048 char */
63
+
64
+ static char *infocmd0 = "\n\
65
+ Swetest computes a complete set of geocentric planetary positions,\n\
66
+ for a given date or a sequence of dates.\n\
67
+ Input can either be a date or an absolute julian day number.\n\
68
+ 0:00 (midnight).\n\
69
+ With the proper options, swetest can be used to output a printed\n\
70
+ ephemeris and transfer the data into other programs like spreadsheets\n\
71
+ for graphical display.\n\
72
+ Version: \n\
73
+ \n";
74
+ static char *infocmd1 = "\n\
75
+ Command line options:\n\
76
+ help commands:\n\
77
+ -?, -h display whole info\n\
78
+ -hcmd display commands\n\
79
+ -hplan display planet numbers\n\
80
+ -hform display format characters\n\
81
+ -hdate display input date format\n\
82
+ -hexamp display examples\n\
83
+ -glp report file location of library\n\
84
+ input time formats:\n\
85
+ -bDATE begin date; e.g. -b1.1.1992 if\n\
86
+ Note: the date format is day month year (European style).\n\
87
+ -bj... begin date as an absolute Julian day number; e.g. -bj2415020.5\n\
88
+ -j... same as -bj\n\
89
+ -tHH[:MM[:SS]] input time (as Ephemeris Time)\n\
90
+ -ut input date is Universal Time (UT1)\n\
91
+ -utHH[:MM[:SS]] input time (as Universal Time)\n\
92
+ -utcHH[:MM[:SS]] input time (as Universal Time Coordinated UTC)\n\
93
+ H,M,S can have one or two digits. Their limits are unchecked.\n\
94
+ output time for eclipses, occultations, risings/settings is UT by default\n\
95
+ -lmt output date/time is LMT (with -geopos)\n\
96
+ -lat output date/time is LAT (with -geopos)\n\
97
+ object, number of steps, step with\n\
98
+ -pSEQ planet sequence to be computed.\n\
99
+ See the letter coding below.\n\
100
+ -dX differential ephemeris: print differential ephemeris between\n\
101
+ body X and each body in list given by -p\n\
102
+ example: -p2 -d0 -fJl -n366 -b1.1.1992 prints the longitude\n\
103
+ distance between SUN (planet 0) and MERCURY (planet 2)\n\
104
+ for a full year starting at 1 Jan 1992.\n\
105
+ -dhX differential ephemeris: print differential ephemeris between\n\
106
+ heliocentric body X and each body in list given by -p\n\
107
+ example: -p8 -dh8 -ftl -n36600 -b1.1.1500 -s5 prints the longitude\n\
108
+ distance between geocentric and heliocentric Neptune (planet 8)\n\
109
+ for 500 year starting at 1 Jan 1500.\n\
110
+ Using this option mostly makes sense for a single planet\n\
111
+ to find out how much its geocentric and heliocentric positions can differ\n\
112
+ over extended periods of time\n\
113
+ -DX midpoint ephemeris, works the same way as the differential\n\
114
+ mode -d described above, but outputs the midpoint position.\n\
115
+ -nN output data for N consecutive timesteps; if no -n option\n\
116
+ is given, the default is 1. If the option -n without a\n\
117
+ number is given, the default is 20.\n\
118
+ -sN timestep N days, default 1. This option is only meaningful\n\
119
+ when combined with option -n.\n\
120
+ If an 'y' is appended, the time step is in years instead of days, \n\
121
+ for example -s10y for a time step of 10 years.\n\
122
+ If an 'mo' is appended, the time step is in months instead of days, \n\
123
+ for example -s3mo for a time step of 3 months.\n\
124
+ If an 'm' is appended, the time step is in minutes instead of days, \n\
125
+ for example -s15m for a time step of 15 minutes.\n\
126
+ If an 's' is appended, the time step is in seconds instead of days, \n\
127
+ for example -s1s for a time step of 1 second.\n\
128
+ ";
129
+ static char *infocmd2 = "\
130
+ output format:\n\
131
+ -fSEQ use SEQ as format sequence for the output columns;\n\
132
+ default is PLBRS.\n\
133
+ -head don\'t print the header before the planet data. This option\n\
134
+ is useful when you want to paste the output into a\n\
135
+ spreadsheet for displaying graphical ephemeris.\n\
136
+ +head header before every step (with -s..) \n\
137
+ -gPPP use PPP as gap between output columns; default is a single\n\
138
+ blank. -g followed by white space sets the\n\
139
+ gap to the TAB character; which is useful for data entry\n\
140
+ into spreadsheets.\n\
141
+ -hor list data for multiple planets 'horizontally' in same line.\n\
142
+ all columns of -fSEQ are repeated except time colums tTJyY.\n\
143
+ astrological house system:\n\
144
+ -house[long,lat,hsys] \n\
145
+ include house cusps. The longitude, latitude (degrees with\n\
146
+ DECIMAL fraction) and house system letter can be given, with\n\
147
+ commas separated, + for east and north. If none are given,\n\
148
+ Greenwich UK and Placidus is used: 0.00,51.50,p.\n\
149
+ The output lists 12 house cusps, Asc, MC, ARMC, Vertex,\n\
150
+ Equatorial Ascendant, co-Ascendant as defined by Walter Koch, \n\
151
+ co-Ascendant as defined by Michael Munkasey, and Polar Ascendant. \n\
152
+ Houses can only be computed if option -ut is given.\n\
153
+ A equal\n\
154
+ B Alcabitius\n\
155
+ C Campanus\n\
156
+ D equal / MC\n\
157
+ E equal = A\n\
158
+ F Carter poli-equatorial\n\
159
+ G 36 Gauquelin sectors\n\
160
+ H horizon / azimuth\n\
161
+ I Sunshine\n\
162
+ i Sunshine alternative\n\
163
+ K Koch\n\
164
+ L Pullen S-delta\n\
165
+ M Morinus\n\
166
+ N Whole sign, Aries = 1st house\n\
167
+ O Porphyry\n\
168
+ P Placidus\n\
169
+ Q Pullen S-ratio\n\
170
+ R Regiomontanus\n\
171
+ S Sripati\n\
172
+ T Polich/Page (\"topocentric\")\n\
173
+ U Krusinski-Pisa-Goelzer\n\
174
+ V equal Vehlow\n\
175
+ W equal, whole sign\n\
176
+ X axial rotation system/ Meridian houses\n\
177
+ Y APC houses\n\
178
+ The use of lower case letters is deprecated. They will have a\n\
179
+ different meaning in future releases of Swiss Ephemeris.\n\
180
+ -hsy[hsys] \n\
181
+ house system to be used (for house positions of planets)\n\
182
+ for long, lat, hsys, see -house\n\
183
+ The use of lower case letters is deprecated. They will have a\n\
184
+ different meaning in future releases of Swiss Ephemeris.\n\
185
+ ";
186
+ static char *infocmd3 = "\
187
+ -geopos[long,lat,elev] \n\
188
+ Geographic position. Can be used for azimuth and altitude\n\
189
+ or house cusps calculations.\n\
190
+ The longitude, latitude (degrees with DECIMAL fraction)\n\
191
+ and elevation (meters) can be given, with\n\
192
+ commas separated, + for east and north. If none are given,\n\
193
+ Greenwich is used: 0,51.5,0.\n\
194
+ For topocentric planet positions please user the parameter -topo\n\
195
+ sidereal astrology:\n\
196
+ -ay.. ayanamsha, with number of method, e.g. ay0 for Fagan/Bradley\n\
197
+ -sid.. sidereal, with number of method (see below)\n\
198
+ -sidt0.. dito, but planets are projected on the ecliptic plane of the\n\
199
+ reference date of the ayanamsha (more info in general documentation\n\
200
+ www.astro.com/swisseph/swisseph.htm)\n\
201
+ -sidsp.. dito, but planets are projected on the solar system plane.\n\
202
+ (see www.astro.com/swisseph/swisseph.htm)\n\
203
+ -sidudef[jd,ay0,...] sidereal, with user defined ayanamsha; \n\
204
+ jd=julian day number in TT/ET\n\
205
+ ay0=initial value of ayanamsha, \n\
206
+ ...=optional parameters, comma-sparated:\n\
207
+ 'jdisut': ayanamsha reference date is UT\n\
208
+ 'eclt0': project on ecliptic of reference date (like -sidt0..)\n\
209
+ 'ssyplane': project on solar system plane (like -sidsp..)\n\
210
+ e.g. '-sidudef2452163.8333333,25.0,jdisut': ayanamsha is 25.0° on JD 2452163.8333333 UT\n\
211
+ number of ayanamsha method:\n\
212
+ 0 for Fagan/Bradley\n\
213
+ 1 for Lahiri\n\
214
+ 2 for De Luce\n\
215
+ 3 for Raman\n\
216
+ 4 for Usha/Shashi\n\
217
+ 5 for Krishnamurti\n\
218
+ 6 for Djwhal Khul\n\
219
+ 7 for Yukteshwar\n\
220
+ 8 for J.N. Bhasin\n\
221
+ 9 for Babylonian/Kugler 1\n\
222
+ 10 for Babylonian/Kugler 2\n\
223
+ 11 for Babylonian/Kugler 3\n\
224
+ 12 for Babylonian/Huber\n\
225
+ 13 for Babylonian/Eta Piscium\n\
226
+ 14 for Babylonian/Aldebaran = 15 Tau\n\
227
+ 15 for Hipparchos\n\
228
+ 16 for Sassanian\n\
229
+ 17 for Galact. Center = 0 Sag\n\
230
+ 18 for J2000\n\
231
+ 19 for J1900\n\
232
+ 20 for B1950\n\
233
+ 21 for Suryasiddhanta\n\
234
+ 22 for Suryasiddhanta, mean Sun\n\
235
+ 23 for Aryabhata\n\
236
+ 24 for Aryabhata, mean Sun\n\
237
+ 25 for SS Revati\n\
238
+ 26 for SS Citra\n\
239
+ 27 for True Citra\n\
240
+ 28 for True Revati\n\
241
+ 29 for True Pushya (PVRN Rao)\n\
242
+ 30 for Galactic (Gil Brand)\n\
243
+ 31 for Galactic Equator (IAU1958)\n\
244
+ 32 for Galactic Equator\n\
245
+ 33 for Galactic Equator mid-Mula\n\
246
+ 34 for Skydram (Mardyks)\n\
247
+ 35 for True Mula (Chandra Hari)\n\
248
+ 36 Dhruva/Gal.Center/Mula (Wilhelm)\n\
249
+ 37 Aryabhata 522\n\
250
+ 38 Babylonian/Britton\n\
251
+ 39 Vedic/Sheoran\n\
252
+ 40 Cochrane (Gal.Center = 0 Cap)\n\
253
+ 41 Galactic Equator (Fiorenza)\n\
254
+ 42 Vettius Valens\n\
255
+ 43 Lahiri 1940\n\
256
+ 44 Lahiri VP285 (1980)\n\
257
+ 45 Krishnamurti VP291\n\
258
+ 46 Lahiri ICRC\n\
259
+ ephemeris specifications:\n\
260
+ -edirPATH change the directory of the ephemeris files \n\
261
+ -eswe swiss ephemeris\n\
262
+ -ejpl jpl ephemeris (DE431), or with ephemeris file name\n\
263
+ -ejplde200.eph \n\
264
+ -emos moshier ephemeris\n\
265
+ -true true positions\n\
266
+ -noaberr no aberration\n\
267
+ -nodefl no gravitational light deflection\n\
268
+ -noaberr -nodefl astrometric positions\n\
269
+ -j2000 no precession (i.e. J2000 positions)\n\
270
+ -icrs ICRS (use Internat. Celestial Reference System)\n\
271
+ -nonut no nutation \n\
272
+ ";
273
+ static char *infocmd4 = "\
274
+ -speed calculate high precision speed \n\
275
+ -speed3 'low' precision speed from 3 positions \n\
276
+ do not use this option. -speed parameter\n\
277
+ is faster and more precise \n\
278
+ -iXX force iflag to value XX\n\
279
+ -testaa96 test example in AA 96, B37,\n\
280
+ i.e. venus, j2450442.5, DE200.\n\
281
+ attention: use precession IAU1976\n\
282
+ and nutation 1980 (s. swephlib.h)\n\
283
+ -testaa95\n\
284
+ -testaa97\n\
285
+ -roundsec round to seconds\n\
286
+ -roundmin round to minutes\n\
287
+ -ep use extra precision in output for some data\n\
288
+ -dms use dms instead of fractions, at some places\n\
289
+ -lim print ephemeris file range\n\
290
+ observer position:\n\
291
+ -hel compute heliocentric positions\n\
292
+ -bary compute barycentric positions (bar. earth instead of node) \n\
293
+ -topo[long,lat,elev] \n\
294
+ topocentric positions. The longitude, latitude (degrees with\n\
295
+ DECIMAL fraction) and elevation (meters) can be given, with\n\
296
+ commas separated, + for east and north. If none are given,\n\
297
+ Greenwich is used 0.00,51.50,0\n\
298
+ -pc... compute planetocentric positions\n\
299
+ to specify the central body, use the internal object number\n\
300
+ of Swiss Ephemeris, e.g. 3 for Venus, 4 for Mars, \n\
301
+ -pc3 Venus-centric \n\
302
+ -pc4 Mars-centric \n\
303
+ -pc5 Jupiter-centric (barycenter)\n\
304
+ -pc9599 Jupiter-centric (center of body)\n\
305
+ -pc9699 Saturn-centric (center of body)\n\
306
+ For asteroids use MPC number + 10000, e.g.\n\
307
+ -pc10433 Eros-centric (Eros = 433 + 10000)\n\
308
+ orbital elements:\n\
309
+ -orbel compute osculating orbital elements relative to the\n\
310
+ mean ecliptic J2000. (Note, all values, including time of\n\
311
+ pericenter vary considerably depending on the date for which the\n\
312
+ osculating ellipse is calculated\n\
313
+ \n\
314
+ special events:\n\
315
+ -solecl solar eclipse\n\
316
+ output 1st line:\n\
317
+ eclipse date,\n\
318
+ time of maximum (UT):\n\
319
+ geocentric angle between centre of Sun and Moon reaches minimum.\n\
320
+ core shadow width (negative with total eclipses),\n\
321
+ eclipse magnitudes:\n\
322
+ 1. NASA method (= 2. with partial ecl. and \n\
323
+ ratio lunar/solar diameter with total and annular ecl.)\n\
324
+ 2. fraction of solar diameter covered by moon;\n\
325
+ if the value is > 1, it means that Moon covers more than\n\
326
+ just the solar disk\n\
327
+ 3. fraction of solar disc covered by moon (obscuration)\n\
328
+ with total and annular eclipses it is the ratio of\n\
329
+ the sizes of the solar disk and the lunar disk.\n\
330
+ Saros series and eclipse number\n\
331
+ Julian day number (6-digit fraction) of maximum\n\
332
+ output 2nd line:\n\
333
+ start and end times for partial and total phases\n\
334
+ delta t in sec\n\
335
+ output 3rd line:\n\
336
+ geographical longitude and latitude of maximum eclipse,\n\
337
+ totality duration at that geographical position,\n\
338
+ output with -local, see below.\n\
339
+ -occult occultation of planet or star by the moon. Use -p to \n\
340
+ specify planet (-pf -xfAldebaran for stars) \n\
341
+ output format same as with -solecl, with the following differences:\n\
342
+ Magnitude is defined like no. 2. with solar eclipses.\n\
343
+ There are no saros series.\n\
344
+ ";
345
+ static char *infocmd5 = "\
346
+ -lunecl lunar eclipse\n\
347
+ output 1st line:\n\
348
+ eclipse date,\n\
349
+ time of maximum (UT),\n\
350
+ eclipse magnitudes: umbral and penumbral\n\
351
+ method as method 2 with solar eclipses\n\
352
+ Saros series and eclipse number \n\
353
+ Julian day number (6-digit fraction) of maximum\n\
354
+ output 2nd line:\n\
355
+ 6 contacts for start and end of penumbral, partial, and\n\
356
+ total phase\n\
357
+ delta t in sec\n\
358
+ output 3rd line:\n\
359
+ geographic position where the Moon is in zenith at maximum eclipse\n\
360
+ -local only with -solecl or -occult, if the next event of this\n\
361
+ kind is wanted for a given geogr. position.\n\
362
+ Use -geopos[long,lat,elev] to specify that position.\n\
363
+ If -local is not set, the program \n\
364
+ searches for the next event anywhere on earth.\n\
365
+ output 1st line:\n\
366
+ eclipse date,\n\
367
+ time of maximum,\n\
368
+ eclipse magnitudes, as with global solar eclipse function \n\
369
+ (with occultations: only diameter method, see solar eclipses, method 2)\n\
370
+ Saros series and eclipse number (with solar eclipses only)\n\
371
+ Julian day number (6-digit fraction) of maximum\n\
372
+ output 2nd line:\n\
373
+ local eclipse duration for totality (zero with partial occultations)\n\
374
+ local four contacts,\n\
375
+ delta t in sec\n\
376
+ Occultations with the remark \"(daytime)\" cannot be observed because\n\
377
+ they are taking place by daylight. Occultations with the remark\n\
378
+ \"(sunrise)\" or \"(sunset)\" can be observed only partly because part\n\
379
+ of them takes place in daylight.\n\
380
+ -hev[type] heliacal events,\n\
381
+ type 1 = heliacal rising\n\
382
+ type 2 = heliacal setting\n\
383
+ type 3 = evening first\n\
384
+ type 4 = morning last\n\
385
+ type 0 or missing = all four events are listed.\n\
386
+ -rise rising and setting of a planet or star.\n\
387
+ Use -geopos[long,lat,elev] to specify geographical position.\n\
388
+ -metr southern and northern meridian transit of a planet of star\n\
389
+ Use -geopos[long,lat,elev] to specify geographical position.\n\
390
+ specifications for eclipses:\n\
391
+ -total total eclipse (only with -solecl, -lunecl)\n\
392
+ -partial partial eclipse (only with -solecl, -lunecl)\n\
393
+ -annular annular eclipse (only with -solecl)\n\
394
+ -anntot annular-total (hybrid) eclipse (only with -solecl)\n\
395
+ -penumbral penumbral lunar eclipse (only with -lunecl)\n\
396
+ -central central eclipse (only with -solecl, nonlocal)\n\
397
+ -noncentral non-central eclipse (only with -solecl, nonlocal)\n\
398
+ ";
399
+ static char *infocmd6 = "\
400
+ specifications for risings and settings:\n\
401
+ -norefrac neglect refraction (with option -rise)\n\
402
+ -disccenter find rise of disc center (with option -rise)\n\
403
+ -discbottom find rise of disc bottom (with option -rise)\n\
404
+ -hindu hindu version of sunrise (with option -rise)\n\
405
+ specifications for heliacal events:\n\
406
+ -at[press,temp,rhum,visr]:\n\
407
+ pressure in hPa\n\
408
+ temperature in degrees Celsius\n\
409
+ relative humidity in %\n\
410
+ visual range, interpreted as follows:\n\
411
+ > 1 : meteorological range in km\n\
412
+ 1>visr>0 : total atmospheric coefficient (ktot)\n\
413
+ = 0 : calculated from press, temp, rhum\n\
414
+ Default values are -at1013.25,15,40,0\n\
415
+ -obs[age,SN] age of observer and Snellen ratio\n\
416
+ Default values are -obs36,1\n\
417
+ -opt[age,SN,binocular,magn,diam,transm]\n\
418
+ age and SN as with -obs\n\
419
+ 0 monocular or 1 binocular\n\
420
+ telescope magnification\n\
421
+ optical aperture in mm\n\
422
+ optical transmission\n\
423
+ Default values: -opt36,1,1,1,0,0 (naked eye)\n\
424
+ backward search:\n\
425
+ -bwd\n";
426
+ /* characters still available:
427
+ ijklruv
428
+ */
429
+ static char *infoplan = "\n\
430
+ Planet selection letters:\n\
431
+ planetary lists:\n\
432
+ d (default) main factors 0123456789mtABCcg\n\
433
+ p main factors as above, plus main asteroids DEFGHI\n\
434
+ h ficticious factors J..X\n\
435
+ a all factors\n\
436
+ (the letters above can only appear as a single letter)\n\n\
437
+ single body numbers/letters:\n\
438
+ 0 Sun (character zero)\n\
439
+ 1 Moon (character 1)\n\
440
+ 2 Mercury\n\
441
+ 3 Venus\n\
442
+ 4 Mars\n\
443
+ 5 Jupiter\n\
444
+ 6 Saturn\n\
445
+ 7 Uranus\n\
446
+ 8 Neptune\n\
447
+ 9 Pluto\n\
448
+ m mean lunar node\n\
449
+ t true lunar node\n\
450
+ n nutation\n\
451
+ o obliquity of ecliptic\n\
452
+ q delta t\n\
453
+ y time equation\n\
454
+ b ayanamsha\n\
455
+ A mean lunar apogee (Lilith, Black Moon) \n\
456
+ B osculating lunar apogee \n\
457
+ c intp. lunar apogee \n\
458
+ g intp. lunar perigee \n\
459
+ C Earth (in heliocentric or barycentric calculation)\n\
460
+ For planets Jupiter to Pluto the center of body (COB) can be\n\
461
+ calculated using the additional parameter -cob\n\
462
+ dwarf planets, plutoids\n\
463
+ F Ceres\n\
464
+ 9 Pluto\n\
465
+ s -xs136199 Eris\n\
466
+ s -xs136472 Makemake\n\
467
+ s -xs136108 Haumea\n\
468
+ some minor planets:\n\
469
+ D Chiron\n\
470
+ E Pholus\n\
471
+ G Pallas \n\
472
+ H Juno \n\
473
+ I Vesta \n\
474
+ s minor planet, with MPC number given in -xs\n\
475
+ some planetary moons and center of body of a planet:\n\
476
+ v with moon number given in -xv:\n\
477
+ v -xv9501 Io/Jupiter:\n\
478
+ v -xv9599 Jupiter, center of body (COB):\n\
479
+ v -xv94.. Mars moons:\n\
480
+ v -xv95.. Jupiter moons and COB:\n\
481
+ v -xv96.. Saturn moons and COB:\n\
482
+ v -xv97.. Uranus moons and COB:\n\
483
+ v -xv98.. Neptune moons and COB:\n\
484
+ v -xv99.. Pluto moons and COB:\n\
485
+ The numbers of the moons are given here: \n\
486
+ https://www.astro.com/ftp/swisseph/ephe/sat/plmolist.txt\n\
487
+ fixed stars:\n\
488
+ f fixed star, with name or number given in -xf option\n\
489
+ f -xfSirius Sirius\n\
490
+ fictitious objects:\n\
491
+ J Cupido \n\
492
+ K Hades \n\
493
+ L Zeus \n\
494
+ M Kronos \n\
495
+ N Apollon \n\
496
+ O Admetos \n\
497
+ P Vulkanus \n\
498
+ Q Poseidon \n\
499
+ R Isis (Sevin) \n\
500
+ S Nibiru (Sitchin) \n\
501
+ T Harrington \n\
502
+ U Leverrier's Neptune\n\
503
+ V Adams' Neptune\n\
504
+ W Lowell's Pluto\n\
505
+ X Pickering's Pluto\n\
506
+ Y Vulcan\n\
507
+ Z White Moon\n\
508
+ w Waldemath's dark Moon\n\
509
+ z hypothetical body, with number given in -xz\n\
510
+ sidereal time:\n\
511
+ x sidereal time\n\
512
+ e print a line of labels\n\
513
+ \n";
514
+ /* characters still available
515
+ CcEeMmOoqWwz
516
+ */
517
+ static char *infoform = "\n\
518
+ Output format SEQ letters:\n\
519
+ In the standard setting five columns of coordinates are printed with\n\
520
+ the default format PLBRS. You can change the default by providing an\n\
521
+ option like -fCCCC where CCCC is your sequence of columns.\n\
522
+ The coding of the sequence is like this:\n\
523
+ y year\n\
524
+ Y year.fraction_of_year\n\
525
+ p planet index\n\
526
+ P planet name\n\
527
+ J absolute juldate\n\
528
+ T date formatted like 23.02.1992 \n\
529
+ t date formatted like 920223 for 1992 february 23\n\
530
+ L longitude in degree ddd mm'ss\"\n\
531
+ l longitude decimal\n\
532
+ Z longitude ddsignmm'ss\"\n\
533
+ S speed in longitude in degree ddd:mm:ss per day\n\
534
+ SS speed for all values specified in fmt\n\
535
+ s speed longitude decimal (degrees/day)\n\
536
+ ss speed for all values specified in fmt\n\
537
+ B latitude degree\n\
538
+ b latitude decimal\n\
539
+ R distance decimal in AU\n\
540
+ r distance decimal in AU, Moon in seconds parallax\n\
541
+ W distance decimal in light years\n\
542
+ w distance decimal in km\n\
543
+ q relative distance (1000=nearest, 0=furthest)\n\
544
+ A right ascension in hh:mm:ss\n\
545
+ a right ascension hours decimal\n\
546
+ m Meridian distance \n\
547
+ z Zenith distance \n\
548
+ D declination degree\n\
549
+ d declination decimal\n\
550
+ I azimuth degree\n\
551
+ i azimuth decimal\n\
552
+ H altitude degree\n\
553
+ h altitude decimal\n\
554
+ K altitude (with refraction) degree\n\
555
+ k altitude (with refraction) decimal\n\
556
+ G house position in degrees\n\
557
+ g house position in degrees decimal\n\
558
+ j house number 1.0 - 12.99999\n\
559
+ X x-, y-, and z-coordinates ecliptical\n\
560
+ x x-, y-, and z-coordinates equatorial\n\
561
+ U unit vector ecliptical\n\
562
+ u unit vector equatorial\n\
563
+ Q l, b, r, dl, db, dr, a, d, da, dd\n\
564
+ n nodes (mean): ascending/descending (Me - Ne); longitude decimal\n\
565
+ N nodes (osculating): ascending/descending, longitude; decimal\n\
566
+ f apsides (mean): perihelion, aphelion, second focal point; longitude dec.\n\
567
+ F apsides (osc.): perihelion, aphelion, second focal point; longitude dec.\n\
568
+ + phase angle\n\
569
+ - phase\n\
570
+ * elongation\n\
571
+ / apparent diameter of disc (without refraction)\n\
572
+ = magnitude\n";
573
+ static char *infoform2 = "\
574
+ v (reserved)\n\
575
+ V (reserved)\n\
576
+ ";
577
+ static char *infodate = "\n\
578
+ Date entry:\n\
579
+ In the interactive mode, when you are asked for a start date,\n\
580
+ you can enter data in one of the following formats:\n\
581
+ \n\
582
+ 1.2.1991 three integers separated by a nondigit character for\n\
583
+ day month year. Dates are interpreted as Gregorian\n\
584
+ after 4.10.1582 and as Julian Calendar before.\n\
585
+ Time is always set to midnight (0 h).\n\
586
+ If the three letters jul are appended to the date,\n\
587
+ the Julian calendar is used even after 1582.\n\
588
+ If the four letters greg are appended to the date,\n\
589
+ the Gregorian calendar is used even before 1582.\n\
590
+ \n\
591
+ j2400123.67 the letter j followed by a real number, for\n\
592
+ the absolute Julian daynumber of the start date.\n\
593
+ Fraction .5 indicates midnight, fraction .0\n\
594
+ indicates noon, other times of the day can be\n\
595
+ chosen accordingly.\n\
596
+ \n\
597
+ <RETURN> repeat the last entry\n\
598
+ \n\
599
+ . stop the program\n\
600
+ \n\
601
+ +20 advance the date by 20 days\n\
602
+ \n\
603
+ -10 go back in time 10 days\n";
604
+ static char *infoexamp = "\n\
605
+ \n\
606
+ Examples:\n\
607
+ \n\
608
+ swetest -p2 -b1.12.1900 -n15 -s2\n\
609
+ ephemeris of Mercury (-p2) starting on 1 Dec 1900,\n\
610
+ 15 positions (-n15) in two-day steps (-s2)\n\
611
+ \n\
612
+ swetest -p2 -b1.12.1900 -n15 -s2 -fTZ -roundsec -g, -head\n\
613
+ same, but output format = date and zodiacal position (-fTZ),\n\
614
+ separated by comma (-g,) and rounded to seconds (-roundsec),\n\
615
+ without header (-head).\n\
616
+ \n\
617
+ swetest -ps -xs433 -b1.12.1900\n\
618
+ position of asteroid 433 Eros (-ps -xs433)\n\
619
+ \n\
620
+ swetest -pf -xfAldebaran -b1.1.2000\n\
621
+ position of fixed star Aldebaran \n\
622
+ \n\
623
+ swetest -p1 -d0 -b1.12.1900 -n10 -fPTl -head\n\
624
+ angular distance of moon (-p1) from sun (-d0) for 10\n\
625
+ consecutive days (-n10).\n\
626
+ \n\
627
+ swetest -p6 -DD -b1.12.1900 -n100 -s5 -fPTZ -head -roundmin\n\
628
+ Midpoints between Saturn (-p6) and Chiron (-DD) for 100\n\
629
+ consecutive steps (-n100) with 5-day steps (-s5) with\n\
630
+ longitude in degree-sign format (-f..Z) rounded to minutes (-roundmin)\n\
631
+ \n\
632
+ swetest -b5.1.2002 -p -house12.05,49.50,K -ut12:30\n\
633
+ Koch houses for a location in Germany at a given date and time\n\
634
+ \n\
635
+ swetest -b1.1.2016 -g -fTlbR -p0123456789Dmte -hor -n366 -roundsec\n\
636
+ tabular ephemeris (all planets Sun - Pluto, Chiron, mean node, true node)\n\
637
+ in one horizontal row, tab-separated, for 366 days. For each planet\n\
638
+ list longitude, latitude and geocentric distance.\n";
639
+ /**************************************************************/
640
+
641
+ #include "swephexp.h" /* this includes "sweodef.h" */
642
+ #include "swephlib.h"
643
+ #include "sweph.h"
644
+
645
+ /*
646
+ * programmers warning: It looks much worse than it is!
647
+ * Originally swetest.c was a small and simple test program to test
648
+ * the main functions of the Swiss Ephemeris and to demonstrate
649
+ * its precision.
650
+ * It compiles on Unix, on MSDOS and as a non-GUI utility on 16-bit
651
+ * and 32-bit windows.
652
+ * This portability has forced us into some clumsy constructs, which
653
+ * end to hide the actual simplicity of the use of Swiss Ephemeris.
654
+ * For example, the mechanism implemented here in swetest.c to find
655
+ * the binary ephemeris files overrides the much simpler mechanism
656
+ * inside the SwissEph library. This was necessary because we wanted
657
+ * swetest.exe to run directly off the CDROM and search with some
658
+ * intelligence for ephemeris files already installed on a system.
659
+ */
660
+
661
+ #if MSDOS
662
+ # include <direct.h>
663
+ # include <dos.h>
664
+ # ifdef _MSC_VER
665
+ # include <sys\types.h>
666
+ # endif
667
+ #ifdef __MINGW32__
668
+ # include <sys/stat.h>
669
+ #else
670
+ # include <sys\stat.h>
671
+ #endif
672
+ # include <float.h>
673
+ #else
674
+ # ifdef MACOS
675
+ # include <console.h>
676
+ # else
677
+ # include <sys/stat.h>
678
+ # endif
679
+ #endif
680
+
681
+ #define J2000 2451545.0 /* 2000 January 1.5 */
682
+ #define square_sum(x) (x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
683
+ #define SEFLG_EPHMASK (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH)
684
+
685
+ #define BIT_ROUND_SEC 1
686
+ #define BIT_ROUND_MIN 2
687
+ #define BIT_ZODIAC 4
688
+ #define BIT_LZEROES 8
689
+
690
+ #define BIT_TIME_LZEROES 8
691
+ #define BIT_TIME_LMT 16
692
+ #define BIT_TIME_LAT 32
693
+ #define BIT_ALLOW_361 64
694
+
695
+ #define PLSEL_D "0123456789mtA"
696
+ #define PLSEL_P "0123456789mtABCcgDEFGHI"
697
+ #define PLSEL_H "JKLMNOPQRSTUVWXYZw"
698
+ #define PLSEL_A "0123456789mtABCcgDEFGHIJKLMNOPQRSTUVWXYZw"
699
+
700
+ #define DIFF_DIFF 'd'
701
+ #define DIFF_GEOHEL 'h'
702
+ #define DIFF_MIDP 'D'
703
+ #define MODE_HOUSE 1
704
+ #define MODE_LABEL 2
705
+ #define MODE_AYANAMSA 4
706
+
707
+ #define SEARCH_RANGE_LUNAR_CYCLES 20000
708
+
709
+ #define LEN_SOUT 1000 // length of output string variable
710
+ #define SIND(x) sin((x) * DEGTORAD)
711
+ #define COSD(x) cos((x) * DEGTORAD)
712
+ #define ACOSD(x) (acos((x)) * RADTODEG)
713
+
714
+ static char se_pname[AS_MAXCH];
715
+ static char *zod_nam[] = {"ar", "ta", "ge", "cn", "le", "vi",
716
+ "li", "sc", "sa", "cp", "aq", "pi"};
717
+
718
+ static char star[AS_MAXCH] = "algol", star2[AS_MAXCH];
719
+ static char sastno[AS_MAXCH] = "433";
720
+ static char shyp[AS_MAXCH] = "1";
721
+ static char *dms(double x, int32 iflag);
722
+ static int make_ephemeris_path(char *argv0, char *ephepath);
723
+ static int letter_to_ipl(int letter);
724
+ static int print_line(int mode, AS_BOOL is_first, int sid_mode);
725
+ static int do_special_event(double tjd, int32 ipl, char *star, int32 special_event, int32 special_mode, double *geopos, double *datm, double *dobs, char *serr) ;
726
+ static int32 orbital_elements(double tjd_et, int32 ipl, int32 iflag, char *serr);
727
+ static char *hms_from_tjd(double x);
728
+ static void do_printf(char *info);
729
+ static char *hms(double x, int32 iflag);
730
+ static void remove_whitespace(char *s);
731
+ #if MSDOS
732
+ static int cut_str_any(char *s, char *cutlist, char *cpos[], int nmax);
733
+ #endif
734
+ static int32 call_swe_fixstar(char *star, double te, int32 iflag, double *x, char *serr);
735
+ static void jd_to_time_string(double jut, char *stimeout);
736
+ static char *our_strcpy(char *to, char *from);
737
+
738
+ /* globals shared between main() and print_line() */
739
+ static char *fmt = "PLBRS";
740
+ static char *gap = " ";
741
+ static double t, te, tut, jut = 0;
742
+ static int jmon, jday, jyear;
743
+ static int ipl = SE_SUN, ipldiff = SE_SUN, nhouses = 12;
744
+ static int iplctr = SE_SUN;
745
+ static char spnam[AS_MAXCH], spnam2[AS_MAXCH], serr[AS_MAXCH];
746
+ static char serr_save[AS_MAXCH], serr_warn[AS_MAXCH];
747
+ static int gregflag = SE_GREG_CAL;
748
+ static AS_BOOL gregflag_auto = TRUE;
749
+ static int diff_mode = 0;
750
+ static AS_BOOL use_dms = FALSE;
751
+ static AS_BOOL universal_time = FALSE;
752
+ static AS_BOOL universal_time_utc = FALSE;
753
+ static int32 round_flag = 0;
754
+ static int32 time_flag = 0;
755
+ static AS_BOOL short_output = FALSE;
756
+ static AS_BOOL list_hor = FALSE;
757
+ static int32 special_event = 0;
758
+ static int32 special_mode = 0;
759
+ static AS_BOOL do_orbital_elements = FALSE;
760
+ static AS_BOOL hel_using_AV = FALSE;
761
+ static AS_BOOL with_header = TRUE;
762
+ static AS_BOOL with_chart_link = FALSE;
763
+ static double x[6], x2[6], xequ[6], xcart[6], xcartq[6], xobl[6], xaz[6], xt[6], hpos, hpos2, hposj, armc, xsv[6];
764
+ static int hpos_meth = 0;
765
+ static double geopos[10];
766
+ static double attr[20], tret[20], datm[4], dobs[6];
767
+ static int32 iflag = 0, iflag2; /* external flag: helio, geo... */
768
+ static char *hs_nam[] =
769
+ {"undef", "Ascendant", "MC", "ARMC", "Vertex", "equat. Asc.","co-Asc. W.Koch", "co-Asc Munkasey", "Polar Asc."};
770
+ static int direction = 1;
771
+ static AS_BOOL direction_flag = FALSE;
772
+ static AS_BOOL step_in_minutes = FALSE;
773
+ static AS_BOOL step_in_seconds = FALSE;
774
+ static AS_BOOL step_in_years = FALSE;
775
+ static AS_BOOL step_in_months = FALSE;
776
+ static int32 helflag = 0;
777
+ static double tjd = 2415020.5;
778
+ static int32 nstep = 1, istep;
779
+ static int32 search_flag = 0;
780
+ static char sout[LEN_SOUT];
781
+ static int32 whicheph = SEFLG_SWIEPH;
782
+ static char *psp;
783
+ static int32 norefrac = 0;
784
+ static int32 disccenter = 0;
785
+ static int32 discbottom = 0;
786
+ static int32 hindu = 0;
787
+ /* for test of old models only */
788
+ static char *astro_models;
789
+ static int do_set_astro_models = FALSE;
790
+ static char smod[2000];
791
+ static AS_BOOL inut = FALSE; /* for Astrodienst internal feature */
792
+ static AS_BOOL have_gap_parameter = FALSE;
793
+ static AS_BOOL use_swe_fixstar2 = FALSE;
794
+ static AS_BOOL output_extra_prec = FALSE;
795
+ static AS_BOOL show_file_limit = FALSE;
796
+
797
+ #define SP_LUNAR_ECLIPSE 1
798
+ #define SP_SOLAR_ECLIPSE 2
799
+ #define SP_OCCULTATION 3
800
+ #define SP_RISE_SET 4
801
+ #define SP_MERIDIAN_TRANSIT 5
802
+ #define SP_HELIACAL 6
803
+
804
+ # define SP_MODE_HOW 2 /* an option for Lunar */
805
+ # define SP_MODE_LOCAL 8 /* an option for Solar */
806
+ # define SP_MODE_HOCAL 4096
807
+
808
+ # define ECL_LUN_PENUMBRAL 1 /* eclipse types for hocal list */
809
+ # define ECL_LUN_PARTIAL 2
810
+ # define ECL_LUN_TOTAL 3
811
+ # define ECL_SOL_PARTIAL 4
812
+ # define ECL_SOL_ANNULAR 5
813
+ # define ECL_SOL_TOTAL 6
814
+
815
+ int main(int argc, char *argv[])
816
+ {
817
+ char sdate_save[AS_MAXCH];
818
+ char s1[AS_MAXCH], s2[AS_MAXCH];
819
+ char *sp, *sp2;
820
+ char *spno;
821
+ char *plsel = PLSEL_D;
822
+ #if HPUNIX
823
+ char hostname[80];
824
+ #endif
825
+ int i, j, n, iflag_f = -1, iflgt;
826
+ int line_count, line_limit = 36525; // days in a century
827
+ double daya;
828
+ double top_long = 0.0; /* Greenwich UK */
829
+ double top_lat = 51.5;
830
+ double top_elev = 0;
831
+ AS_BOOL have_geopos = FALSE;
832
+ int ihsy = 'P';
833
+ int year_start = 0, mon_start = 1, day_start = 1;
834
+ AS_BOOL do_houses = FALSE;
835
+ char ephepath[AS_MAXCH];
836
+ char fname[AS_MAXCH];
837
+ char sdate[AS_MAXCH];
838
+ char *begindate = NULL;
839
+ char stimein[AS_MAXCH];
840
+ char stimeout[AS_MAXCH];
841
+ int32 iflgret;
842
+ AS_BOOL is_first = TRUE;
843
+ AS_BOOL with_glp = FALSE;
844
+ AS_BOOL with_header_always = FALSE;
845
+ AS_BOOL do_ayanamsa = FALSE;
846
+ AS_BOOL do_planeto_centric = FALSE;
847
+ double aya_t0 = 0, aya_val0 = 0;
848
+ AS_BOOL no_speed = FALSE;
849
+ int32 sid_mode = SE_SIDM_FAGAN_BRADLEY;
850
+ double t2, tstep = 1, thour = 0;
851
+ double delt;
852
+ double tid_acc = 0;
853
+ datm[0] = 1013.25; datm[1] = 15; datm[2] = 40; datm[3] = 0;
854
+ dobs[0] = 0; dobs[1] = 0;
855
+ dobs[2] = 0; dobs[3] = 0; dobs[4] = 0; dobs[5] = 0;
856
+ serr[0] = serr_save[0] = serr_warn[0] = sdate_save[0] = '\0';
857
+ # ifdef MACOS
858
+ argc = ccommand(&argv); /* display the arguments window */
859
+ # endif
860
+ *stimein = '\0';
861
+ strcpy(ephepath, "");
862
+ strcpy(fname, SE_FNAME_DFT);
863
+ for (i = 1; i < argc; i++) {
864
+ if (strncmp(argv[i], "-utc", 4) == 0) {
865
+ universal_time = TRUE;
866
+ universal_time_utc = TRUE;
867
+ if (strlen(argv[i]) > 4) {
868
+ strncpy(stimein, argv[i] + 4, 30);
869
+ stimein[30] = '\0';
870
+ }
871
+ } else if (strncmp(argv[i], "-ut", 3) == 0) {
872
+ universal_time = TRUE;
873
+ if (strlen(argv[i]) > 3) {
874
+ strncpy(stimein, argv[i] + 3, 30);
875
+ stimein[30] = '\0';
876
+ }
877
+ } else if (strncmp(argv[i], "-glp", 4) == 0) {
878
+ with_glp = TRUE;
879
+ } else if (strncmp(argv[i], "-hor", 4) == 0) {
880
+ list_hor = TRUE;
881
+ } else if (strncmp(argv[i], "-head", 5) == 0) {
882
+ with_header = FALSE;
883
+ } else if (strncmp(argv[i], "+head", 5) == 0) {
884
+ with_header_always = TRUE;
885
+ } else if (strcmp(argv[i], "-j2000") == 0) {
886
+ iflag |= SEFLG_J2000;
887
+ } else if (strcmp(argv[i], "-icrs") == 0) {
888
+ iflag |= SEFLG_ICRS;
889
+ } else if (strcmp(argv[i], "-cob") == 0) {
890
+ iflag |= SEFLG_CENTER_BODY;
891
+ } else if (strncmp(argv[i], "-ay", 3) == 0) {
892
+ do_ayanamsa = TRUE;
893
+ sid_mode = atol(argv[i]+3);
894
+ /*swe_set_sid_mode(sid_mode, 0, 0);*/
895
+ } else if (strncmp(argv[i], "-sidt0", 6) == 0) {
896
+ iflag |= SEFLG_SIDEREAL;
897
+ sid_mode = atol(argv[i]+6);
898
+ if (sid_mode == 0)
899
+ sid_mode = SE_SIDM_FAGAN_BRADLEY;
900
+ sid_mode |= SE_SIDBIT_ECL_T0;
901
+ /*swe_set_sid_mode(sid_mode, 0, 0);*/
902
+ } else if (strncmp(argv[i], "-sidsp", 6) == 0) {
903
+ iflag |= SEFLG_SIDEREAL;
904
+ sid_mode = atol(argv[i]+6);
905
+ if (sid_mode == 0)
906
+ sid_mode = SE_SIDM_FAGAN_BRADLEY;
907
+ sid_mode |= SE_SIDBIT_SSY_PLANE;
908
+ } else if (strncmp(argv[i], "-sidudef", 8) == 0) {
909
+ iflag |= SEFLG_SIDEREAL;
910
+ sid_mode = SE_SIDM_USER;
911
+ strcpy(s1, argv[i] + 8);
912
+ aya_t0 = atof(s1);
913
+ if ((sp = strchr(s1, ',')) != NULL) {
914
+ aya_val0 = atof(sp+1);
915
+ }
916
+ if (strstr(sp, "jdisut") != NULL) {
917
+ sid_mode |= SE_SIDBIT_USER_UT;
918
+ }
919
+ /*swe_set_sid_mode(sid_mode, 0, 0);*/
920
+ } else if (strncmp(argv[i], "-sidbit", 7) == 0) {
921
+ sid_mode |= atoi(argv[i]+7);
922
+ } else if (strncmp(argv[i], "-sid", 4) == 0) {
923
+ iflag |= SEFLG_SIDEREAL;
924
+ sid_mode = atol(argv[i]+4);
925
+ /*if (sid_mode > 0)
926
+ swe_set_sid_mode(sid_mode, 0, 0);*/
927
+ } else if (strcmp(argv[i], "-jplhora") == 0) {
928
+ iflag |= SEFLG_JPLHOR_APPROX;
929
+ } else if (strcmp(argv[i], "-tpm") == 0) {
930
+ iflag |= SEFLG_TEST_PLMOON;
931
+ } else if (strcmp(argv[i], "-jplhor") == 0) {
932
+ iflag |= SEFLG_JPLHOR;
933
+ } else if (strncmp(argv[i], "-j", 2) == 0) {
934
+ begindate = argv[i] + 1;
935
+ } else if (strncmp(argv[i], "-ejpl", 5) == 0) {
936
+ whicheph = SEFLG_JPLEPH;
937
+ if (*(argv[i]+5) != '\0') {
938
+ strncpy(fname, argv[i]+5, AS_MAXCH - 1);
939
+ fname[AS_MAXCH-1] = '\0';
940
+ }
941
+ } else if (strncmp(argv[i], "-edir", 5) == 0) {
942
+ if (*(argv[i]+5) != '\0') {
943
+ strncpy(ephepath, argv[i]+5, AS_MAXCH - 1);
944
+ ephepath[AS_MAXCH-1] = '\0';
945
+ }
946
+ } else if (strcmp(argv[i], "-eswe") == 0) {
947
+ whicheph = SEFLG_SWIEPH;
948
+ } else if (strcmp(argv[i], "-emos") == 0) {
949
+ whicheph = SEFLG_MOSEPH;
950
+ } else if (strncmp(argv[i], "-helflag", 8) == 0) {
951
+ helflag = atoi(argv[i]+8);
952
+ if (helflag >= SE_HELFLAG_AV)
953
+ hel_using_AV = TRUE;
954
+ } else if (strcmp(argv[i], "-hel") == 0) {
955
+ iflag |= SEFLG_HELCTR;
956
+ } else if (strcmp(argv[i], "-bary") == 0) {
957
+ iflag |= SEFLG_BARYCTR;
958
+ } else if (strncmp(argv[i], "-house", 6) == 0) {
959
+ sout[0] = '\0';
960
+ sout[1] = '\0';
961
+ sp = argv[i] + 6;
962
+ if (*sp == '[') sp++;
963
+ sscanf(sp, "%lf,%lf,%c", &top_long, &top_lat, sout);
964
+ top_elev = 0;
965
+ if (*sout) ihsy = sout[0];
966
+ do_houses = TRUE;
967
+ have_geopos = TRUE;
968
+ } else if (strncmp(argv[i], "-hsy", 4) == 0) {
969
+ ihsy = *(argv[i] + 4);
970
+ if (ihsy == '\0') ihsy = 'P';
971
+ if (strlen(argv[i]) > 5)
972
+ hpos_meth = atoi(argv[i] + 5);
973
+ have_geopos = TRUE;
974
+ } else if (strncmp(argv[i], "-topo", 5) == 0) {
975
+ iflag |= SEFLG_TOPOCTR;
976
+ sp = argv[i] + 5;
977
+ if (*sp == '[') sp++;
978
+ sscanf(sp, "%lf,%lf,%lf", &top_long, &top_lat, &top_elev);
979
+ have_geopos = TRUE;
980
+ } else if (strncmp(argv[i], "-geopos", 7) == 0) {
981
+ sp = argv[i] + 7;
982
+ if (*sp == '[') sp++;
983
+ sscanf(sp, "%lf,%lf,%lf", &top_long, &top_lat, &top_elev);
984
+ have_geopos = TRUE;
985
+ } else if (strcmp(argv[i], "-true") == 0) {
986
+ iflag |= SEFLG_TRUEPOS;
987
+ } else if (strcmp(argv[i], "-noaberr") == 0) {
988
+ iflag |= SEFLG_NOABERR;
989
+ } else if (strcmp(argv[i], "-nodefl") == 0) {
990
+ iflag |= SEFLG_NOGDEFL;
991
+ } else if (strcmp(argv[i], "-nonut") == 0) {
992
+ iflag |= SEFLG_NONUT;
993
+ } else if (strcmp(argv[i], "-speed3") == 0) {
994
+ iflag |= SEFLG_SPEED3;
995
+ } else if (strcmp(argv[i], "-speed") == 0) {
996
+ iflag |= SEFLG_SPEED;
997
+ } else if (strcmp(argv[i], "-nospeed") == 0) {
998
+ no_speed = TRUE;
999
+ } else if (strncmp(argv[i], "-testaa", 7) == 0) {
1000
+ whicheph = SEFLG_JPLEPH;
1001
+ strcpy(fname, SE_FNAME_DE200);
1002
+ if (strcmp(argv[i]+7, "95") == 0)
1003
+ begindate = "j2449975.5";
1004
+ if (strcmp(argv[i]+7, "96") == 0)
1005
+ begindate = "j2450442.5";
1006
+ if (strcmp(argv[i]+7, "97") == 0)
1007
+ begindate = "j2450482.5";
1008
+ fmt = "PADRu";
1009
+ universal_time = FALSE;
1010
+ plsel="3";
1011
+ } else if (strncmp(argv[i], "-lmt", 4) == 0) {
1012
+ universal_time = TRUE;
1013
+ time_flag |= BIT_TIME_LMT;
1014
+ if (strlen(argv[i]) > 4) {
1015
+ strncpy(stimein, argv[i] + 4, 30);
1016
+ stimein[30] = '\0';
1017
+ }
1018
+ } else if (strcmp(argv[i], "-lat") == 0) {
1019
+ universal_time = TRUE;
1020
+ time_flag |= BIT_TIME_LAT;
1021
+ } else if (strcmp(argv[i], "-lim") == 0) {
1022
+ show_file_limit = TRUE;
1023
+ } else if (strcmp(argv[i], "-clink") == 0) {
1024
+ with_chart_link = TRUE;
1025
+ } else if (strcmp(argv[i], "-lunecl") == 0) {
1026
+ special_event = SP_LUNAR_ECLIPSE;
1027
+ } else if (strcmp(argv[i], "-solecl") == 0) {
1028
+ special_event = SP_SOLAR_ECLIPSE;
1029
+ have_geopos = TRUE;
1030
+ } else if (strcmp(argv[i], "-short") == 0) {
1031
+ short_output = TRUE;
1032
+ } else if (strcmp(argv[i], "-occult") == 0) {
1033
+ special_event = SP_OCCULTATION;
1034
+ have_geopos = TRUE;
1035
+ } else if (strcmp(argv[i], "-ep") == 0) {
1036
+ output_extra_prec = TRUE;
1037
+ } else if (strcmp(argv[i], "-hocal") == 0) {
1038
+ /* used to create a listing for inclusion in hocal.c source code */
1039
+ special_mode |= SP_MODE_HOCAL;
1040
+ } else if (strcmp(argv[i], "-how") == 0) {
1041
+ special_mode |= SP_MODE_HOW;
1042
+ } else if (strcmp(argv[i], "-total") == 0) {
1043
+ search_flag |= SE_ECL_TOTAL;
1044
+ } else if (strcmp(argv[i], "-annular") == 0) {
1045
+ search_flag |= SE_ECL_ANNULAR;
1046
+ } else if (strcmp(argv[i], "-anntot") == 0) {
1047
+ search_flag |= SE_ECL_ANNULAR_TOTAL;
1048
+ } else if (strcmp(argv[i], "-partial") == 0) {
1049
+ search_flag |= SE_ECL_PARTIAL;
1050
+ } else if (strcmp(argv[i], "-penumbral") == 0) {
1051
+ search_flag |= SE_ECL_PENUMBRAL;
1052
+ } else if (strcmp(argv[i], "-noncentral") == 0) {
1053
+ search_flag &= ~SE_ECL_CENTRAL;
1054
+ search_flag |= SE_ECL_NONCENTRAL;
1055
+ } else if (strcmp(argv[i], "-central") == 0) {
1056
+ search_flag &= ~SE_ECL_NONCENTRAL;
1057
+ search_flag |= SE_ECL_CENTRAL;
1058
+ } else if (strcmp(argv[i], "-local") == 0) {
1059
+ special_mode |= SP_MODE_LOCAL;
1060
+ } else if (strcmp(argv[i], "-rise") == 0) {
1061
+ special_event = SP_RISE_SET;
1062
+ have_geopos = TRUE;
1063
+ } else if (strcmp(argv[i], "-norefrac") == 0) {
1064
+ norefrac = 1;
1065
+ } else if (strcmp(argv[i], "-disccenter") == 0) {
1066
+ disccenter = 1;
1067
+ } else if (strcmp(argv[i], "-hindu") == 0) {
1068
+ hindu = 1;
1069
+ norefrac = 1;
1070
+ disccenter = 1;
1071
+ } else if (strcmp(argv[i], "-discbottom") == 0) {
1072
+ discbottom = 1;
1073
+ } else if (strcmp(argv[i], "-metr") == 0) {
1074
+ special_event = SP_MERIDIAN_TRANSIT;
1075
+ have_geopos = TRUE;
1076
+ /* undocumented test feature */
1077
+ } else if (strncmp(argv[i], "-amod",5) == 0) {
1078
+ astro_models = argv[i] + 5;
1079
+ do_set_astro_models = TRUE;
1080
+ /* undocumented test feature */
1081
+ } else if (strncmp(argv[i], "-tidacc",7) == 0) {
1082
+ tid_acc = atof(argv[i] + 7);
1083
+ } else if (strncmp(argv[i], "-hev", 4) == 0) {
1084
+ special_event = SP_HELIACAL;
1085
+ search_flag = 0;
1086
+ sp = argv[i] + 4;
1087
+ if (*sp == '[') sp++;
1088
+ if (strlen(sp) > 0)
1089
+ search_flag = atoi(sp);
1090
+ have_geopos = TRUE;
1091
+ if (strstr(argv[i], "AV")) hel_using_AV = TRUE;
1092
+ } else if (strncmp(argv[i], "-at", 3) == 0) {
1093
+ sp = argv[i]+3;
1094
+ if (*sp == '[') sp++;
1095
+ j = 0;
1096
+ while (j < 4 && sp != NULL) {
1097
+ datm[j] = atof(sp);
1098
+ sp = strchr(sp, ',');
1099
+ if (sp != NULL) sp += 1;
1100
+ j++;
1101
+ }
1102
+ } else if (strncmp(argv[i], "-obs", 4) == 0) {
1103
+ sp = argv[i] + 4;
1104
+ if (*sp == '[') sp++;
1105
+ sscanf(sp, "%lf,%lf", &(dobs[0]), &(dobs[1]));
1106
+ } else if (strncmp(argv[i], "-opt", 4) == 0) {
1107
+ sp = argv[i] + 4;
1108
+ if (*sp == '[') sp++;
1109
+ sscanf(sp, "%lf,%lf,%lf,%lf,%lf,%lf", &(dobs[0]), &(dobs[1]), &(dobs[2]), &(dobs[3]), &(dobs[4]), &(dobs[5]));
1110
+ } else if (strcmp(argv[i], "-orbel") == 0) {
1111
+ do_orbital_elements = TRUE;
1112
+ } else if (strcmp(argv[i], "-bwd") == 0) {
1113
+ direction = -1;
1114
+ direction_flag = TRUE;
1115
+ } else if (strncmp(argv[i], "-pc", 3) == 0) {
1116
+ iplctr = atoi(argv[i]+3);
1117
+ do_planeto_centric = TRUE;
1118
+ } else if (strncmp(argv[i], "-p", 2) == 0) {
1119
+ spno = argv[i]+2;
1120
+ switch (*spno) {
1121
+ case 'd':
1122
+ /*
1123
+ case '\0':
1124
+ case ' ':
1125
+ */
1126
+ plsel = PLSEL_D; break;
1127
+ case 'p': plsel = PLSEL_P; break;
1128
+ case 'h': plsel = PLSEL_H; break;
1129
+ case 'a': plsel = PLSEL_A; break;
1130
+ default: plsel = spno;
1131
+ }
1132
+ } else if (strncmp(argv[i], "-xs", 3) == 0) {
1133
+ /* number of asteroid */
1134
+ strncpy(sastno, argv[i] + 3, AS_MAXCH - 1);
1135
+ sastno[AS_MAXCH-1] = '\0';
1136
+ } else if (strncmp(argv[i], "-xv", 3) == 0) {
1137
+ /* number of planetary moon */
1138
+ strncpy(sastno, argv[i] + 3, AS_MAXCH - 1);
1139
+ sastno[AS_MAXCH-1] = '\0';
1140
+ } else if (strncmp(argv[i], "-xf", 3) == 0) {
1141
+ /* name or number of fixed star */
1142
+ strncpy(star, argv[i] + 3, AS_MAXCH - 1);
1143
+ star[AS_MAXCH-1] = '\0';
1144
+ } else if (strncmp(argv[i], "-xz", 3) == 0) {
1145
+ /* number of hypothetical body */
1146
+ strncpy(shyp, argv[i] + 3, AS_MAXCH - 1);
1147
+ shyp[AS_MAXCH-1] = '\0';
1148
+ } else if (strncmp(argv[i], "-x", 2) == 0) {
1149
+ /* name or number of fixed star */
1150
+ strncpy(star, argv[i] + 2, AS_MAXCH - 1);
1151
+ star[AS_MAXCH-1] = '\0';
1152
+ } else if (strcmp(argv[i], "-nut") == 0) {
1153
+ inut = TRUE;
1154
+ } else if (strncmp(argv[i], "-n", 2) == 0) {
1155
+ nstep = atoi(argv[i]+2);
1156
+ if (nstep == 0)
1157
+ nstep = 20;
1158
+ } else if (strncmp(argv[i], "-i", 2) == 0) {
1159
+ iflag_f = atoi(argv[i]+2);
1160
+ if (iflag_f & SEFLG_XYZ)
1161
+ fmt = "PX";
1162
+ } else if (strcmp(argv[i], "-swefixstar2") == 0) {
1163
+ use_swe_fixstar2 = TRUE;
1164
+ } else if (strncmp(argv[i], "-s", 2) == 0) {
1165
+ tstep = atof(argv[i]+2);
1166
+ if (*(argv[i] + strlen(argv[i]) -1) == 'm')
1167
+ step_in_minutes = TRUE;
1168
+ if (*(argv[i] + strlen(argv[i]) -1) == 's')
1169
+ step_in_seconds = TRUE;
1170
+ if (*(argv[i] + strlen(argv[i]) -1) == 'y')
1171
+ step_in_years = TRUE;
1172
+ if (*(argv[i] + strlen(argv[i]) -1) == 'o') {
1173
+ step_in_minutes = FALSE;
1174
+ step_in_months = TRUE;
1175
+ }
1176
+ } else if (strncmp(argv[i], "-b", 2) == 0) {
1177
+ begindate = argv[i] + 2;
1178
+ } else if (strncmp(argv[i], "-f", 2) == 0) {
1179
+ fmt = argv[i] + 2;
1180
+ } else if (strncmp(argv[i], "-g", 2) == 0) {
1181
+ gap = argv[i] + 2;
1182
+ have_gap_parameter = TRUE;
1183
+ if (*gap == '\0') gap = "\t";
1184
+ } else if (strcmp(argv[i], "-dms") == 0) {
1185
+ use_dms = TRUE;
1186
+ } else if (strncmp(argv[i], "-d", 2) == 0
1187
+ || strncmp(argv[i], "-D", 2) == 0) {
1188
+ diff_mode = *(argv[i] + 1); /* 'd' or 'D' */
1189
+ sp = argv[i]+2;
1190
+ if (*(argv[i] + 2) == 'h') {
1191
+ sp++;
1192
+ diff_mode = 'h'; // diff helio to geo
1193
+ }
1194
+ ipldiff = letter_to_ipl((int) *sp);
1195
+ if (ipldiff <0) ipldiff = SE_SUN;
1196
+ swe_get_planet_name(ipldiff, spnam2);
1197
+ } else if (strcmp(argv[i], "-roundsec") == 0) {
1198
+ round_flag |= BIT_ROUND_SEC;
1199
+ } else if (strcmp(argv[i], "-roundmin") == 0) {
1200
+ round_flag |= BIT_ROUND_MIN;
1201
+ /*} else if (strncmp(argv[i], "-timeout", 8) == 0) {
1202
+ swe_set_timeout(atoi(argv[i]) + 8);*/
1203
+ } else if (strncmp(argv[i], "-t", 2) == 0) {
1204
+ if (strlen(argv[i]) > 2) {
1205
+ strncat(stimein, argv[i] + 2, 30);
1206
+ stimein[30] = '\0';
1207
+ }
1208
+ } else if (strncmp(argv[i], "-h", 2) == 0
1209
+ || strncmp(argv[i], "-?", 2) == 0) {
1210
+ sp = argv[i]+2;
1211
+ if (*sp == 'c' || *sp == '\0') {
1212
+ //char si0[strlen(infocmd0)+1]; // Microsoft Visual Studio does not like this
1213
+ char si0[2000];
1214
+ swe_version(sout);
1215
+ strcpy(si0, infocmd0);
1216
+ sp2 = strstr(si0, "Version:");
1217
+ if (sp2 != NULL && strlen(sp2) > 10 + strlen(sout))
1218
+ strcpy(sp2 + 9, sout);
1219
+ fputs(si0,stdout);
1220
+ fputs(infocmd1,stdout);
1221
+ fputs(infocmd2,stdout);
1222
+ fputs(infocmd3,stdout);
1223
+ fputs(infocmd4,stdout);
1224
+ fputs(infocmd5,stdout);
1225
+ fputs(infocmd6,stdout);
1226
+ }
1227
+ if (*sp == 'p' || *sp == '\0')
1228
+ fputs(infoplan,stdout);
1229
+ if (*sp == 'f' || *sp == '\0') {
1230
+ fputs(infoform,stdout);
1231
+ fputs(infoform2,stdout);
1232
+ }
1233
+ if (*sp == 'd' || *sp == '\0')
1234
+ fputs(infodate,stdout);
1235
+ if (*sp == 'e' || *sp == '\0')
1236
+ fputs(infoexamp,stdout);
1237
+ goto end_main;
1238
+ } else {
1239
+ strcpy(sout, "illegal option ");
1240
+ strncat(sout, argv[i], 100);
1241
+ sout[100] = '\0';
1242
+ strcat(sout, "\n");
1243
+ fputs(sout,stdout);
1244
+ exit(1);
1245
+ }
1246
+ }
1247
+ if (special_event == SP_OCCULTATION ||
1248
+ special_event == SP_RISE_SET ||
1249
+ special_event == SP_MERIDIAN_TRANSIT ||
1250
+ special_event == SP_HELIACAL
1251
+ ) {
1252
+ ipl = letter_to_ipl(*plsel);
1253
+ if (*plsel == 'f') {
1254
+ ipl = SE_FIXSTAR;
1255
+ } else {
1256
+ if (*plsel == 's')
1257
+ ipl = atoi(sastno) + SE_AST_OFFSET;
1258
+ *star = '\0';
1259
+ }
1260
+ if (special_event == SP_OCCULTATION && ipl == 1)
1261
+ ipl = 2; /* no occultation of moon by moon */
1262
+ }
1263
+ if (*stimein != '\0') {
1264
+ t = 0;
1265
+ if ((sp = strchr(stimein, ':')) != NULL) {
1266
+ if ((sp2 = strchr(sp + 1, ':')) != NULL) {
1267
+ t += atof(sp2 + 1) / 60.0;
1268
+ }
1269
+ t += atoi(sp + 1);
1270
+ t /= 60.0;
1271
+ }
1272
+ if (atoi(stimein) < 0)
1273
+ t = -t;
1274
+ t += atoi(stimein);
1275
+ //t += 0.0000000001;
1276
+ thour = t;
1277
+ }
1278
+ #if HPUNIX
1279
+ gethostname (hostname, 80);
1280
+ if (strstr(hostname, "as10") != NULL)
1281
+ line_limit = 1000;
1282
+ #endif
1283
+ #if MSDOS
1284
+ SetConsoleOutputCP(65001); // set console to utf-8,
1285
+ // works only from Windows Vista upwards, not on XP.
1286
+ #endif
1287
+ if (with_header) {
1288
+ for (i = 0; i < argc; i++) {
1289
+ fputs(argv[i],stdout);
1290
+ printf(" ");
1291
+ }
1292
+ }
1293
+ iflag = (iflag & ~SEFLG_EPHMASK) | whicheph;
1294
+ if (strpbrk(fmt, "SsQ") != NULL && !(iflag & SEFLG_SPEED3) && !no_speed)
1295
+ iflag |= SEFLG_SPEED;
1296
+ if (*ephepath == '\0') {
1297
+ if (make_ephemeris_path(argv[0], ephepath) == ERR) {
1298
+ iflag = (iflag & ~SEFLG_EPHMASK) | SEFLG_MOSEPH;
1299
+ whicheph = SEFLG_MOSEPH;
1300
+ }
1301
+ }
1302
+ if (whicheph != SEFLG_MOSEPH)
1303
+ swe_set_ephe_path(ephepath);
1304
+ if (whicheph & SEFLG_JPLEPH)
1305
+ swe_set_jpl_file(fname);
1306
+ /* the following is only a test feature */
1307
+ if (do_set_astro_models) {
1308
+ swe_set_astro_models(astro_models, iflag); /* secret test feature for dieter */
1309
+ swe_get_astro_models(astro_models, smod, iflag);
1310
+ }
1311
+ #if 1
1312
+ if (inut) /* Astrodienst internal feature */
1313
+ swe_set_interpolate_nut(TRUE);
1314
+ #endif
1315
+ if ((iflag & SEFLG_SIDEREAL) || do_ayanamsa) {
1316
+ if (sid_mode & SE_SIDM_USER)
1317
+ swe_set_sid_mode(sid_mode, aya_t0, aya_val0);
1318
+ else
1319
+ swe_set_sid_mode(sid_mode, 0, 0);
1320
+ }
1321
+ geopos[0] = top_long;
1322
+ geopos[1] = top_lat;
1323
+ geopos[2] = top_elev;
1324
+ swe_set_topo(top_long, top_lat, top_elev);
1325
+ if (tid_acc != 0)
1326
+ swe_set_tid_acc(tid_acc);
1327
+ serr[0] = serr_save[0] = serr_warn[0] = '\0';
1328
+ while (TRUE) {
1329
+ if (begindate == NULL) {
1330
+ printf("\nDate ?");
1331
+ sdate[0] = '\0';
1332
+ if( !fgets(sdate, AS_MAXCH, stdin) ) goto end_main;
1333
+ } else {
1334
+ strncpy(sdate, begindate, AS_MAXCH-1);
1335
+ sdate[AS_MAXCH-1] = '\0';
1336
+ begindate = "."; /* to exit afterwards */
1337
+ }
1338
+ if (strcmp(sdate, "-bary") == 0) {
1339
+ iflag = iflag & ~SEFLG_HELCTR;
1340
+ iflag |= SEFLG_BARYCTR;
1341
+ *sdate = '\0';
1342
+ } else if (strcmp(sdate, "-hel") == 0) {
1343
+ iflag = iflag & ~SEFLG_BARYCTR;
1344
+ iflag |= SEFLG_HELCTR;
1345
+ *sdate = '\0';
1346
+ } else if (strcmp(sdate, "-geo") == 0) {
1347
+ iflag = iflag & ~SEFLG_BARYCTR;
1348
+ iflag = iflag & ~SEFLG_HELCTR;
1349
+ *sdate = '\0';
1350
+ } else if (strcmp(sdate, "-ejpl") == 0) {
1351
+ iflag &= ~SEFLG_EPHMASK;
1352
+ iflag |= SEFLG_JPLEPH;
1353
+ *sdate = '\0';
1354
+ } else if (strcmp(sdate, "-eswe") == 0) {
1355
+ iflag &= ~SEFLG_EPHMASK;
1356
+ iflag |= SEFLG_SWIEPH;
1357
+ *sdate = '\0';
1358
+ } else if (strcmp(sdate, "-emos") == 0) {
1359
+ iflag &= ~SEFLG_EPHMASK;
1360
+ iflag |= SEFLG_MOSEPH;
1361
+ *sdate = '\0';
1362
+ } else if (strncmp(sdate, "-xs",3) == 0) {
1363
+ /* number of asteroid */
1364
+ strcpy(sastno, sdate + 3);
1365
+ *sdate = '\0';
1366
+ }
1367
+ sp = sdate;
1368
+ if (*sp == '.') {
1369
+ goto end_main;
1370
+ } else if (*sp == '\0' || *sp == '\n' || *sp == '\r') {
1371
+ strcpy(sdate, sdate_save);
1372
+ } else {
1373
+ strcpy(sdate_save, sdate);
1374
+ }
1375
+ if (*sdate == '\0') {
1376
+ sprintf(sdate, "j%f", tjd);
1377
+ }
1378
+ if (*sp == 'j') { /* it's a day number */
1379
+ if ((sp2 = strchr(sp, ',')) != NULL)
1380
+ *sp2 = '.';
1381
+ sscanf(sp+1,"%lf", &tjd);
1382
+ if (tjd < 2299160.5)
1383
+ gregflag = SE_JUL_CAL;
1384
+ else
1385
+ gregflag = SE_GREG_CAL;
1386
+ if (strstr(sp, "jul") != NULL) {
1387
+ gregflag = SE_JUL_CAL;
1388
+ gregflag_auto = FALSE;
1389
+ } else if (strstr(sp, "greg") != NULL) {
1390
+ gregflag = SE_GREG_CAL;
1391
+ gregflag_auto = FALSE;
1392
+ }
1393
+ swe_revjul(tjd, gregflag, &jyear, &jmon, &jday, &jut);
1394
+ year_start = jyear;
1395
+ mon_start = jmon;
1396
+ day_start = jday;
1397
+ } else if (*sp == '+') {
1398
+ n = atoi(sp);
1399
+ if (n == 0) n = 1;
1400
+ tjd += n;
1401
+ swe_revjul(tjd, gregflag, &jyear, &jmon, &jday, &jut);
1402
+ } else if (*sp == '-') {
1403
+ n = atoi(sp);
1404
+ if (n == 0) n = -1;
1405
+ tjd += n;
1406
+ swe_revjul(tjd, gregflag, &jyear, &jmon, &jday, &jut);
1407
+ } else {
1408
+ if (sscanf (sp, "%d%*c%d%*c%d", &jday,&jmon,&jyear) < 1) exit(1);
1409
+ year_start = jyear;
1410
+ mon_start = jmon;
1411
+ day_start = jday;
1412
+ if ((int32) jyear * 10000L + (int32) jmon * 100L + (int32) jday < 15821015L)
1413
+ gregflag = SE_JUL_CAL;
1414
+ else
1415
+ gregflag = SE_GREG_CAL;
1416
+ if (strstr(sp, "jul") != NULL) {
1417
+ gregflag = SE_JUL_CAL;
1418
+ gregflag_auto = FALSE;
1419
+ } else if (strstr(sp, "greg") != NULL) {
1420
+ gregflag = SE_GREG_CAL;
1421
+ gregflag_auto = FALSE;
1422
+ }
1423
+ jut = 0;
1424
+ if (universal_time_utc) {
1425
+ int ih = 0, im = 0;
1426
+ double ds = 0.0;
1427
+ if (*stimein != '\0') {
1428
+ sscanf(stimein, "%d:%d:%lf", &ih, &im, &ds);
1429
+ }
1430
+ if (swe_utc_to_jd(jyear,jmon,jday, ih, im, ds, gregflag, tret, serr) == ERR) {
1431
+ printf(" error in swe_utc_to_jd(): %s\n", serr);
1432
+ exit(-1);
1433
+ }
1434
+ tjd = tret[1];
1435
+ } else {
1436
+ tjd = swe_julday(jyear,jmon,jday,jut,gregflag);
1437
+ tjd += thour / 24.0;
1438
+ }
1439
+ }
1440
+ if (special_event > 0) {
1441
+ do_special_event(tjd, ipl, star, special_event, special_mode, geopos, datm, dobs, serr) ;
1442
+ swe_close();
1443
+ return OK;
1444
+ }
1445
+ line_count = 0;
1446
+ for (t = tjd, istep = 1; istep <= nstep; t += tstep, istep++) {
1447
+ if (step_in_minutes)
1448
+ t = tjd + (istep -1) * tstep / 1440;
1449
+ if (step_in_seconds)
1450
+ t = tjd + (istep -1) * tstep / 86400;
1451
+ if (step_in_years) {
1452
+ t = swe_julday(year_start + (istep - 1) * (int) tstep, mon_start, day_start, jut, gregflag);
1453
+ }
1454
+ if (step_in_months) {
1455
+ jmon = mon_start + (istep - 1) * (int) tstep;
1456
+ jyear = year_start + (int) ((jmon - 1) / 12);
1457
+ jmon = ((jmon - 1) % 12) + 1;
1458
+ t = swe_julday(jyear, jmon, day_start, jut, gregflag);
1459
+ }
1460
+ if (gregflag_auto) {
1461
+ if (t < 2299160.5)
1462
+ gregflag = SE_JUL_CAL;
1463
+ else
1464
+ gregflag = SE_GREG_CAL;
1465
+ }
1466
+ // must repeat because gregflag may have changed
1467
+ if (step_in_years) {
1468
+ t = swe_julday(year_start + (istep - 1) * (int) tstep, mon_start, day_start, jut, gregflag);
1469
+ }
1470
+ if (step_in_months) {
1471
+ jmon = mon_start + (istep - 1) * (int) tstep;
1472
+ jyear = year_start + (int) ((jmon - 1) / 12);
1473
+ jmon = ((jmon - 1) % 12) + 1;
1474
+ t = swe_julday(jyear, jmon, day_start, jut, gregflag);
1475
+ }
1476
+ delt = swe_deltat_ex(t, iflag, serr);
1477
+ if (!universal_time) {
1478
+ delt = swe_deltat_ex(t - delt, iflag, serr);
1479
+ }
1480
+ t2 = t;
1481
+ // output line:
1482
+ // "date (dmy) 4.6.2017 greg. 2:07:00 TT version 2.07.02"
1483
+ swe_revjul(t2, gregflag, &jyear, &jmon, &jday, &jut);
1484
+ if (with_header) {
1485
+ #ifndef NO_SWE_GLP // -DNO_SWE_GLP to suppress this function
1486
+ if (with_glp) {
1487
+ swe_get_library_path(sout);
1488
+ printf("\npath: %s", sout);
1489
+ }
1490
+ #endif
1491
+ printf("\ndate (dmy) %d.%d.%04d", jday, jmon, jyear);
1492
+ if (gregflag)
1493
+ printf(" greg.");
1494
+ else
1495
+ printf(" jul.");
1496
+ jd_to_time_string(jut, stimeout);
1497
+ printf(stimeout);
1498
+ if (universal_time) {
1499
+ if (time_flag & BIT_TIME_LMT)
1500
+ printf(" LMT");
1501
+ else
1502
+ printf(" UT");
1503
+ } else {
1504
+ printf(" TT");
1505
+ }
1506
+ printf("\t\tversion %s", swe_version(sout));
1507
+ }
1508
+ if (universal_time) {
1509
+ // "LMT: 2457908.588194444"
1510
+ if (time_flag & BIT_TIME_LMT) {
1511
+ if (with_header) {
1512
+ printf("\nLMT: %.9f", t);
1513
+ t -= geopos[0] / 15.0 / 24.0;
1514
+ }
1515
+ }
1516
+ // "UT: 2457908.565972222 delta t: 68.761612 sec"
1517
+ if (with_header) {
1518
+ printf("\nUT: %.9f", t);
1519
+ printf(" delta t: %f sec", delt * 86400.0);
1520
+ }
1521
+ te = t + delt;
1522
+ tut = t;
1523
+ } else {
1524
+ te = t;
1525
+ tut = t - delt;
1526
+ // "UT: 2457908.565972222 delta t: 68.761612 sec"
1527
+ if (with_header) {
1528
+ printf("\nUT: %.9f", tut);
1529
+ printf(" delta t: %f sec", delt * 86400.0);
1530
+ }
1531
+ }
1532
+ iflgret = swe_calc(te, SE_ECL_NUT, iflag, xobl, serr);
1533
+ if (with_header) {
1534
+ // "TT: 2457908.566768074
1535
+ printf("\nTT: %.9f", te);
1536
+ // "ayanamsa = 24° 5'51.6509 (Lahiri)"
1537
+ if (iflag & SEFLG_SIDEREAL) {
1538
+ if (swe_get_ayanamsa_ex(te, iflag, &daya, serr) == ERR) {
1539
+ printf(" error in swe_get_ayanamsa_ex(): %s\n", serr);
1540
+ exit(1);
1541
+ }
1542
+ printf(" ayanamsa = %s (%s)", dms(daya, round_flag), swe_get_ayanamsa_name(sid_mode));
1543
+ }
1544
+ // "geo. long 8.000000, lat 47.000000, alt 0.000000"
1545
+ if (have_geopos) {
1546
+ printf("\ngeo. long %f, lat %f, alt %f", geopos[0], geopos[1], geopos[2]);
1547
+ }
1548
+ if (iflag_f >=0)
1549
+ iflag = iflag_f;
1550
+ if (strchr(plsel, 'o') == NULL) {
1551
+ if (iflag & (SEFLG_NONUT | SEFLG_SIDEREAL)) {
1552
+ printf("\n%-15s %s", "Epsilon (m)", dms(xobl[0],round_flag));
1553
+ } else {
1554
+ printf("\n%-15s %s%s", "Epsilon (t/m)", dms(xobl[0],round_flag), gap);
1555
+ printf("%s", dms(xobl[1],round_flag));
1556
+ }
1557
+ }
1558
+ if (strchr(plsel, 'n') == NULL && !(iflag & (SEFLG_NONUT | SEFLG_SIDEREAL))) {
1559
+ fputs("\nNutation ", stdout);
1560
+ fputs(dms(xobl[2], round_flag), stdout);
1561
+ fputs(gap, stdout);
1562
+ fputs(dms(xobl[3], round_flag), stdout);
1563
+ }
1564
+ printf("\n");
1565
+ if (do_houses) {
1566
+ const char *shsy = swe_house_name(ihsy);
1567
+ if (!universal_time) {
1568
+ do_houses = FALSE;
1569
+ printf("option -house requires option -ut for Universal Time\n");
1570
+ } else {
1571
+ strcpy(s1, dms(top_long, round_flag));
1572
+ strcpy(s2, dms(top_lat, round_flag));
1573
+ printf("Houses system %c (%s) for long=%s, lat=%s\n", ihsy, shsy, s1, s2);
1574
+ }
1575
+ }
1576
+ }
1577
+ if (with_header && !with_header_always)
1578
+ with_header = FALSE;
1579
+ if (do_ayanamsa) {
1580
+ if (swe_get_ayanamsa_ex(te, iflag, &daya, serr) == ERR) {
1581
+ printf(" error in swe_get_ayanamsa_ex(): %s\n", serr);
1582
+ exit(1);
1583
+ }
1584
+ x[0] = daya;
1585
+ print_line(MODE_AYANAMSA, TRUE, sid_mode);
1586
+ continue;
1587
+ }
1588
+ if (t == tjd && strchr(plsel, 'e')) {
1589
+ if (list_hor) {
1590
+ is_first = TRUE;
1591
+ for (psp = plsel; *psp != '\0'; psp++) {
1592
+ if (*psp == 'e') continue;
1593
+ ipl = letter_to_ipl((int) *psp);
1594
+ *spnam = '\0';
1595
+ if (ipl >= SE_SUN && ipl <= SE_VESTA)
1596
+ swe_get_planet_name(ipl, spnam);
1597
+ print_line(MODE_LABEL, is_first, 0);
1598
+ is_first = FALSE;
1599
+ }
1600
+ printf("\n");
1601
+ } else {
1602
+ print_line(MODE_LABEL, TRUE, 0);
1603
+ }
1604
+ }
1605
+ is_first = TRUE;
1606
+ for (psp = plsel; *psp != '\0'; psp++) {
1607
+ if (*psp == 'e') continue;
1608
+ ipl = letter_to_ipl((int) *psp);
1609
+ if (ipl == -2) {
1610
+ printf("illegal parameter -p%s\n", plsel);
1611
+ exit(1);
1612
+ }
1613
+ if (*psp == 'f') // fixed star
1614
+ ipl = SE_FIXSTAR;
1615
+ else if (*psp == 's') // asteroid
1616
+ ipl = atoi(sastno) + 10000;
1617
+ else if (*psp == 'v') // planetary moon
1618
+ ipl = atoi(sastno);
1619
+ else if (*psp == 'z') // fictitious object
1620
+ ipl = atoi(shyp) + SE_FICT_OFFSET_1;
1621
+ if (iflag & SEFLG_HELCTR) {
1622
+ if (ipl == SE_SUN
1623
+ || ipl == SE_MEAN_NODE || ipl == SE_TRUE_NODE
1624
+ || ipl == SE_MEAN_APOG || ipl == SE_OSCU_APOG)
1625
+ continue;
1626
+ } else if (iflag & SEFLG_BARYCTR) {
1627
+ if (ipl == SE_MEAN_NODE || ipl == SE_TRUE_NODE
1628
+ || ipl == SE_MEAN_APOG || ipl == SE_OSCU_APOG)
1629
+ continue;
1630
+ } else { /* geocentric */
1631
+ if (ipl == SE_EARTH && !do_orbital_elements)
1632
+ continue;
1633
+ }
1634
+ /* ecliptic position */
1635
+ if (iflag_f >=0)
1636
+ iflag = iflag_f;
1637
+ if (ipl == SE_FIXSTAR) {
1638
+ iflgret = call_swe_fixstar(star, te, iflag, x, serr);
1639
+ /* magnitude, etc. */
1640
+ if (iflgret != ERR && strpbrk(fmt, "=") != NULL) {
1641
+ double mag;
1642
+ iflgret = swe_fixstar_mag(star, &mag, serr);
1643
+ attr[4] = mag;
1644
+ }
1645
+ strcpy(se_pname, star);
1646
+ } else if (do_planeto_centric) {
1647
+ iflgret = swe_calc_pctr(te, ipl, iplctr, iflag, x, serr);
1648
+ swe_get_planet_name(ipl, se_pname);
1649
+ } else {
1650
+ iflgret = swe_calc(te, ipl, iflag, x, serr);
1651
+ /* phase, magnitude, etc. */
1652
+ if (iflgret != ERR && strpbrk(fmt, "+-*/=") != NULL)
1653
+ iflgret = swe_pheno(te, ipl, iflag, attr, serr);
1654
+ swe_get_planet_name(ipl, se_pname);
1655
+ if (show_file_limit && ipl > SE_AST_OFFSET) {
1656
+ const char *fnam;
1657
+ char sbeg[40], send[40];
1658
+ double tfstart, tfend;
1659
+ int denum;
1660
+ fnam = swe_get_current_file_data(3, &tfstart, &tfend, &denum);
1661
+ if (fnam != NULL) {
1662
+ swe_revjul(tfstart, gregflag, &jyear, &jmon, &jday, &jut);
1663
+ sprintf(sbeg, "%d.%02d.%04d", jday, jmon, jyear);
1664
+ swe_revjul(tfend, gregflag, &jyear, &jmon, &jday, &jut);
1665
+ sprintf(send, "%d.%02d.%04d", jday, jmon, jyear);
1666
+ printf("range %s: %.1lf = %s to %.1lf = %s de=%d\n", fnam, tfstart, sbeg, tfend, send, denum);
1667
+ show_file_limit = FALSE;
1668
+ }
1669
+ }
1670
+ }
1671
+ if (*psp == 'q') {/* delta t */
1672
+ x[0] = swe_deltat_ex(tut, iflag, serr) * 86400;
1673
+ x[1] = x[2] = x[3] = 0;
1674
+ x[1] = x[0] / 3600.0; // to hours
1675
+ strcpy(se_pname, "Delta T");
1676
+ }
1677
+ if (*psp == 'x') {/* sidereal time */
1678
+ x[0] = swe_degnorm(swe_sidtime(tut) * 15 + geopos[0]);
1679
+ x[1] = x[2] = x[3] = 0;
1680
+ strcpy(se_pname, "Sidereal Time");
1681
+ }
1682
+ if (*psp == 'o') {/* ecliptic is wanted, remove nutation */
1683
+ x[2] = x[3] = 0;
1684
+ strcpy(se_pname, "Ecl. Obl.");
1685
+ }
1686
+ if (*psp == 'n') {/* nutation is wanted, remove ecliptic */
1687
+ x[0] = x[2];
1688
+ x[1] = x[3];
1689
+ x[2] = x[3] = 0;
1690
+ strcpy(se_pname, "Nutation");
1691
+ }
1692
+ if (*psp == 'y') {/* time equation */
1693
+ iflgret = swe_time_equ(tut, &(x[0]), serr);
1694
+ x[0] *= 86400; /* in seconds */;
1695
+ x[1] = x[2] = x[3] = 0;
1696
+ strcpy(se_pname, "Time Equ.");
1697
+ }
1698
+ if (*psp == 'b') {/* ayanamsha */
1699
+ if (swe_get_ayanamsa_ex(te, iflag, &(x[0]), serr) == ERR) {
1700
+ printf(" error in swe_get_ayanamsa_ex(): %s\n", serr);
1701
+ iflgret = -1;
1702
+ }
1703
+ x[1] = 0;
1704
+ strcpy(se_pname, "Ayanamsha");
1705
+ }
1706
+ if (iflgret < 0) {
1707
+ if (strcmp(serr, serr_save) != 0
1708
+ && (ipl == SE_SUN || ipl == SE_MOON || ipl <= SE_PLUTO
1709
+ || ipl == SE_MEAN_NODE || ipl == SE_TRUE_NODE
1710
+ || ipl == SE_CERES || ipl == SE_PALLAS || ipl == SE_JUNO || ipl == SE_VESTA
1711
+ || ipl == SE_CHIRON || ipl == SE_PHOLUS || ipl == SE_CUPIDO
1712
+ || ipl >= SE_PLMOON_OFFSET
1713
+ || ipl >= SE_AST_OFFSET || ipl == SE_FIXSTAR
1714
+ || *psp == 'y')) {
1715
+ fputs("error: ", stdout);
1716
+ fputs(serr, stdout);
1717
+ fputs("\n", stdout);
1718
+ }
1719
+ strcpy(serr_save, serr);
1720
+ } else if (*serr != '\0' && *serr_warn == '\0') {
1721
+ if (strstr(serr, "'seorbel.txt' not found") == NULL)
1722
+ strcpy(serr_warn, serr);
1723
+ }
1724
+ if (diff_mode) {
1725
+ iflgret = swe_calc(te, ipldiff, iflag, x2, serr);
1726
+ if (diff_mode == DIFF_GEOHEL)
1727
+ iflgret = swe_calc(te, ipldiff, iflag|SEFLG_HELCTR, x2, serr);
1728
+ if (iflgret < 0) {
1729
+ fputs("error: ", stdout);
1730
+ fputs(serr, stdout);
1731
+ fputs("\n", stdout);
1732
+ }
1733
+ if (diff_mode == DIFF_DIFF || diff_mode == DIFF_GEOHEL) {
1734
+ for (i = 1; i < 6; i++)
1735
+ x[i] -= x2[i];
1736
+ if ((iflag & SEFLG_RADIANS) == 0)
1737
+ x[0] = swe_difdeg2n(x[0], x2[0]);
1738
+ else
1739
+ x[0] = swe_difrad2n(x[0], x2[0]);
1740
+ } else { /* DIFF_MIDP */
1741
+ for (i = 1; i < 6; i++)
1742
+ x[i] = (x[i] + x2[i]) / 2;
1743
+ if ((iflag & SEFLG_RADIANS) == 0)
1744
+ x[0] = swe_deg_midp(x[0], x2[0]);
1745
+ else
1746
+ x[0] = swe_rad_midp(x[0], x2[0]);
1747
+ }
1748
+ }
1749
+ /* equator position */
1750
+ if (strpbrk(fmt, "aADdQmz") != NULL) {
1751
+ iflag2 = iflag | SEFLG_EQUATORIAL;
1752
+ if (ipl == SE_FIXSTAR) {
1753
+ iflgret = call_swe_fixstar(star, te, iflag2, xequ, serr);
1754
+ } else if (do_planeto_centric) {
1755
+ iflgret = swe_calc_pctr(te, ipl, iplctr, iflag2, xequ, serr);
1756
+ } else {
1757
+ iflgret = swe_calc(te, ipl, iflag2, xequ, serr);
1758
+ }
1759
+ if (diff_mode) {
1760
+ iflgret = swe_calc(te, ipldiff, iflag2, x2, serr);
1761
+ if (diff_mode == DIFF_DIFF || diff_mode == DIFF_GEOHEL) {
1762
+ if (diff_mode == DIFF_GEOHEL)
1763
+ iflgret = swe_calc(te, ipldiff, iflag2|SEFLG_HELCTR, x2, serr);
1764
+ for (i = 1; i < 6; i++)
1765
+ xequ[i] -= x2[i];
1766
+ if ((iflag & SEFLG_RADIANS) == 0)
1767
+ xequ[0] = swe_difdeg2n(xequ[0], x2[0]);
1768
+ else
1769
+ xequ[0] = swe_difrad2n(xequ[0], x2[0]);
1770
+ } else { /* DIFF_MIDP */
1771
+ for (i = 1; i < 6; i++)
1772
+ xequ[i] = (xequ[i] + x2[i]) / 2;
1773
+ if ((iflag & SEFLG_RADIANS) == 0)
1774
+ xequ[0] = swe_deg_midp(xequ[0], x2[0]);
1775
+ else
1776
+ xequ[0] = swe_rad_midp(xequ[0], x2[0]);
1777
+ }
1778
+ }
1779
+ }
1780
+ /* azimuth and height */
1781
+ if (strpbrk(fmt, "IiHhKk") != NULL) {
1782
+ /* first, get topocentric equatorial positions */
1783
+ iflgt = whicheph | SEFLG_EQUATORIAL | SEFLG_TOPOCTR;
1784
+ if (ipl == SE_FIXSTAR)
1785
+ iflgret = call_swe_fixstar(star, te, iflgt, xt, serr);
1786
+ else
1787
+ iflgret = swe_calc(te, ipl, iflgt, xt, serr);
1788
+ /* to azimuth/height */
1789
+ /* atmospheric pressure "0" has the effect that a value
1790
+ * of 1013.25 mbar is assumed at 0 m above sea level.
1791
+ * If the altitude of the observer is given (in geopos[2])
1792
+ * pressure is estimated according to that */
1793
+ swe_azalt(tut, SE_EQU2HOR, geopos, datm[0], datm[1], xt, xaz);
1794
+ if (diff_mode) {
1795
+ iflgret = swe_calc(te, ipldiff, iflgt, xt, serr);
1796
+ swe_azalt(tut, SE_EQU2HOR, geopos, datm[0], datm[1], xt, x2);
1797
+ if (diff_mode == DIFF_DIFF || diff_mode == DIFF_GEOHEL) {
1798
+ if (diff_mode == DIFF_GEOHEL) { // makes little sense for a heliocentric
1799
+ iflgret = swe_calc(te, ipldiff, iflgt|SEFLG_HELCTR, xt, serr);
1800
+ swe_azalt(tut, SE_EQU2HOR, geopos, datm[0], datm[1], xt, x2);
1801
+ }
1802
+ for (i = 1; i < 3; i++)
1803
+ xaz[i] -= x2[i];
1804
+ if ((iflag & SEFLG_RADIANS) == 0)
1805
+ xaz[0] = swe_difdeg2n(xaz[0], x2[0]);
1806
+ else
1807
+ xaz[0] = swe_difrad2n(xaz[0], x2[0]);
1808
+ } else { /* DIFF_MIDP */
1809
+ for (i = 1; i < 3; i++)
1810
+ xaz[i] = (xaz[i] + x2[i]) / 2;
1811
+ if ((iflag & SEFLG_RADIANS) == 0)
1812
+ xaz[0] = swe_deg_midp(xaz[0], x2[0]);
1813
+ else
1814
+ xaz[0] = swe_rad_midp(xaz[0], x2[0]);
1815
+ }
1816
+ }
1817
+ }
1818
+ /* ecliptic cartesian position */
1819
+ if (strpbrk(fmt, "XU") != NULL) {
1820
+ iflag2 = iflag | SEFLG_XYZ;
1821
+ if (ipl == SE_FIXSTAR)
1822
+ iflgret = call_swe_fixstar(star, te, iflag2, xcart, serr);
1823
+ else
1824
+ iflgret = swe_calc(te, ipl, iflag2, xcart, serr);
1825
+ if (diff_mode) {
1826
+ iflgret = swe_calc(te, ipldiff, iflag2, x2, serr);
1827
+ if (diff_mode == DIFF_DIFF || diff_mode == DIFF_GEOHEL) {
1828
+ if (diff_mode == DIFF_GEOHEL)
1829
+ iflgret = swe_calc(te, ipldiff, iflag2|SEFLG_HELCTR, x2, serr);
1830
+ for (i = 0; i < 6; i++)
1831
+ xcart[i] -= x2[i];
1832
+ } else {
1833
+ xcart[i] = (xcart[i] + x2[i]) / 2;
1834
+ }
1835
+ }
1836
+ }
1837
+ /* equator cartesian position */
1838
+ if (strpbrk(fmt, "xu") != NULL) {
1839
+ iflag2 = iflag | SEFLG_XYZ | SEFLG_EQUATORIAL;
1840
+ if (ipl == SE_FIXSTAR)
1841
+ iflgret = call_swe_fixstar(star, te, iflag2, xcartq, serr);
1842
+ else
1843
+ iflgret = swe_calc(te, ipl, iflag2, xcartq, serr);
1844
+ if (diff_mode) {
1845
+ iflgret = swe_calc(te, ipldiff, iflag2, x2, serr);
1846
+ if (diff_mode == DIFF_DIFF || diff_mode == DIFF_GEOHEL) {
1847
+ if (diff_mode == DIFF_GEOHEL)
1848
+ iflgret = swe_calc(te, ipldiff, iflag2|SEFLG_HELCTR, x2, serr);
1849
+ for (i = 0; i < 6; i++)
1850
+ xcartq[i] -= x2[i];
1851
+ } else {
1852
+ xcartq[i] = (xcart[i] + x2[i]) / 2;
1853
+ }
1854
+ }
1855
+ }
1856
+ /* house position */
1857
+ if (strpbrk(fmt, "gGjzm") != NULL) {
1858
+ armc = swe_degnorm(swe_sidtime(tut) * 15 + geopos[0]);
1859
+ for (i = 0; i < 6; i++) {
1860
+ xsv[i] = x[i];
1861
+ }
1862
+ if (hpos_meth == 1) {
1863
+ xsv[1] = 0;
1864
+ }
1865
+ if (ipl == SE_FIXSTAR) {
1866
+ strcpy(star2, star);
1867
+ } else {
1868
+ *star2 = '\0';
1869
+ }
1870
+ if (hpos_meth >= 2 && toupper(ihsy) == 'G') {
1871
+ swe_gauquelin_sector(tut, ipl, star2, iflag, hpos_meth, geopos, 0, 0, &hposj, serr);
1872
+ } else {
1873
+ double cusp[100];
1874
+ if (ihsy == 'i' || ihsy == 'I') {
1875
+ iflgret = swe_houses_ex(t,iflag, top_lat, top_long, ihsy, cusp, cusp+13);
1876
+ }
1877
+ hposj = swe_house_pos(armc, geopos[1], xobl[0], ihsy, xsv, serr);
1878
+ }
1879
+ if (toupper(ihsy) == 'G')
1880
+ hpos = (hposj - 1) * 10;
1881
+ else
1882
+ hpos = (hposj - 1) * 30;
1883
+ if (diff_mode) {
1884
+ for (i = 0; i < 6; i++)
1885
+ xsv[i] = x2[i];
1886
+ if (hpos_meth == 1)
1887
+ xsv[1] = 0;
1888
+ hpos2 = swe_house_pos(armc, geopos[1], xobl[0], ihsy, xsv, serr);
1889
+ if (toupper(ihsy) == 'G')
1890
+ hpos2 = (hpos2 - 1) * 10;
1891
+ else
1892
+ hpos2 = (hpos2 - 1) * 30;
1893
+ if (diff_mode == DIFF_DIFF || diff_mode == DIFF_GEOHEL) {
1894
+ if ((iflag & SEFLG_RADIANS) == 0)
1895
+ hpos = swe_difdeg2n(hpos, hpos2);
1896
+ else
1897
+ hpos = swe_difrad2n(hpos, hpos2);
1898
+ } else { /* DIFF_MIDP */
1899
+ if ((iflag & SEFLG_RADIANS) == 0)
1900
+ hpos = swe_deg_midp(hpos, hpos2);
1901
+ else
1902
+ hpos = swe_rad_midp(hpos, hpos2);
1903
+ }
1904
+ }
1905
+ }
1906
+ strcpy(spnam, se_pname);
1907
+ print_line(0, is_first, 0);
1908
+ is_first = FALSE;
1909
+ if (! list_hor) line_count++;
1910
+ if (do_orbital_elements) {
1911
+ orbital_elements(te, ipl, iflag, serr);
1912
+ continue;
1913
+ }
1914
+ if (line_count >= line_limit) {
1915
+ printf("****** line count %d was exceeded\n", line_limit);
1916
+ break;
1917
+ }
1918
+ } /* for psp */
1919
+ if (list_hor) {
1920
+ printf("\n");
1921
+ line_count++;
1922
+ }
1923
+ if (do_houses) {
1924
+ double cusp[37];
1925
+ double cusp_speed[37];
1926
+ double ascmc[10];
1927
+ double ascmc_speed[10];
1928
+ int iofs;
1929
+ if (toupper(ihsy) == 'G') // Gauquelin has 36 cusps
1930
+ nhouses = 36;
1931
+ iofs = nhouses + 1;
1932
+ iflgret = swe_houses_ex2(t,iflag, top_lat, top_long, ihsy, cusp, ascmc, cusp_speed, ascmc_speed, serr);
1933
+ // when swe_houses_ex() fails (e.g. with Placidus, Gauquelin, Makranski),
1934
+ // it always returns Porphyry cusps instead
1935
+ if (iflgret < 0) {
1936
+ const char *shsy = swe_house_name(ihsy);
1937
+ sprintf(serr, "House method %s failed, Porphyry calculated instead", shsy);
1938
+ if (strcmp(serr, serr_save) != 0 ) {
1939
+ fputs("error: ", stdout);
1940
+ fputs(serr, stdout);
1941
+ fputs("\n", stdout);
1942
+ }
1943
+ strcpy(serr_save, serr);
1944
+ ihsy = 'O';
1945
+ nhouses = 12; // instead of 36 with 'G'
1946
+ iofs = nhouses + 1;
1947
+ }
1948
+ is_first = TRUE;
1949
+ for (ipl = 1; ipl < iofs+8; ipl++) {
1950
+ x[0] = cusp[ipl];
1951
+ if (ipl >= iofs) {
1952
+ x[0] = ascmc[ipl - iofs];
1953
+ x[3] = ascmc_speed[ipl - iofs];
1954
+ } else {
1955
+ x[3] = cusp_speed[ipl];
1956
+ }
1957
+ x[1] = 0; /* latitude */
1958
+ x[2] = 1.0; /* pseudo radius vector */
1959
+ if (ipl == iofs+2) { /* armc is already equatorial! */
1960
+ xequ[0] = x[0];
1961
+ xequ[1] = x[1];
1962
+ xequ[2] = x[2];
1963
+ } else if (strpbrk(fmt, "aADdQ") != NULL) {
1964
+ swe_cotrans(x, xequ, -xobl[0]);
1965
+ }
1966
+ if (strpbrk(fmt, "IiHhKk") != NULL) {
1967
+ double gpos[3];
1968
+ gpos[0] = top_long;
1969
+ gpos[1] = top_lat;
1970
+ gpos[2] = 0;
1971
+ swe_azalt(t, SE_ECL2HOR, gpos, datm[0], datm[1], x, xaz);
1972
+ }
1973
+ if (strpbrk(fmt, "gGj") != NULL) {
1974
+ hposj = swe_house_pos(armc, geopos[1], xobl[0], ihsy, x, serr);
1975
+ if (toupper(ihsy) == 'G')
1976
+ hpos = (hposj - 1) * 10;
1977
+ else
1978
+ hpos = (hposj - 1) * 30;
1979
+ }
1980
+ print_line(MODE_HOUSE, is_first, 0);
1981
+ is_first = FALSE;
1982
+ if (! list_hor) line_count++;
1983
+ }
1984
+ if (list_hor) {
1985
+ printf("\n");
1986
+ line_count++;
1987
+ }
1988
+ }
1989
+ if (line_count >= line_limit) {
1990
+ printf("****** line count %d was exceeded\n", line_limit);
1991
+ break;
1992
+ }
1993
+ } /* for tjd */
1994
+ if (*serr_warn != '\0') {
1995
+ printf("\nwarning: ");
1996
+ fputs(serr_warn,stdout);
1997
+ printf("\n");
1998
+ }
1999
+ } /* while 1 */
2000
+ /* close open files and free allocated space */
2001
+ end_main:
2002
+ if (do_set_astro_models) {
2003
+ printf(smod);
2004
+ }
2005
+ swe_close();
2006
+ return OK;
2007
+ }
2008
+
2009
+ static int32 call_swe_fixstar(char *star, double te, int32 iflag, double *x, char *serr)
2010
+ {
2011
+ if (use_swe_fixstar2)
2012
+ return swe_fixstar2(star, te, iflag, x, serr);
2013
+ else
2014
+ return swe_fixstar(star, te, iflag, x, serr);
2015
+ }
2016
+
2017
+ /* This function calculates the geocentric relative distance of a planet,
2018
+ * where the closest position has value 1000, and remotest position has
2019
+ * value 0.
2020
+ * The value is returned as an integer. The algorithm does not allow
2021
+ * much higher accuracy.
2022
+ *
2023
+ * With the Moon we measure the distance relative to the maximum and minimum
2024
+ * found between 12000 BCE and 16000 CE.
2025
+ * If the distance value were given relative to the momentary osculating
2026
+ * ellipse, then the apogee would always have the value 1000 and the perigee
2027
+ * the value 0. It is certainly more interesting to know how much it is
2028
+ * relative to a greater time range.
2029
+ */
2030
+ static int32 get_geocentric_relative_distance(double tjd_et, int32 ipl, int32 iflag, char *serr)
2031
+ {
2032
+ int32 iflagi = (iflag & (SEFLG_EPHMASK | SEFLG_HELCTR | SEFLG_BARYCTR));
2033
+ int32 retval;
2034
+ double ar = 0;
2035
+ double xx[6];
2036
+ double dmax, dmin, dtrue;
2037
+ if ((0) && ipl == SE_MOON) {
2038
+ dmax = 0.002718774; // jd = 283030.8
2039
+ dmin = 0.002381834; // jd = -1006731.3
2040
+ if ((retval = swe_calc(tjd_et, SE_MOON, iflagi | SEFLG_J2000 | SEFLG_TRUEPOS, xx, serr)) == ERR)
2041
+ return 0;
2042
+ dtrue = xx[2];
2043
+ } else {
2044
+ if (swe_orbit_max_min_true_distance(tjd_et, ipl, iflagi, &dmax, &dmin, &dtrue, serr) == ERR)
2045
+ return 0;
2046
+ }
2047
+ if (dmax - dmin == 0) {
2048
+ ar = 0;
2049
+ } else {
2050
+ ar = (1 - (dtrue - dmin) / (dmax - dmin)) * 1000.0;
2051
+ ar += 0.5; // rounding
2052
+ }
2053
+ return (int32) ar;
2054
+ }
2055
+
2056
+ /*
2057
+ * The string fmt contains a sequence of format specifiers;
2058
+ * each character in fmt creates a column, the columns are
2059
+ * sparated by the gap string.
2060
+ * Time columns tTJyY are only printed, if is_first is TRUE,
2061
+ * so that they are not repeated in list_hor (horizontal list) mode.
2062
+ * In list_hor mode, no newline is printed.
2063
+ */
2064
+ static int print_line(int mode, AS_BOOL is_first, int sid_mode)
2065
+ {
2066
+ char *sp, *sp2;
2067
+ double t2, ju2 = 0;
2068
+ double y_frac;
2069
+ double ar, sinp;
2070
+ double dret[20];
2071
+ char slon[40];
2072
+ char pnam[30];
2073
+ AS_BOOL is_house = ((mode & MODE_HOUSE) != 0);
2074
+ AS_BOOL is_label = ((mode & MODE_LABEL) != 0);
2075
+ AS_BOOL is_ayana = ((mode & MODE_AYANAMSA) != 0);
2076
+ int32 iflgret, dar;
2077
+ // build planet name column, just in case
2078
+ if (is_house) {
2079
+ if (ipl <= nhouses) {
2080
+ sprintf(pnam, "house %2d ", ipl);
2081
+ } else {
2082
+ sprintf(pnam, "%-15s", hs_nam[ipl - nhouses]);
2083
+ }
2084
+ } else if (diff_mode == DIFF_DIFF) {
2085
+ sprintf(pnam, "%.3s-%.3s", spnam, spnam2);
2086
+ } else if (diff_mode == DIFF_GEOHEL) {
2087
+ sprintf(pnam, "%.3s-%.3sHel", spnam, spnam2);
2088
+ } else if (diff_mode == DIFF_MIDP) {
2089
+ sprintf(pnam, "%.3s/%.3s", spnam, spnam2);
2090
+ } else {
2091
+ sprintf(pnam, "%-15.15s", spnam);
2092
+ }
2093
+ if (list_hor && strchr(fmt, 'P') == NULL) {
2094
+ sprintf(slon, "%.8s %s", pnam, "long.");
2095
+ } else {
2096
+ sprintf(slon, "%-14s", "long.");
2097
+ }
2098
+ for (sp = fmt; *sp != '\0'; sp++) {
2099
+ // if (is_house && ipl <= nhouses && strchr("bBsSrRxXuUQnNfFj+-*/=", *sp) != NULL) continue;
2100
+ if (is_house && strchr("bBrRxXuUQnNfFj+-*/=", *sp) != NULL) continue;
2101
+ if (is_ayana && strchr("bBsSrRxXuUQnNfFj+-*/=", *sp) != NULL) continue;
2102
+ if (sp != fmt)
2103
+ fputs(gap,stdout);
2104
+ if (sp == fmt && list_hor && !is_first && strchr("yYJtT", *sp) == NULL)
2105
+ fputs(gap,stdout);
2106
+ switch(*sp) {
2107
+ case 'y':
2108
+ if (list_hor && ! is_first) {
2109
+ break;
2110
+ }
2111
+ if (is_label) { printf("year"); break; }
2112
+ printf("%d", jyear);
2113
+ break;
2114
+ case 'Y':
2115
+ if (list_hor && ! is_first) {
2116
+ break;
2117
+ }
2118
+ if (is_label) { printf("year"); break; }
2119
+ t2 = swe_julday(jyear,1,1,ju2,gregflag);
2120
+ y_frac = (t - t2) / 365.0;
2121
+ printf("%.2f", jyear + y_frac);
2122
+ break;
2123
+ case 'p':
2124
+ if (is_label) { printf("obj.nr"); break; }
2125
+ if (! is_house && diff_mode == DIFF_DIFF) {
2126
+ printf("%d-%d", ipl, ipldiff);
2127
+ } else if (! is_house && diff_mode == DIFF_GEOHEL) {
2128
+ printf("%d-%dhel", ipl, ipldiff);
2129
+ } else if (! is_house && diff_mode == DIFF_MIDP) {
2130
+ printf("%d/%d", ipl, ipldiff);
2131
+ } else {
2132
+ printf("%d", ipl);
2133
+ }
2134
+ break;
2135
+ case 'P':
2136
+ if (is_label) { printf("%-15s", "name"); break; }
2137
+ if (is_house) {
2138
+ if (ipl <= nhouses) {
2139
+ printf("house %2d ", ipl);
2140
+ } else {
2141
+ printf("%-15s", hs_nam[ipl - nhouses]);
2142
+ }
2143
+ } else if (is_ayana) {
2144
+ // printf("Ayanamsha ");
2145
+ printf("Ayanamsha %s ", swe_get_ayanamsa_name(sid_mode));
2146
+ } else if (diff_mode == DIFF_DIFF || diff_mode == DIFF_GEOHEL) {
2147
+ printf("%.3s-%.3s", spnam, spnam2);
2148
+ } else if (diff_mode == DIFF_MIDP) {
2149
+ printf("%.3s/%.3s", spnam, spnam2);
2150
+ } else {
2151
+ printf("%-15s", spnam);
2152
+ }
2153
+ break;
2154
+ case 'J':
2155
+ if (list_hor && ! is_first) {
2156
+ break;
2157
+ }
2158
+ if (is_label) { printf("julday"); break; }
2159
+ y_frac = (t - floor(t)) * 100;
2160
+ if (floor(y_frac) != y_frac) {
2161
+ printf("%.5f", t);
2162
+ } else {
2163
+ printf("%.2f", t);
2164
+ }
2165
+ break;
2166
+ case 'T':
2167
+ if (list_hor && ! is_first) {
2168
+ break;
2169
+ }
2170
+ if (is_label) { printf("date "); break; }
2171
+ printf("%02d.%02d.%04d", jday, jmon, jyear);
2172
+ if (gregflag == SE_JUL_CAL) printf("j");
2173
+ if (jut != 0 || step_in_minutes || step_in_seconds ) {
2174
+ int h, m, s;
2175
+ s = (int) (jut * 3600 + 0.5);
2176
+ h = (int) (s / 3600.0);
2177
+ m = (int) ((s % 3600) / 60.0);
2178
+ s %= 60;
2179
+ printf(" %d:%02d:%02d", h, m, s);
2180
+ if (universal_time)
2181
+ printf(" UT");
2182
+ else
2183
+ printf(" TT");
2184
+ }
2185
+ break;
2186
+ case 't':
2187
+ if (list_hor && ! is_first) {
2188
+ break;
2189
+ }
2190
+ if (is_label) { printf("date"); break; }
2191
+ printf("%02d%02d%02d", jyear % 100, jmon, jday);
2192
+ break;
2193
+ case 'L':
2194
+ if (is_label) { printf(slon); break; }
2195
+ if (psp != NULL && (*psp == 'q' || *psp == 'y')) { /* delta t or time equation */
2196
+ printf("%# 11.7f", x[0]);
2197
+ printf("s");
2198
+ break;
2199
+ }
2200
+ fputs(dms(x[0], round_flag),stdout);
2201
+ break;
2202
+ case 'l':
2203
+ if (is_label) { printf(slon); break; }
2204
+ if (output_extra_prec)
2205
+ printf("%# 11.11f", x[0]);
2206
+ else
2207
+ printf("%# 11.7f", x[0]);
2208
+ break;
2209
+ case 'G':
2210
+ if (is_label) { printf("housPos"); break; }
2211
+ fputs(dms(hpos, round_flag),stdout);
2212
+ break;
2213
+ case 'g':
2214
+ if (is_label) { printf("housPos"); break; }
2215
+ printf("%# 11.7f", hpos);
2216
+ break;
2217
+ case 'j':
2218
+ if (is_label) { printf("houseNr"); break; }
2219
+ printf("%# 11.7f", hposj);
2220
+ break;
2221
+ case 'Z':
2222
+ if (is_label) { printf(slon); break; }
2223
+ fputs(dms(x[0], round_flag|BIT_ZODIAC),stdout);
2224
+ break;
2225
+ case 'S':
2226
+ case 's':
2227
+ if (*(sp+1) == 'S' || *(sp+1) == 's' || strpbrk(fmt, "XUxu") != NULL) {
2228
+ for (sp2 = fmt; *sp2 != '\0'; sp2++) {
2229
+ if (sp2 != fmt)
2230
+ fputs(gap,stdout);
2231
+ switch(*sp2) {
2232
+ case 'L': /* speed! */
2233
+ case 'Z': /* speed! */
2234
+ if (is_label) { printf("lon/day"); break; }
2235
+ fputs(dms(x[3], round_flag),stdout);
2236
+ break;
2237
+ case 'l': /* speed! */
2238
+ if (is_label) { printf("lon/day"); break; }
2239
+ if (output_extra_prec)
2240
+ printf("%# 11.9f", x[3]);
2241
+ else
2242
+ printf("%# 11.7f", x[3]);
2243
+ break;
2244
+ case 'B': /* speed! */
2245
+ if (is_label) { printf("lat/day"); break; }
2246
+ fputs(dms(x[4], round_flag),stdout);
2247
+ break;
2248
+ case 'b': /* speed! */
2249
+ if (is_label) { printf("lat/day"); break; }
2250
+ if (output_extra_prec)
2251
+ printf("%# 11.9f", x[4]);
2252
+ else
2253
+ printf("%# 11.7f", x[4]);
2254
+ break;
2255
+ case 'A': /* speed! */
2256
+ if (is_label) { printf("RA/day"); break; }
2257
+ fputs(dms(xequ[3]/15, round_flag|SEFLG_EQUATORIAL),stdout);
2258
+ break;
2259
+ case 'a': /* speed! */
2260
+ if (is_label) { printf("RA/day"); break; }
2261
+ if (output_extra_prec)
2262
+ printf("%# 11.9f", xequ[3]);
2263
+ else
2264
+ printf("%# 11.7f", xequ[3]);
2265
+ break;
2266
+ case 'D': /* speed! */
2267
+ if (is_label) { printf("dcl/day"); break; }
2268
+ fputs(dms(xequ[4], round_flag),stdout);
2269
+ break;
2270
+ case 'd': /* speed! */
2271
+ if (is_label) { printf("dcl/day"); break; }
2272
+ if (output_extra_prec)
2273
+ printf("%# 11.9f", xequ[4]);
2274
+ else
2275
+ printf("%# 11.7f", xequ[4]);
2276
+ break;
2277
+ case 'R': /* speed! */
2278
+ case 'r': /* speed! */
2279
+ if (is_label) { printf("AU/day"); break; }
2280
+ if (output_extra_prec)
2281
+ printf("%# 16.14f", x[5]);
2282
+ else
2283
+ printf("%# 14.9f", x[5]);
2284
+ break;
2285
+ case 'U': /* speed! */
2286
+ case 'X': /* speed! */
2287
+ if (is_label) {
2288
+ fputs("speed_0", stdout);
2289
+ fputs(gap, stdout);
2290
+ fputs("speed_1", stdout);
2291
+ fputs(gap, stdout);
2292
+ fputs("speed_2", stdout);
2293
+ break;
2294
+ }
2295
+ if (*sp =='U')
2296
+ ar = sqrt(square_sum(xcart));
2297
+ else
2298
+ ar = 1;
2299
+ printf("%# 14.9f", xcart[3]/ar);
2300
+ fputs(gap,stdout);
2301
+ printf("%# 14.9f", xcart[4]/ar);
2302
+ fputs(gap,stdout);
2303
+ printf("%# 14.9f", xcart[5]/ar);
2304
+ break;
2305
+ case 'u': /* speed! */
2306
+ case 'x': /* speed! */
2307
+ if (is_label) {
2308
+ fputs("speed_0", stdout);
2309
+ fputs(gap, stdout);
2310
+ fputs("speed_1", stdout);
2311
+ fputs(gap, stdout);
2312
+ fputs("speed_2", stdout);
2313
+ break;
2314
+ }
2315
+ if (*sp =='u')
2316
+ ar = sqrt(square_sum(xcartq));
2317
+ else
2318
+ ar = 1;
2319
+ printf("%# 14.9f", xcartq[3]/ar);
2320
+ fputs(gap,stdout);
2321
+ printf("%# 14.9f", xcartq[4]/ar);
2322
+ fputs(gap,stdout);
2323
+ printf("%# 14.9f", xcartq[5]/ar);
2324
+ break;
2325
+ default:
2326
+ break;
2327
+ }
2328
+ }
2329
+ if (*(sp+1) == 'S' || *(sp+1) == 's')
2330
+ sp++;
2331
+ } else if (*sp == 'S') {
2332
+ int flag = round_flag;
2333
+ if (is_house) flag |= BIT_ALLOW_361; // speed of houses can be > 360
2334
+ if (is_label) { printf("deg/day"); break; }
2335
+ fputs(dms(x[3], flag),stdout);
2336
+ } else {
2337
+ if (is_label) { printf("deg/day"); break; }
2338
+ if (output_extra_prec)
2339
+ printf("%# 11.17f", x[3]);
2340
+ else
2341
+ printf("%# 11.7f", x[3]);
2342
+ }
2343
+ break;
2344
+ case 'B':
2345
+ if (is_label) { printf("lat. "); break; }
2346
+ if (*psp == 'q') { /* delta t */
2347
+ printf("%# 11.7f", x[1]);
2348
+ printf("h");
2349
+ break;
2350
+ }
2351
+ fputs(dms(x[1], round_flag),stdout);
2352
+ break;
2353
+ case 'b':
2354
+ if (is_label) { printf("lat. "); break; }
2355
+ if (output_extra_prec)
2356
+ printf("%# 11.11f", x[1]);
2357
+ else
2358
+ printf("%# 11.7f", x[1]);
2359
+ break;
2360
+ case 'A': /* right ascension */
2361
+ if (is_label) { printf("RA "); break; }
2362
+ fputs(dms(xequ[0]/15, round_flag|SEFLG_EQUATORIAL),stdout);
2363
+ break;
2364
+ case 'a': /* right ascension */
2365
+ if (is_label) { printf("RA "); break; }
2366
+ if (output_extra_prec)
2367
+ printf("%# 11.11f", xequ[0]);
2368
+ else
2369
+ printf("%# 11.7f", xequ[0]);
2370
+ break;
2371
+ case 'D': /* declination */
2372
+ if (is_label) { printf("decl "); break; }
2373
+ fputs(dms(xequ[1], round_flag),stdout);
2374
+ break;
2375
+ case 'd': /* declination */
2376
+ if (is_label) { printf("decl "); break; }
2377
+ if (output_extra_prec)
2378
+ printf("%# 11.11f", xequ[1]);
2379
+ else
2380
+ printf("%# 11.7f", xequ[1]);
2381
+ break;
2382
+ case 'I': /* azimuth */
2383
+ if (is_label) { printf("azimuth"); break; }
2384
+ fputs(dms(xaz[0], round_flag),stdout);
2385
+ break;
2386
+ case 'i': /* azimuth */
2387
+ if (is_label) { printf("azimuth"); break; }
2388
+ printf("%# 11.7f", xaz[0]);
2389
+ break;
2390
+ case 'H': /* height */
2391
+ if (is_label) { printf("height"); break; }
2392
+ fputs(dms(xaz[1], round_flag),stdout);
2393
+ break;
2394
+ case 'h': /* height */
2395
+ if (is_label) { printf("height"); break; }
2396
+ printf("%# 11.7f", xaz[1]);
2397
+ break;
2398
+ case 'K': /* height (apparent) */
2399
+ if (is_label) { printf("hgtApp"); break; }
2400
+ fputs(dms(xaz[2], round_flag),stdout);
2401
+ break;
2402
+ case 'k': /* height (apparent) */
2403
+ if (is_label) { printf("hgtApp"); break; }
2404
+ printf("%# 11.7f", xaz[2]);
2405
+ break;
2406
+ case 'R':
2407
+ if (is_label) { printf("distAU "); break; }
2408
+ if (output_extra_prec)
2409
+ printf("%# 16.14f", x[2]);
2410
+ else
2411
+ printf("%# 14.9f", x[2]);
2412
+ break;
2413
+ case 'W':
2414
+ if (is_label) { printf("distLY "); break; }
2415
+ printf("%# 14.9f", x[2] * SE_AUNIT_TO_LIGHTYEAR);
2416
+ break;
2417
+ case 'w':
2418
+ if (is_label) { printf("distkm "); break; }
2419
+ printf("%# 14.9f", x[2] * SE_AUNIT_TO_KM);
2420
+ break;
2421
+ case 'r':
2422
+ if (is_label) { printf("dist"); break; }
2423
+ if ( ipl == SE_MOON ) { /* for moon print parallax */
2424
+ /* geocentric horizontal parallax: */
2425
+ if ((0)) {
2426
+ sinp = 8.794 / x[2]; /* in seconds of arc */
2427
+ ar = sinp * (1 + sinp * sinp * 3.917402e-12);
2428
+ /* the factor is 1 / (3600^2 * (180/pi)^2 * 6) */
2429
+ printf("%# 13.5f\" %# 13.5f'", ar, ar/60.0);
2430
+ }
2431
+ swe_pheno(te, ipl, iflag, dret, serr);
2432
+ printf("%# 13.5f\"", dret[5] * 3600);
2433
+ } else {
2434
+ printf("%# 14.9f", x[2]);
2435
+ }
2436
+ break;
2437
+ case 'q':
2438
+ if (is_label) { printf("reldist"); break; }
2439
+ dar = get_geocentric_relative_distance(te, ipl, iflag, serr);
2440
+ printf("% 5d", dar);
2441
+ break;
2442
+ case 'U':
2443
+ case 'X':
2444
+ if (*sp =='U')
2445
+ ar = sqrt(square_sum(xcart));
2446
+ else
2447
+ ar = 1;
2448
+ printf("%# 14.9f", xcart[0]/ar);
2449
+ fputs(gap,stdout);
2450
+ printf("%# 14.9f", xcart[1]/ar);
2451
+ fputs(gap,stdout);
2452
+ printf("%# 14.9f", xcart[2]/ar);
2453
+ break;
2454
+ case 'u':
2455
+ case 'x':
2456
+ if (is_label) {
2457
+ fputs("x0", stdout);
2458
+ fputs(gap, stdout);
2459
+ fputs("x1", stdout);
2460
+ fputs(gap, stdout);
2461
+ fputs("x2", stdout);
2462
+ break;
2463
+ }
2464
+ if (*sp =='u')
2465
+ ar = sqrt(square_sum(xcartq));
2466
+ else
2467
+ ar = 1;
2468
+ if (output_extra_prec) {
2469
+ printf("%# .17f", xcartq[0]/ar);
2470
+ fputs(gap,stdout);
2471
+ printf("%# .17f", xcartq[1]/ar);
2472
+ fputs(gap,stdout);
2473
+ printf("%# .17f", xcartq[2]/ar);
2474
+ } else {
2475
+ printf("%# 14.9f", xcartq[0]/ar);
2476
+ fputs(gap,stdout);
2477
+ printf("%# 14.9f", xcartq[1]/ar);
2478
+ fputs(gap,stdout);
2479
+ printf("%# 14.9f", xcartq[2]/ar);
2480
+ }
2481
+ break;
2482
+ case 'Q':
2483
+ if (is_label) { printf("Q"); break; }
2484
+ printf("%-15s", spnam);
2485
+ fputs(dms(x[0], round_flag),stdout);
2486
+ fputs(dms(x[1], round_flag),stdout);
2487
+ printf(" %# 14.9f", x[2]);
2488
+ fputs(dms(x[3], round_flag),stdout);
2489
+ fputs(dms(x[4], round_flag),stdout);
2490
+ printf(" %# 14.9f\n", x[5]);
2491
+ printf(" %s", dms(xequ[0], round_flag));
2492
+ fputs(dms(xequ[1], round_flag),stdout);
2493
+ printf(" %s", dms(xequ[3], round_flag));
2494
+ fputs(dms(xequ[4], round_flag),stdout);
2495
+ break;
2496
+ case 'N':
2497
+ case 'n': {
2498
+ double xasc[6], xdsc[6];
2499
+ int imeth = (*sp == tolower(*sp))?SE_NODBIT_MEAN:SE_NODBIT_OSCU;
2500
+ iflgret = swe_nod_aps(te, ipl, iflag, imeth, xasc, xdsc, NULL, NULL, serr);
2501
+ if (iflgret >= 0 && (ipl <= SE_NEPTUNE || *sp == 'N') ) {
2502
+ if (is_label) {
2503
+ fputs("nodAsc", stdout);
2504
+ fputs(gap, stdout);
2505
+ fputs("nodDesc", stdout);
2506
+ break;
2507
+ }
2508
+ if (use_dms)
2509
+ fputs(dms(xasc[0], round_flag|BIT_ZODIAC),stdout);
2510
+ else
2511
+ printf("%# 11.7f", xasc[0]);
2512
+ fputs(gap,stdout);
2513
+ if (use_dms)
2514
+ fputs(dms(xdsc[0], round_flag|BIT_ZODIAC),stdout);
2515
+ else
2516
+ printf("%# 11.7f", xdsc[0]);
2517
+ }
2518
+ };
2519
+ break;
2520
+ case 'F':
2521
+ case 'f':
2522
+ if (! is_house) {
2523
+ double xfoc[6], xaph[6], xper[6];
2524
+ int imeth = (*sp == tolower(*sp))?SE_NODBIT_MEAN:SE_NODBIT_OSCU;
2525
+ // fprintf(stderr, "c=%c\n", *sp);
2526
+ iflgret = swe_nod_aps(te, ipl, iflag, imeth, NULL, NULL, xper, xaph, serr);
2527
+ if (iflgret >= 0 && (ipl <= SE_NEPTUNE || *sp == 'F') ) {
2528
+ if (is_label) {
2529
+ fputs("peri", stdout);
2530
+ fputs(gap, stdout);
2531
+ fputs("apo", stdout);
2532
+ fputs(gap, stdout);
2533
+ fputs("focus", stdout);
2534
+ break;
2535
+ }
2536
+ printf("%# 11.7f", xper[0]);
2537
+ fputs(gap,stdout);
2538
+ printf("%# 11.7f", xaph[0]);
2539
+ }
2540
+ imeth |= SE_NODBIT_FOPOINT;
2541
+ iflgret = swe_nod_aps(te, ipl, iflag, imeth, NULL, NULL, xper, xfoc, serr);
2542
+ if (iflgret >= 0 && (ipl <= SE_NEPTUNE || *sp == 'F') ) {
2543
+ fputs(gap,stdout);
2544
+ printf("%# 11.7f", xfoc[0]);
2545
+ }
2546
+ };
2547
+ break;
2548
+ case '+':
2549
+ if (is_house) break;
2550
+ if (is_label) { printf("phase"); break; }
2551
+ if (strchr(fmt, 'l') != NULL) { // if decimal longitude is present, do phae angle also decimal
2552
+ printf("%# 11.7f", attr[0]);
2553
+ } else {
2554
+ fputs(dms(attr[0], round_flag),stdout);
2555
+ }
2556
+ break;
2557
+ case '-':
2558
+ if (is_label) { printf("phase"); break; }
2559
+ if (is_house) break;
2560
+ printf(" %# 14.9f", attr[1]);
2561
+ break;
2562
+ case '*':
2563
+ if (is_label) { printf("elong"); break; }
2564
+ if (is_house) break;
2565
+ if (strchr(fmt, 'l') != NULL) { // if decimal longitude is present, do elongation also decimal
2566
+ printf("%# 11.7f", attr[2]);
2567
+ } else {
2568
+ fputs(dms(attr[2], round_flag),stdout);
2569
+ }
2570
+ break;
2571
+ case '/':
2572
+ if (is_label) { printf("diamet"); break; }
2573
+ if (is_house) break;
2574
+ fputs(dms(attr[3], round_flag),stdout);
2575
+ break;
2576
+ case '=':
2577
+ if (is_label) { printf("magn"); break; }
2578
+ if (is_house) break;
2579
+ printf(" %# 6.3fm", attr[4]);
2580
+ break;
2581
+ case 'V': /* human design gates */
2582
+ case 'v': {
2583
+ double xhds;
2584
+ int igate, iline, ihex;
2585
+ static int hexa[64] = {1, 43, 14, 34, 9, 5, 26, 11, 10, 58, 38, 54, 61, 60, 41, 19, 13, 49, 30, 55, 37, 63, 22, 36, 25, 17, 21, 51, 42, 3, 27, 24, 2, 23, 8, 20, 16, 35, 45, 12, 15, 52, 39, 53, 62, 56, 31, 33, 7, 4, 29, 59, 40, 64, 47, 6, 46, 18, 48, 57, 32, 50, 28, 44};
2586
+ if (is_label) { printf("hds"); break; }
2587
+ if (is_house) break;
2588
+ xhds = swe_degnorm(x[0] - 223.25);
2589
+ ihex = (int) floor(xhds / 5.625);
2590
+ iline = ((int) (floor(xhds / 0.9375))) % 6 + 1 ;
2591
+ igate = hexa[ihex];
2592
+ printf("%2d.%d", igate, iline);
2593
+ if (*sp == 'V')
2594
+ printf(" %2d%%", swe_d2l(100 * fmod(xhds / 0.9375, 1)));
2595
+ break;
2596
+ }
2597
+ case 'm': { // Meridian distance
2598
+ if (is_label) { printf("MD "); break; }
2599
+ double md = swe_difdeg2n(xequ[0], armc);
2600
+ if (md < 0) md = -md;
2601
+ if (output_extra_prec)
2602
+ printf("%# 11.11f", md);
2603
+ else
2604
+ printf("%# 11.7f", md);
2605
+ break;
2606
+ }
2607
+ case 'z': { // Zenith distance
2608
+ if (is_label) { printf("ZD "); break; }
2609
+ swe_azalt(tut, SE_EQU2HOR, geopos, datm[0], datm[1], xequ, xaz);
2610
+ double zd = 90 - xaz[1];
2611
+ if (output_extra_prec)
2612
+ printf("%# 11.11f", zd);
2613
+ else
2614
+ printf("%# 11.7f", zd);
2615
+ break;
2616
+ }
2617
+ } /* switch */
2618
+ } /* for sp */
2619
+ if (! list_hor)
2620
+ printf("\n");
2621
+ return OK;
2622
+ }
2623
+
2624
+ static char *dms(double xv, int32 iflg)
2625
+ {
2626
+ int izod;
2627
+ int32 k, kdeg, kmin, ksec;
2628
+ char *c = ODEGREE_STRING;
2629
+ char *sp, s1[50];
2630
+ static char s[50];
2631
+ int sgn;
2632
+ #if MSDOS
2633
+ if (_isnan(xv))
2634
+ return "nan";
2635
+ #else
2636
+ if (isnan(xv))
2637
+ return "nan";
2638
+ #endif
2639
+ if (xv >= 360 && !(iflg & BIT_ALLOW_361))
2640
+ xv = 0;
2641
+ *s = '\0';
2642
+ if (iflg & SEFLG_EQUATORIAL)
2643
+ c = "h";
2644
+ if (xv < 0) {
2645
+ xv = -xv;
2646
+ sgn = -1;
2647
+ } else {
2648
+ sgn = 1;
2649
+ }
2650
+ if (iflg & BIT_ROUND_MIN) {
2651
+ if (!(iflg & BIT_ALLOW_361))
2652
+ xv = swe_degnorm(xv + 0.5/60);
2653
+ } else if (iflg & BIT_ROUND_SEC) {
2654
+ if (!(iflg & BIT_ALLOW_361))
2655
+ xv = swe_degnorm(xv + 0.5/3600);
2656
+ } else {
2657
+ /* rounding 0.9999999999 to 1 */
2658
+ if (output_extra_prec)
2659
+ xv += (xv < 0 ? -1 : 1 ) * 0.000000005 / 3600.0;
2660
+ else
2661
+ xv += (xv < 0 ? -1 : 1 ) * 0.00005 / 3600.0;
2662
+ }
2663
+ if (iflg & BIT_ZODIAC) {
2664
+ izod = (int) (xv / 30);
2665
+ if (izod == 12) izod = 0;
2666
+ xv = fmod(xv, 30);
2667
+ kdeg = (int32) xv;
2668
+ sprintf(s, "%2d %s ", kdeg, zod_nam[izod]);
2669
+ } else {
2670
+ kdeg = (int32) xv;
2671
+ sprintf(s, " %3d%s", kdeg, c);
2672
+ }
2673
+ xv -= kdeg;
2674
+ xv *= 60;
2675
+ kmin = (int32) xv;
2676
+ if ((iflg & BIT_ZODIAC) && (iflg & BIT_ROUND_MIN)) {
2677
+ sprintf(s1, "%2d", kmin);
2678
+ } else {
2679
+ sprintf(s1, "%2d'", kmin);
2680
+ }
2681
+ strcat(s, s1);
2682
+ if (iflg & BIT_ROUND_MIN)
2683
+ goto return_dms;
2684
+ xv -= kmin;
2685
+ xv *= 60;
2686
+ ksec = (int32) xv;
2687
+ if (iflg & BIT_ROUND_SEC) {
2688
+ sprintf(s1, "%2d\"", ksec);
2689
+ } else {
2690
+ sprintf(s1, "%2d", ksec);
2691
+ }
2692
+ strcat(s, s1);
2693
+ if (iflg & BIT_ROUND_SEC)
2694
+ goto return_dms;
2695
+ xv -= ksec;
2696
+ if (output_extra_prec) {
2697
+ k = (int32) (xv * 100000000);
2698
+ sprintf(s1, ".%08d", k);
2699
+ } else {
2700
+ k = (int32) (xv * 10000);
2701
+ sprintf(s1, ".%04d", k);
2702
+ }
2703
+ strcat(s, s1);
2704
+ return_dms:;
2705
+ if (sgn < 0) {
2706
+ sp = strpbrk(s, "0123456789");
2707
+ *(sp-1) = '-';
2708
+ }
2709
+ if (iflg & BIT_LZEROES) {
2710
+ while ((sp = strchr(s+2, ' ')) != NULL) *sp = '0';
2711
+ }
2712
+ return(s);
2713
+ }
2714
+
2715
+ static int letter_to_ipl(int letter)
2716
+ {
2717
+ if (letter >= '0' && letter <= '9')
2718
+ return letter - '0' + SE_SUN;
2719
+ if (letter >= 'A' && letter <= 'I')
2720
+ return letter - 'A' + SE_MEAN_APOG;
2721
+ if (letter >= 'J' && letter <= 'Z')
2722
+ return letter - 'J' + SE_CUPIDO;
2723
+ switch (letter) {
2724
+ case 'm': return SE_MEAN_NODE;
2725
+ case 'c': return SE_INTP_APOG;
2726
+ case 'g': return SE_INTP_PERG;
2727
+ case 'n':
2728
+ case 'o': return SE_ECL_NUT;
2729
+ case 't': return SE_TRUE_NODE;
2730
+ case 'f': return SE_FIXSTAR;
2731
+ case 'w': return SE_WALDEMATH;
2732
+ case 'e': /* swetest: a line of labels */
2733
+ case 'q': /* swetest: delta t */
2734
+ case 'y': /* swetest: time equation */
2735
+ case 'x': /* swetest: sidereal time */
2736
+ case 'b': /* swetest: ayanamsha */
2737
+ case 's': /* swetest: an asteroid, with number given in -xs[number] */
2738
+ case 'v': /* swetest: a planetary moon, with number given in -xv[number] */
2739
+ case 'z': /* swetest: a fictitious body, number given in -xz[number] */
2740
+ case 'd': /* swetest: default (main) factors 0123456789mtABC */
2741
+ case 'p': /* swetest: main factors ('d') plus main asteroids DEFGHI */
2742
+ case 'h': /* swetest: fictitious factors JKLMNOPQRSTUVWXYZw */
2743
+ case 'a': /* swetest: all factors, like 'p'+'h' */
2744
+ return -1;
2745
+ }
2746
+ return -2;
2747
+ }
2748
+
2749
+ static int32 ut_to_lmt_lat(double t_ut, double *geopos, double *t_ret, char *serr)
2750
+ {
2751
+ int32 iflgret = OK;
2752
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
2753
+ t_ut += geopos[0] / 360.0;
2754
+ if (time_flag & BIT_TIME_LAT) {
2755
+ iflgret = swe_lmt_to_lat(t_ut, geopos[0], &t_ut, serr);
2756
+ }
2757
+ }
2758
+ *t_ret = t_ut;
2759
+ return iflgret;
2760
+ }
2761
+
2762
+ static int32 orbital_elements(double tjd_et, int32 ipl, int32 iflag, char *serr)
2763
+ {
2764
+ int32 retval;
2765
+ double dret[20], jut;
2766
+ int32 jyear, jmon, jday;
2767
+ char sdateperi[20];
2768
+ retval = swe_get_orbital_elements(tjd_et, ipl, iflag, dret, serr);
2769
+ if (retval == ERR) {
2770
+ printf("%s\n", serr);
2771
+ return ERR;
2772
+ } else {
2773
+ swe_revjul(dret[14], gregflag, &jyear, &jmon, &jday, &jut);
2774
+ sprintf(sdateperi, "%2d.%02d.%04d,%s", jday, jmon, jyear, hms(jut,BIT_LZEROES));
2775
+ printf("semiaxis \t%f\neccentricity \t%f\ninclination \t%f\nasc. node \t%f\narg. pericenter \t%f\npericenter \t%f\n", dret[0], dret[1], dret[2], dret[3], dret[4], dret[5]);
2776
+ printf("mean longitude \t%f\nmean anomaly \t%f\necc. anomaly \t%f\ntrue anomaly \t%f\n", dret[9], dret[6], dret[8], dret[7]);
2777
+ printf("time pericenter \t%f %s\ndist. pericenter \t%f\ndist. apocenter \t%f\n", dret[14], sdateperi, dret[15], dret[16]);
2778
+ printf("mean daily motion\t%f\nsid. period (y) \t%f\ntrop. period (y) \t%f\nsynodic cycle (d)\t%f\n", dret[11], dret[10], dret[12], dret[13]);
2779
+ }
2780
+ return OK;
2781
+ }
2782
+
2783
+ static void insert_gap_string_for_tabs(char *sout, char *gap)
2784
+ {
2785
+ char *sp;
2786
+ char s[LEN_SOUT];
2787
+ if (!have_gap_parameter)
2788
+ return;
2789
+ if (*gap == '\t')
2790
+ return;
2791
+ while((sp = strchr(sout, '\t')) != NULL && strlen(sout) + strlen(gap) < LEN_SOUT) {
2792
+ strcpy(s, sp + 1);
2793
+ strcpy(sp, gap);
2794
+ strcat(sp, s);
2795
+ }
2796
+ }
2797
+
2798
+ static int32 print_rise_set_line(double trise, double tset, double *geopos, char *serr) {
2799
+ double t0;
2800
+ int retc = OK;
2801
+ *sout = '\0';
2802
+ if (trise != 0) retc = ut_to_lmt_lat(trise, geopos, &(trise), serr);
2803
+ if (tset != 0) retc = ut_to_lmt_lat(tset, geopos, &(tset), serr);
2804
+ strcpy(sout, "rise ");
2805
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2806
+ if (trise == 0) {
2807
+ strcat(sout, " -\t - ");
2808
+ } else {
2809
+ swe_revjul(trise, gregflag, &jyear, &jmon, &jday, &jut);
2810
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d\t%s ", jday, jmon, jyear, hms(jut,BIT_LZEROES));
2811
+ }
2812
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2813
+ strcat(sout, "set ");
2814
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2815
+ if (tset == 0 ) {
2816
+ strcat(sout, " -\t - ");
2817
+ } else {
2818
+ swe_revjul(tset, gregflag, &jyear, &jmon, &jday, &jut);
2819
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d\t%s ", jday, jmon, jyear, hms(jut,BIT_LZEROES));
2820
+ }
2821
+ if (trise != 0 && tset != 0) {
2822
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2823
+ sprintf(sout + strlen(sout), "dt =");
2824
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2825
+ t0 = (tset - trise) * 24;
2826
+ sprintf(sout + strlen(sout), "%s", hms(t0, BIT_LZEROES));
2827
+ }
2828
+ strcat(sout, "\n");
2829
+ if (have_gap_parameter) insert_gap_string_for_tabs(sout, gap);
2830
+ do_printf(sout);
2831
+ return retc;
2832
+ }
2833
+
2834
+ static int32 call_rise_set(double t_ut, int32 ipl, char *star, int32 whicheph, double *geopos, char *serr)
2835
+ {
2836
+ int ii, rval, loop_count;
2837
+ int32 rsmi = 0;
2838
+ double dayfrac = 0.0001;
2839
+ double tret[10], trise, tset, tnext, tret1sv = 0;
2840
+ AS_BOOL do_rise, do_set;
2841
+ AS_BOOL last_was_empty = FALSE;
2842
+ int32 retc = OK;
2843
+ int rsmior = 0;
2844
+ if (norefrac) rsmior |= SE_BIT_NO_REFRACTION;
2845
+ if (disccenter) rsmior |= SE_BIT_DISC_CENTER;
2846
+ if (discbottom) rsmior |= SE_BIT_DISC_BOTTOM;
2847
+ if (hindu) rsmior |= SE_BIT_HINDU_RISING;
2848
+ if (fabs(geopos[1]) < 60 && ipl >= SE_SUN && ipl <= SE_PLUTO)
2849
+ dayfrac = 0.01;
2850
+ swe_set_topo(geopos[0], geopos[1], geopos[2]);
2851
+ // "geo. long 8.000000, lat 47.000000, alt 0.000000"
2852
+ if (with_header)
2853
+ printf("\ngeo. long %f, lat %f, alt %f", geopos[0], geopos[1], geopos[2]);
2854
+ do_printf("\n");
2855
+ tnext = t_ut;
2856
+ // the code is designed for looping with -nxxx over many days, during which
2857
+ // the object might become circumpolar, or never rise at all.
2858
+ while (special_event == SP_RISE_SET && tnext < t_ut + nstep) {
2859
+ // the following 'if' avoids unnecessary calculations for circumpolar
2860
+ // objects. even without it, the output would be correct, but
2861
+ // could be considerably slower.
2862
+ if (last_was_empty && (star == NULL || *star == '\0')) {
2863
+ rval = swe_calc_ut(tnext, ipl, whicheph|SEFLG_EQUATORIAL, tret, serr);
2864
+ if (rval >= 0 ) {
2865
+ double edist = geopos[1] + tret[1];
2866
+ double edist2 = geopos[1] - tret[1];
2867
+ if ((edist - 2 > 90 || edist + 2 < -90)
2868
+ || (edist2 - 2 > 90 || edist2 + 2 < -90)) {
2869
+ tnext += 1;
2870
+ continue;
2871
+ }
2872
+ }
2873
+ }
2874
+ /* rising */
2875
+ rsmi = SE_CALC_RISE | rsmior;
2876
+ rval= swe_rise_trans(tnext, ipl, star, whicheph, rsmi, geopos, datm[0], datm[1], &trise, serr);
2877
+ if (rval == ERR) {
2878
+ do_printf(serr);
2879
+ exit(0);
2880
+ }
2881
+ do_rise = (rval == OK);
2882
+ /* setting */
2883
+ rsmi = SE_CALC_SET | rsmior;
2884
+ do_set = FALSE;
2885
+ loop_count = 0;
2886
+ //tnext = trise; // dieter 14-feb-17
2887
+ while (! do_set && loop_count < 2) {
2888
+ rval = swe_rise_trans(tnext, ipl, star, whicheph, rsmi, geopos, datm[0], datm[1], &tset, serr);
2889
+ if (rval == ERR) {
2890
+ do_printf(serr);
2891
+ exit(0);
2892
+ }
2893
+ do_set = (rval == OK);
2894
+ if (!do_set && do_rise ) {
2895
+ tnext = trise;
2896
+ }
2897
+ loop_count++;
2898
+ }
2899
+ if (do_rise && do_set && trise > tset) {
2900
+ do_rise = FALSE; // ignore rises happening before setting
2901
+ trise = 0; // we hope that exact time 0 never happens, is highly unlikely.
2902
+ }
2903
+ if (do_rise && do_set) {
2904
+ rval = print_rise_set_line(trise, tset, geopos, serr);
2905
+ last_was_empty = FALSE;
2906
+ tnext = tset + dayfrac;
2907
+ } else if (do_rise && !do_set) {
2908
+ rval = print_rise_set_line(trise, 0, geopos, serr);
2909
+ last_was_empty = FALSE;
2910
+ tnext = trise + dayfrac;
2911
+ } else if (do_set && ! do_rise) {
2912
+ tnext = tset + dayfrac;
2913
+ rval = print_rise_set_line(0, tset, geopos, serr);
2914
+ last_was_empty = FALSE;
2915
+ } else { // neither rise nor set
2916
+ // for sequences of days without rise or set, the line '- -' is printed only once.
2917
+ if (! last_was_empty) rval = print_rise_set_line(0, 0, geopos, serr);
2918
+ tnext += 1;
2919
+ last_was_empty = TRUE;
2920
+ }
2921
+ if (rval == ERR) {
2922
+ do_printf(serr);
2923
+ exit(0);
2924
+ }
2925
+ if (nstep == 1) break;
2926
+ }
2927
+ /* swetest -metr
2928
+ * calculate and print transits over meridian (midheaven and lower
2929
+ * midheaven */
2930
+ if (special_event == SP_MERIDIAN_TRANSIT) {
2931
+ /* loop over days */
2932
+ for (ii = 0; ii < nstep; ii++, t_ut = tret1sv + 0.001) {
2933
+ /* transit over midheaven */
2934
+ if (swe_rise_trans(t_ut, ipl, star, whicheph, SE_CALC_MTRANSIT, geopos, datm[0], datm[1], &(tret[0]), serr) != OK) {
2935
+ do_printf(serr);
2936
+ return ERR;
2937
+ }
2938
+ /* transit over lower midheaven */
2939
+ if (swe_rise_trans(t_ut, ipl, star, whicheph, SE_CALC_ITRANSIT, geopos, datm[0], datm[1], &(tret[1]), serr) != OK) {
2940
+ do_printf(serr);
2941
+ return ERR;
2942
+ }
2943
+ tret1sv = tret[1];
2944
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
2945
+ retc = ut_to_lmt_lat(tret[0], geopos, &(tret[0]), serr);
2946
+ retc = ut_to_lmt_lat(tret[1], geopos, &(tret[1]), serr);
2947
+ }
2948
+ strcpy(sout, "mtransit ");
2949
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2950
+ if (tret[0] == 0 || tret[0] > tret[1]) strcat(sout, " -\t - ");
2951
+ else {
2952
+ swe_revjul(tret[0], gregflag, &jyear, &jmon, &jday, &jut);
2953
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d\t%s ", jday, jmon, jyear, hms(jut,BIT_LZEROES));
2954
+ }
2955
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2956
+ strcat(sout, "itransit ");
2957
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
2958
+ if (tret[1] == 0) strcat(sout, " -\t - \n");
2959
+ else {
2960
+ swe_revjul(tret[1], gregflag, &jyear, &jmon, &jday, &jut);
2961
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d\t%s\n", jday, jmon, jyear, hms(jut,BIT_LZEROES));
2962
+ }
2963
+ if (have_gap_parameter) insert_gap_string_for_tabs(sout, gap);
2964
+ do_printf(sout);
2965
+ }
2966
+ }
2967
+ return retc;
2968
+ }
2969
+
2970
+ static char* get_gregjul(int gregflag, int year)
2971
+ {
2972
+ if (gregflag == SE_JUL_CAL) return "jul";
2973
+ if (year < 1700) return "greg";
2974
+ return "";
2975
+ }
2976
+
2977
+ // print lon and lat string in minute precision
2978
+ static void format_lon_lat(char *slon, char *slat, double lon, double lat)
2979
+ {
2980
+ int roundflag, ideg, imin, isec, isgn;
2981
+ double dsecfr;
2982
+ char c;
2983
+ roundflag = SE_SPLIT_DEG_ROUND_SEC;
2984
+ swe_split_deg(lon, roundflag, &ideg, &imin, &isec, &dsecfr, &isgn);
2985
+ c = (lon < 0) ? 'w' : 'e';
2986
+ sprintf(slon, "%d%c%02d%02d", abs(ideg), c, imin, isec);
2987
+ swe_split_deg(lat, roundflag, &ideg, &imin, &isec, &dsecfr, &isgn);
2988
+ c = (lat < 0) ? 's' : 'n';
2989
+ sprintf(slat, "%d%c%02d%02d", abs(ideg), c, imin, isec);
2990
+ }
2991
+
2992
+ static int32 call_lunar_eclipse(double t_ut, int32 whicheph, int32 special_mode, double *geopos, char *serr)
2993
+ {
2994
+ int i, ii, retc = OK, eclflag, ecl_type = 0;
2995
+ int rval, ihou, imin, isec, isgn;
2996
+ double dfrc, attr[30], dt, xx[6], geopos_max[3];
2997
+ char s1[AS_MAXCH], s2[AS_MAXCH], sout_short[2 * LEN_SOUT], sfmt[AS_MAXCH], *styp = "none", *sgj;
2998
+ char slon[8], slat[8], saros[40];
2999
+ geopos_max[0] = 0; geopos_max[1] = 0;
3000
+ /* no selective eclipse type set, set all */
3001
+ if (with_chart_link) do_printf("<pre>");
3002
+ if ((search_flag & SE_ECL_ALLTYPES_LUNAR) == 0)
3003
+ search_flag |= SE_ECL_ALLTYPES_LUNAR;
3004
+ // "geo. long 8.000000, lat 47.000000, alt 0.000000"
3005
+ if (special_mode & SP_MODE_LOCAL) {
3006
+ if (with_header)
3007
+ printf("\ngeo. long %f, lat %f, alt %f", geopos[0], geopos[1], geopos[2]);
3008
+ }
3009
+ do_printf("\n");
3010
+ for (ii = 0; ii < nstep; ii++, t_ut += direction) {
3011
+ *sout = '\0';
3012
+ /* swetest -lunecl -how
3013
+ * type of lunar eclipse and percentage for a given time: */
3014
+ if (special_mode & SP_MODE_HOW) {
3015
+ if ((eclflag = swe_lun_eclipse_how(t_ut, whicheph, geopos, attr, serr)) ==
3016
+ ERR) {
3017
+ do_printf(serr);
3018
+ return ERR;
3019
+ } else {
3020
+ if (eclflag & SE_ECL_TOTAL) {
3021
+ ecl_type = ECL_LUN_TOTAL;
3022
+ strcpy(sfmt, "total lunar eclipse: %f o/o \n");
3023
+ } else if (eclflag & SE_ECL_PARTIAL) {
3024
+ ecl_type = ECL_LUN_PARTIAL;
3025
+ strcpy(sfmt, "partial lunar eclipse: %f o/o \n");
3026
+ } else if (eclflag & SE_ECL_PENUMBRAL) {
3027
+ ecl_type = ECL_LUN_PENUMBRAL;
3028
+ strcpy(sfmt, "penumbral lunar eclipse: %f o/o \n");
3029
+ } else {
3030
+ strcpy(sfmt, "no lunar eclipse \n");
3031
+ }
3032
+ strcpy(sout, sfmt);
3033
+ if (strchr(sfmt, '%') != NULL) {
3034
+ sprintf(sout, sfmt, attr[0]);
3035
+ }
3036
+ do_printf(sout);
3037
+ }
3038
+ continue;
3039
+ }
3040
+ /* swetest -lunecl
3041
+ * find next lunar eclipse: */
3042
+ /* locally visible lunar eclipse */
3043
+ if (special_mode & SP_MODE_LOCAL) {
3044
+ if ((eclflag = swe_lun_eclipse_when_loc(t_ut, whicheph, geopos,
3045
+ tret, attr, direction_flag, serr)) == ERR) {
3046
+ do_printf(serr);
3047
+ return ERR;
3048
+ }
3049
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3050
+ for (i = 0; i < 10; i++) {
3051
+ if (tret[i] != 0) {
3052
+ retc = ut_to_lmt_lat(tret[i], geopos, &(tret[i]), serr);
3053
+ if (retc == ERR) {
3054
+ do_printf(serr);
3055
+ return ERR;
3056
+ }
3057
+ }
3058
+ }
3059
+ }
3060
+ t_ut = tret[0];
3061
+ if ((eclflag & SE_ECL_TOTAL)) {
3062
+ strcpy(sout, "total ");
3063
+ ecl_type = ECL_LUN_TOTAL;
3064
+ }
3065
+ if ((eclflag & SE_ECL_PENUMBRAL)) {
3066
+ strcpy(sout, "penumb. ");
3067
+ ecl_type = ECL_LUN_PENUMBRAL;
3068
+ }
3069
+ if ((eclflag & SE_ECL_PARTIAL)) {
3070
+ strcpy(sout, "partial ");
3071
+ ecl_type = ECL_LUN_PARTIAL;
3072
+ }
3073
+ strcat(sout, "lunar eclipse\t");
3074
+ swe_revjul(t_ut, gregflag, &jyear, &jmon, &jday, &jut);
3075
+ sgj = get_gregjul(gregflag, jyear);
3076
+ /*if ((eclflag = swe_lun_eclipse_how(t_ut, whicheph, geopos, attr, serr)) == ERR) {
3077
+ do_printf(serr);
3078
+ return ERR;
3079
+ }*/
3080
+ dt = (tret[3] - tret[2]) * 24 * 60;
3081
+ sprintf(s1, "%d min %4.2f sec", (int) dt, fmod(dt, 1) * 60);
3082
+ /* short output:
3083
+ * date, time of day, umbral magnitude, umbral duration, saros series, member number */
3084
+ sprintf(saros, "%d/%d", (int) attr[9], (int) attr[10]);
3085
+ sprintf(sout_short, "%s\t%2d.%2d.%4d%s\t%s\t%.3f\t%s\t%s\n", sout, jday, jmon, jyear, sgj, hms(jut,0), attr[8],s1, saros);
3086
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d%s\t%s\t%.4f/%.4f\tsaros %s\t%.6f\n", jday, jmon, jyear, sgj, hms(jut,BIT_LZEROES), attr[0],attr[1], saros, t_ut);
3087
+ /* second line:
3088
+ * eclipse times, penumbral, partial, total begin and end */
3089
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3090
+ if (eclflag & SE_ECL_PENUMBBEG_VISIBLE)
3091
+ sprintf(sout + strlen(sout), " %s ", hms_from_tjd(tret[6]));
3092
+ else
3093
+ strcat(sout, " - ");
3094
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3095
+ if (eclflag & SE_ECL_PARTBEG_VISIBLE)
3096
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[2]));
3097
+ else
3098
+ strcat(sout, " - ");
3099
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3100
+ if (eclflag & SE_ECL_TOTBEG_VISIBLE)
3101
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
3102
+ else
3103
+ strcat(sout, " - ");
3104
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3105
+ if (eclflag & SE_ECL_TOTEND_VISIBLE)
3106
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[5]));
3107
+ else
3108
+ strcat(sout, " - ");
3109
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3110
+ if (eclflag & SE_ECL_PARTEND_VISIBLE)
3111
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[3]));
3112
+ else
3113
+ strcat(sout, " - ");
3114
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3115
+ if (eclflag & SE_ECL_PENUMBEND_VISIBLE)
3116
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[7]));
3117
+ else
3118
+ strcat(sout, " - ");
3119
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3120
+ sprintf(sout + strlen(sout), "dt=%.1f", swe_deltat_ex(tret[0], whicheph, serr) * 86400.0);
3121
+ strcat(sout, "\n");
3122
+ /* global lunar eclipse */
3123
+ } else {
3124
+ if ((eclflag = swe_lun_eclipse_when(t_ut, whicheph, search_flag,
3125
+ tret, direction_flag, serr)) == ERR) {
3126
+ do_printf(serr);
3127
+ return ERR;
3128
+ }
3129
+ t_ut = tret[0];
3130
+ if ((eclflag & SE_ECL_TOTAL)) {
3131
+ styp = "Total";
3132
+ strcpy(sout, "total ");
3133
+ ecl_type = ECL_LUN_TOTAL;
3134
+ }
3135
+ if ((eclflag & SE_ECL_PENUMBRAL)) {
3136
+ styp = "Penumbral";
3137
+ strcpy(sout, "penumb. ");
3138
+ ecl_type = ECL_LUN_PENUMBRAL;
3139
+ }
3140
+ if ((eclflag & SE_ECL_PARTIAL)) {
3141
+ styp = "Partial";
3142
+ strcpy(sout, "partial ");
3143
+ ecl_type = ECL_LUN_PARTIAL;
3144
+ }
3145
+ strcat(sout, "lunar eclipse\t");
3146
+ if ((eclflag = swe_lun_eclipse_how(t_ut, whicheph, geopos, attr, serr)) ==
3147
+ ERR) {
3148
+ do_printf(serr);
3149
+ return ERR;
3150
+ }
3151
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3152
+ for (i = 0; i < 10; i++) {
3153
+ if (tret[i] != 0) {
3154
+ retc = ut_to_lmt_lat(tret[i], geopos, &(tret[i]), serr);
3155
+ if (retc == ERR) {
3156
+ do_printf(serr);
3157
+ return ERR;
3158
+ }
3159
+ }
3160
+ }
3161
+ }
3162
+ t_ut = tret[0];
3163
+ rval = swe_calc_ut(t_ut, SE_MOON, whicheph|SEFLG_EQUATORIAL, xx, s1);
3164
+ if (rval < 0)
3165
+ strcat(s1, "\n");
3166
+ do_printf(s1);
3167
+ swe_revjul(t_ut, gregflag, &jyear, &jmon, &jday, &jut);
3168
+ geopos_max[0] = swe_degnorm(xx[0]- swe_sidtime(t_ut) * 15);
3169
+ if (geopos_max[0] > 180) geopos_max[0] -= 360;
3170
+ geopos_max[1] = xx[1];
3171
+ sgj = get_gregjul(gregflag, jyear);
3172
+ dt = (tret[3] - tret[2]) * 24 * 60;
3173
+ sprintf(s1, "%d min %4.2f sec", (int) dt, fmod(dt, 1) * 60);
3174
+ /* short output:
3175
+ * date, time of day, umbral magnitude, umbral duration, saros series, member number */
3176
+ sprintf(saros, "%d/%d", (int) attr[9], (int) attr[10]);
3177
+ sprintf(sout_short, "%s\t%2d.%2d.%4d%s\t%s\t%.3f\t%s\t%s\n", sout, jday, jmon, jyear, sgj, hms(jut,0), attr[8],s1, saros);
3178
+ //sprintf(sout + strlen(sout), "%2d.%02d.%04d%s\t%s\t%.4f/%.4f\tsaros %s\t%.6f\tdt=%.2f\n", jday, jmon, jyear, sgj, hms(jut,BIT_LZEROES), attr[0],attr[1], saros, t_ut, swe_deltat_ex(t_ut, whicheph, serr) * 86400);
3179
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d%s\t%s\t%.4f/%.4f\tsaros %s\t%.6f\n", jday, jmon, jyear, sgj, hms(jut,BIT_LZEROES), attr[0],attr[1], saros, t_ut);
3180
+ /* second line:
3181
+ * eclipse times, penumbral, partial, total begin and end */
3182
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3183
+ sprintf(sout + strlen(sout), " %s ", hms_from_tjd(tret[6]));
3184
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3185
+ if (tret[2] != 0)
3186
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[2]));
3187
+ else
3188
+ strcat(sout, " - ");
3189
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3190
+ if (tret[4] != 0)
3191
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
3192
+ else
3193
+ strcat(sout, " - ");
3194
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3195
+ if (tret[5] != 0)
3196
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[5]));
3197
+ else
3198
+ strcat(sout, " - ");
3199
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3200
+ if (tret[3] != 0)
3201
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[3]));
3202
+ else
3203
+ strcat(sout, " - ");
3204
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3205
+ sprintf(sout + strlen(sout), "%s", hms_from_tjd(tret[7]));
3206
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3207
+ sprintf(sout + strlen(sout), "dt=%.1f", swe_deltat_ex(tret[0], whicheph, serr) * 86400.0);
3208
+ strcat(sout, "\n");
3209
+ if (special_mode & SP_MODE_HOCAL) {
3210
+ swe_split_deg(jut, SE_SPLIT_DEG_ROUND_MIN, &ihou, &imin, &isec, &dfrc, &isgn);
3211
+ sprintf(sout, "\"%04d%s %02d %02d %02d.%02d %d\",\n", jyear, sgj, jmon, jday, ihou, imin, ecl_type);
3212
+ }
3213
+ sprintf(sout + strlen(sout), "\t%s\t%s\n", strcpy(s1, dms(geopos_max[0], BIT_ROUND_SEC)), strcpy(s2, dms(geopos_max[1], BIT_ROUND_SEC)));
3214
+ }
3215
+ //dt = (tret[7] - tret[6]) * 24 * 60;
3216
+ //sprintf(sout + strlen(sout), "\t%d min %4.2f sec\n", (int) dt, fmod(dt, 1) * 60);
3217
+ if (have_gap_parameter) insert_gap_string_for_tabs(sout, gap);
3218
+ if (short_output) {
3219
+ do_printf(sout_short);
3220
+ } else {
3221
+ do_printf(sout);
3222
+ }
3223
+ if (with_chart_link) {
3224
+ char snat[2 * AS_MAXCH];
3225
+ char stim[80];
3226
+ int iflg = 0;
3227
+ char cal = gregflag ? 'g' : 'j';
3228
+ strcpy(stim, hms(jut,BIT_LZEROES));
3229
+ format_lon_lat(slon, slat, geopos_max[0], geopos_max[1]);
3230
+ while (*stim == ' ') our_strcpy(stim, stim + 1);
3231
+ if (*stim == '0') our_strcpy(stim, stim + 1);
3232
+ sprintf(snat, "Lunar Eclipse %s,%s,e,%d,%d,%d,%s,h0e,%cnu,%d,Moon Zenith location,,%s,%s,u,0,0,0", saros, styp, jday, jmon, jyear, stim, cal, iflg, slon, slat);
3233
+ sprintf(sout, "<a href='https://www.astro.com/cgi/chart.cgi?muasp=1;nhor=1;act=chmnat;nd1=%s;rs=1;iseclipse=1' target='eclipse'>chart link</a>\n\n", snat);
3234
+ do_printf(sout);
3235
+ }
3236
+ }
3237
+ if (with_chart_link) do_printf("</pre>\n");
3238
+ return OK;
3239
+ }
3240
+
3241
+ static int32 call_solar_eclipse(double t_ut, int32 whicheph, int32 special_mode, double *geopos, char *serr)
3242
+ {
3243
+ int i, ii, retc = OK, eclflag, ecl_type = 0;
3244
+ double dt, tret[30], attr[30], geopos_max[3];
3245
+ char slon[8], slat[8], saros[20];
3246
+ char s1[AS_MAXCH], s2[AS_MAXCH], sout_short[AS_MAXCH + LEN_SOUT], *styp = "none", *sgj;
3247
+ AS_BOOL has_found = FALSE;
3248
+ /* no selective eclipse type set, set all */
3249
+ if (with_chart_link) do_printf("<pre>");
3250
+ if ((search_flag & SE_ECL_ALLTYPES_SOLAR) == 0)
3251
+ search_flag |= SE_ECL_ALLTYPES_SOLAR;
3252
+ /* for local eclipses: set geographic position of observer */
3253
+ if (special_mode & SP_MODE_LOCAL) {
3254
+ swe_set_topo(geopos[0], geopos[1], geopos[2]);
3255
+ // "geo. long 8.000000, lat 47.000000, alt 0.000000"
3256
+ if (with_header)
3257
+ printf("\ngeo. long %f, lat %f, alt %f", geopos[0], geopos[1], geopos[2]);
3258
+ }
3259
+ do_printf("\n");
3260
+ for (ii = 0; ii < nstep; ii++, t_ut += direction) {
3261
+ *sout = '\0';
3262
+ /* swetest -solecl -local -geopos...
3263
+ * find next solar eclipse observable from a given geographic position */
3264
+ if (special_mode & SP_MODE_LOCAL) {
3265
+ if ((eclflag = swe_sol_eclipse_when_loc(t_ut, whicheph, geopos, tret,
3266
+ attr, direction_flag, serr)) == ERR) {
3267
+ do_printf(serr);
3268
+ return ERR;
3269
+ } else {
3270
+ has_found = FALSE;
3271
+ t_ut = tret[0];
3272
+ if ((search_flag & SE_ECL_TOTAL) && (eclflag & SE_ECL_TOTAL)) {
3273
+ strcpy(sout, "total ");
3274
+ has_found = TRUE;
3275
+ ecl_type = ECL_SOL_TOTAL;
3276
+ }
3277
+ if ((search_flag & SE_ECL_ANNULAR) && (eclflag & SE_ECL_ANNULAR)) {
3278
+ strcpy(sout, "annular ");
3279
+ has_found = TRUE;
3280
+ ecl_type = ECL_SOL_ANNULAR;
3281
+ }
3282
+ if ((search_flag & SE_ECL_PARTIAL) && (eclflag & SE_ECL_PARTIAL)) {
3283
+ strcpy(sout, "partial ");
3284
+ has_found = TRUE;
3285
+ ecl_type = ECL_SOL_PARTIAL;
3286
+ }
3287
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3288
+ if (!has_found) {
3289
+ ii--;
3290
+ } else {
3291
+ swe_calc(t_ut + swe_deltat_ex(t_ut, whicheph, serr), SE_ECL_NUT, 0, x, serr);
3292
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3293
+ for (i = 0; i < 10; i++) {
3294
+ if (tret[i] != 0) {
3295
+ retc = ut_to_lmt_lat(tret[i], geopos, &(tret[i]), serr);
3296
+ if (retc == ERR) {
3297
+ do_printf(serr);
3298
+ return ERR;
3299
+ }
3300
+ }
3301
+ }
3302
+ }
3303
+ t_ut = tret[0];
3304
+ swe_revjul(t_ut, gregflag, &jyear, &jmon, &jday, &jut);
3305
+ dt = (tret[3] - tret[2]) * 24 * 60;
3306
+ sgj = get_gregjul(gregflag, jyear);
3307
+ sprintf(saros, "%d/%d", (int) attr[9], (int) attr[10]);
3308
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d%s\t%s\t%.4f/%.4f/%.4f\tsaros %s\t%.6f\n", jday, jmon, jyear, sgj,hms(jut,BIT_LZEROES), attr[8], attr[0], attr[2], saros, t_ut);
3309
+ sprintf(sout + strlen(sout), "\t%d min %4.2f sec\t", (int) dt, fmod(dt, 1) * 60);
3310
+ if (eclflag & SE_ECL_1ST_VISIBLE) {
3311
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[1]));
3312
+ } else {
3313
+ strcat(sout, " - ");
3314
+ }
3315
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3316
+ if (eclflag & SE_ECL_2ND_VISIBLE) {
3317
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[2]));
3318
+ } else {
3319
+ strcat(sout, " - ");
3320
+ }
3321
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3322
+ if (eclflag & SE_ECL_3RD_VISIBLE) {
3323
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[3]));
3324
+ } else {
3325
+ strcat(sout, " - ");
3326
+ }
3327
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3328
+ if (eclflag & SE_ECL_4TH_VISIBLE) {
3329
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
3330
+ } else {
3331
+ strcat(sout, " - ");
3332
+ }
3333
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3334
+ #if 0
3335
+ sprintf(sout + strlen(sout), "\t%d min %4.2f sec %s %s %s %s",
3336
+ (int) dt, fmod(dt, 1) * 60,
3337
+ strcpy(s1, hms(fmod(tret[1] + 0.5, 1) * 24, BIT_LZEROES)),
3338
+ strcpy(s3, hms(fmod(tret[2] + 0.5, 1) * 24, BIT_LZEROES)),
3339
+ strcpy(s4, hms(fmod(tret[3] + 0.5, 1) * 24, BIT_LZEROES)),
3340
+ strcpy(s2, hms(fmod(tret[4] + 0.5, 1) * 24, BIT_LZEROES)));
3341
+ #endif
3342
+ sprintf(sout + strlen(sout), "dt=%.1f", swe_deltat_ex(tret[0], whicheph, serr) * 86400.0);
3343
+ strcat(sout, "\n");
3344
+ if (have_gap_parameter) insert_gap_string_for_tabs(sout, gap);
3345
+ do_printf(sout);
3346
+ }
3347
+ }
3348
+ } /* endif search_local */
3349
+ /* swetest -solecl
3350
+ * find next solar eclipse observable from anywhere on earth */
3351
+ if (!(special_mode & SP_MODE_LOCAL)) {
3352
+ if ((eclflag = swe_sol_eclipse_when_glob(t_ut, whicheph, search_flag,
3353
+ tret, direction_flag, serr)) == ERR) {
3354
+ do_printf(serr);
3355
+ return ERR;
3356
+ }
3357
+ t_ut = tret[0];
3358
+ if ((eclflag & SE_ECL_TOTAL)) {
3359
+ styp = "Total";
3360
+ strcpy(sout, "total");
3361
+ ecl_type = ECL_SOL_TOTAL;
3362
+ }
3363
+ if ((eclflag & SE_ECL_ANNULAR)) {
3364
+ styp = "Annular";
3365
+ strcpy(sout, "annular");
3366
+ ecl_type = ECL_SOL_ANNULAR;
3367
+ }
3368
+ if ((eclflag & SE_ECL_ANNULAR_TOTAL)) {
3369
+ styp = "Annular-Total";
3370
+ strcpy(sout, "ann-tot");
3371
+ ecl_type = ECL_SOL_ANNULAR; /* by Alois: what is this ? */
3372
+ }
3373
+ if ((eclflag & SE_ECL_PARTIAL)) {
3374
+ styp = "Partial";
3375
+ strcpy(sout, "partial");
3376
+ ecl_type = ECL_SOL_PARTIAL;
3377
+ }
3378
+ if ((eclflag & SE_ECL_NONCENTRAL) && !(eclflag & SE_ECL_PARTIAL))
3379
+ strcat(sout, " non-central");
3380
+ sprintf(sout + strlen(sout), " solar\t");
3381
+ swe_sol_eclipse_where(t_ut, whicheph, geopos_max, attr, serr);
3382
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3383
+ for (i = 0; i < 10; i++) {
3384
+ if (tret[i] != 0) {
3385
+ retc = ut_to_lmt_lat(tret[i], geopos, &(tret[i]), serr);
3386
+ if (retc == ERR) {
3387
+ do_printf(serr);
3388
+ return ERR;
3389
+ }
3390
+ }
3391
+ }
3392
+ }
3393
+ swe_revjul(tret[0], gregflag, &jyear, &jmon, &jday, &jut);
3394
+ sgj = get_gregjul(gregflag, jyear);
3395
+ sprintf(saros, "%d/%d", (int) attr[9], (int) attr[10]);
3396
+ sprintf(sout_short, "%s\t%2d.%2d.%4d%s\t%s\t%.3f", sout, jday, jmon, jyear, sgj, hms(jut,0), attr[8]);
3397
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d%s\t%s\t%f km\t%.4f/%.4f/%.4f\tsaros %s\t%.6f\n", jday, jmon, jyear, sgj, hms(jut,0), attr[3], attr[8], attr[0], attr[2], saros, tret[0]);
3398
+ sprintf(sout + strlen(sout), "\t%s ", hms_from_tjd(tret[2]));
3399
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3400
+ if (tret[4] != 0) {
3401
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
3402
+ } else {
3403
+ strcat(sout, " - ");
3404
+ }
3405
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3406
+ if (tret[5] != 0) {
3407
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[5]));
3408
+ } else {
3409
+ strcat(sout, " - ");
3410
+ }
3411
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3412
+ sprintf(sout + strlen(sout), "%s", hms_from_tjd(tret[3]));
3413
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3414
+ sprintf(sout + strlen(sout), "dt=%.1f", swe_deltat_ex(tret[0], whicheph, serr) * 86400.0);
3415
+ strcat(sout, "\n");
3416
+ sprintf(sout + strlen(sout), "\t%s\t%s", strcpy(s1, dms(geopos_max[0], BIT_ROUND_SEC)), strcpy(s2, dms(geopos_max[1], BIT_ROUND_SEC)));
3417
+ strcat(sout, "\t");
3418
+ strcat(sout_short, "\t");
3419
+ if (!(eclflag & SE_ECL_PARTIAL) && !(eclflag & SE_ECL_NONCENTRAL)) {
3420
+ if ((eclflag = swe_sol_eclipse_when_loc(t_ut - 10, whicheph, geopos_max, tret, attr, 0, serr)) == ERR) {
3421
+ do_printf(serr);
3422
+ return ERR;
3423
+ }
3424
+ if (fabs(tret[0] - t_ut) > 2) {
3425
+ do_printf("when_loc returns wrong date\n");
3426
+ }
3427
+ dt = (tret[3] - tret[2]) * 24 * 60;
3428
+ sprintf(s1, "%d min %4.2f sec", (int) dt, fmod(dt, 1) * 60);
3429
+ strcat(sout, s1);
3430
+ strcat(sout_short, s1);
3431
+ }
3432
+ sprintf(sout_short + strlen(sout_short), "\t%d\t%d", (int) attr[9], (int) attr[10]);
3433
+ strcat(sout, "\n");
3434
+ strcat(sout_short, "\n");
3435
+ if (special_mode & SP_MODE_HOCAL) {
3436
+ int ihou, imin, isec, isgn;
3437
+ double dfrc;
3438
+ swe_split_deg(jut, SE_SPLIT_DEG_ROUND_MIN, &ihou, &imin, &isec, &dfrc, &isgn);
3439
+ sprintf(sout, "\"%04d%s %02d %02d %02d.%02d %d\",\n", jyear, sgj, jmon, jday, ihou, imin, ecl_type);
3440
+ }
3441
+ /*printf("len=%ld\n", strlen(sout));*/
3442
+ if (short_output) {
3443
+ do_printf(sout_short);
3444
+ } else {
3445
+ if (have_gap_parameter) insert_gap_string_for_tabs(sout, gap);
3446
+ do_printf(sout);
3447
+ }
3448
+ if (with_chart_link) {
3449
+ char snat[2 * AS_MAXCH];
3450
+ char stim[80];
3451
+ int iflg = 0; // NAT_IFLG_UNKNOWN_TIME;
3452
+ char cal = gregflag ? 'g' : 'j';
3453
+ format_lon_lat(slon, slat, geopos_max[0], geopos_max[1]);
3454
+ strcpy(stim, hms(jut,BIT_LZEROES));
3455
+ while (*stim == ' ') our_strcpy(stim, stim + 1);
3456
+ if (*stim == '0') our_strcpy(stim, stim + 1);
3457
+ sprintf(snat, "Solar Eclipse %s,%s,e,%d,%d,%d,%s,h0e,%cnu,%d,Location of Maximum,,%s,%s,u,0,0,0", saros, styp, jday, jmon, jyear, stim, cal, iflg, slon, slat);
3458
+ sprintf(sout, "<a href='https://www.astro.com/cgi/chart.cgi?muasp=1;nhor=1;act=chmnat;nd1=%s;rs=1;iseclipse=1;topo=1' target='eclipse'>chart link</a>\n\n", snat);
3459
+ do_printf(sout);
3460
+ }
3461
+ }
3462
+ }
3463
+ if (with_chart_link) do_printf("</pre>\n");
3464
+ return OK;
3465
+ }
3466
+
3467
+ static int32 call_lunar_occultation(double t_ut, int32 ipl, char *star, int32 whicheph, int32 special_mode, double *geopos, char *serr)
3468
+ {
3469
+ int i, ii, ecl_type = 0, eclflag, retc = OK;
3470
+ double dt, tret[30], attr[30], geopos_max[3];
3471
+ char s1[AS_MAXCH], s2[AS_MAXCH];
3472
+ AS_BOOL has_found = FALSE;
3473
+ int nloops = 0;
3474
+ /* no selective eclipse type set, set all */
3475
+ if ((search_flag & SE_ECL_ALLTYPES_SOLAR) == 0)
3476
+ search_flag |= SE_ECL_ALLTYPES_SOLAR;
3477
+ /* for local occultations: set geographic position of observer */
3478
+ if (special_mode & SP_MODE_LOCAL) {
3479
+ swe_set_topo(geopos[0], geopos[1], geopos[2]);
3480
+ if (with_header)
3481
+ printf("\ngeo. long %f, lat %f, alt %f", geopos[0], geopos[1], geopos[2]);
3482
+ }
3483
+ do_printf("\n");
3484
+ for (ii = 0; ii < nstep; ii++) {
3485
+ *sout = '\0';
3486
+ nloops++;
3487
+ if (nloops > SEARCH_RANGE_LUNAR_CYCLES) {
3488
+ sprintf(serr, "event search ended after %d lunar cycles at jd=%f\n", SEARCH_RANGE_LUNAR_CYCLES, t_ut);
3489
+ do_printf(serr);
3490
+ return ERR;
3491
+ }
3492
+ if (special_mode & SP_MODE_LOCAL) {
3493
+ /* * local search for occultation, test one lunar cycle only (SE_ECL_ONE_TRY) */
3494
+ if (ipl != SE_SUN) {
3495
+ search_flag &= ~(SE_ECL_ANNULAR|SE_ECL_ANNULAR_TOTAL);
3496
+ if (search_flag == 0)
3497
+ search_flag = SE_ECL_ALLTYPES_SOLAR;
3498
+ }
3499
+ if ((eclflag = swe_lun_occult_when_loc(t_ut, ipl, star, whicheph, geopos, tret, attr, direction_flag|SE_ECL_ONE_TRY, serr)) == ERR) {
3500
+ do_printf(serr);
3501
+ return ERR;
3502
+ } else if (eclflag == 0) { /* event not found, try next conjunction */
3503
+ t_ut = tret[0] + direction * 10; /* try again with start date increased by 10 */
3504
+ ii--;
3505
+ } else {
3506
+ t_ut = tret[0];
3507
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3508
+ for (i = 0; i < 10; i++) {
3509
+ if (tret[i] != 0) {
3510
+ retc = ut_to_lmt_lat(tret[i], geopos, &(tret[i]), serr);
3511
+ if (retc == ERR) {
3512
+ do_printf(serr);
3513
+ return ERR;
3514
+ }
3515
+ }
3516
+ }
3517
+ }
3518
+ has_found = FALSE;
3519
+ *sout = '\0';
3520
+ if ((search_flag & SE_ECL_TOTAL) && (eclflag & SE_ECL_TOTAL)) {
3521
+ strcat(sout, "total");
3522
+ has_found = TRUE;
3523
+ ecl_type = ECL_SOL_TOTAL;
3524
+ }
3525
+ if ((search_flag & SE_ECL_ANNULAR) && (eclflag & SE_ECL_ANNULAR)) {
3526
+ strcat(sout, "annular");
3527
+ has_found = TRUE;
3528
+ ecl_type = ECL_SOL_ANNULAR;
3529
+ }
3530
+ if ((search_flag & SE_ECL_PARTIAL) && (eclflag & SE_ECL_PARTIAL)) {
3531
+ strcat(sout, "partial");
3532
+ has_found = TRUE;
3533
+ ecl_type = ECL_SOL_PARTIAL;
3534
+ }
3535
+ if (ipl != SE_SUN) {
3536
+ if ((eclflag & SE_ECL_OCC_BEG_DAYLIGHT) && (eclflag & SE_ECL_OCC_END_DAYLIGHT))
3537
+ strcat(sout, "(daytime)"); /* occultation occurs during the day */
3538
+ else if (eclflag & SE_ECL_OCC_BEG_DAYLIGHT)
3539
+ strcat(sout, "(sunset) "); /* occultation occurs during the day */
3540
+ else if (eclflag & SE_ECL_OCC_END_DAYLIGHT)
3541
+ strcat(sout, "(sunrise)"); /* occultation occurs during the day */
3542
+ }
3543
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3544
+ while (strlen(sout) < 17)
3545
+ strcat(sout, " ");
3546
+ if (!has_found) {
3547
+ ii--;
3548
+ } else {
3549
+ swe_calc_ut(t_ut, SE_ECL_NUT, 0, x, serr);
3550
+ swe_revjul(tret[0], gregflag, &jyear, &jmon, &jday, &jut);
3551
+ dt = (tret[3] - tret[2]) * 24 * 60;
3552
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d\t%s\t%f\t%.6f\n", jday, jmon, jyear, hms(jut,BIT_LZEROES), attr[0], tret[0]);
3553
+ sprintf(sout + strlen(sout), "\t%d min %4.2f sec\t", (int) dt, fmod(dt, 1) * 60);
3554
+ if (eclflag & SE_ECL_1ST_VISIBLE)
3555
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[1]));
3556
+ else
3557
+ strcat(sout, " - ");
3558
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3559
+ if (eclflag & SE_ECL_2ND_VISIBLE)
3560
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[2]));
3561
+ else
3562
+ strcat(sout, " - ");
3563
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3564
+ if (eclflag & SE_ECL_3RD_VISIBLE)
3565
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[3]));
3566
+ else
3567
+ strcat(sout, " - ");
3568
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3569
+ if (eclflag & SE_ECL_4TH_VISIBLE)
3570
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
3571
+ else
3572
+ strcat(sout, " - ");
3573
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3574
+ #if 0
3575
+ sprintf(sout + strlen(sout), "\t%d min %4.2f sec %s %s %s %s",
3576
+ (int) dt, fmod(dt, 1) * 60,
3577
+ strcpy(s1, hms(fmod(tret[1] + 0.5, 1) * 24, BIT_LZEROES)),
3578
+ strcpy(s3, hms(fmod(tret[2] + 0.5, 1) * 24, BIT_LZEROES)),
3579
+ strcpy(s4, hms(fmod(tret[3] + 0.5, 1) * 24, BIT_LZEROES)),
3580
+ strcpy(s2, hms(fmod(tret[4] + 0.5, 1) * 24, BIT_LZEROES)));
3581
+ #endif
3582
+ sprintf(sout + strlen(sout), "dt=%.1f", swe_deltat_ex(tret[0], whicheph, serr) * 86400.0);
3583
+ strcat(sout, "\n");
3584
+ if (have_gap_parameter) insert_gap_string_for_tabs(sout, gap);
3585
+ do_printf(sout);
3586
+ }
3587
+ }
3588
+ } /* endif search_local */
3589
+ if (!(special_mode & SP_MODE_LOCAL)) {
3590
+ /* * global search for occultations, test one lunar cycle only (SE_ECL_ONE_TRY) */
3591
+ if ((eclflag = swe_lun_occult_when_glob(t_ut, ipl, star, whicheph, search_flag, tret, direction_flag|SE_ECL_ONE_TRY, serr)) == ERR) {
3592
+ do_printf(serr);
3593
+ return ERR;
3594
+ }
3595
+ if (eclflag == 0) { /* no occltation was found at next conjunction, try next conjunction */
3596
+ t_ut = tret[0] + direction;
3597
+ ii--;
3598
+ continue;
3599
+ }
3600
+ if ((eclflag & SE_ECL_TOTAL)) {
3601
+ strcpy(sout, "total ");
3602
+ ecl_type = ECL_SOL_TOTAL;
3603
+ }
3604
+ if ((eclflag & SE_ECL_ANNULAR)) {
3605
+ strcpy(sout, "annular ");
3606
+ ecl_type = ECL_SOL_ANNULAR;
3607
+ }
3608
+ if ((eclflag & SE_ECL_ANNULAR_TOTAL)) {
3609
+ strcpy(sout, "ann-tot ");
3610
+ ecl_type = ECL_SOL_ANNULAR; /* by Alois: what is this ? */
3611
+ }
3612
+ if ((eclflag & SE_ECL_PARTIAL)) {
3613
+ strcpy(sout, "partial ");
3614
+ ecl_type = ECL_SOL_PARTIAL;
3615
+ }
3616
+ if ((eclflag & SE_ECL_NONCENTRAL) && !(eclflag & SE_ECL_PARTIAL))
3617
+ strcat(sout, "non-central ");
3618
+ t_ut = tret[0];
3619
+ swe_lun_occult_where(t_ut, ipl, star, whicheph, geopos_max, attr, serr);
3620
+ /* for (i = 0; i < 8; i++) {
3621
+ printf("attr[%d]=%.17f\n", i, attr[i]);
3622
+ } */
3623
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3624
+ for (i = 0; i < 10; i++) {
3625
+ if (tret[i] != 0) {
3626
+ retc = ut_to_lmt_lat(tret[i], geopos, &(tret[i]), serr);
3627
+ if (retc == ERR) {
3628
+ do_printf(serr);
3629
+ return ERR;
3630
+ }
3631
+ }
3632
+ }
3633
+ }
3634
+ swe_revjul(tret[0], gregflag, &jyear, &jmon, &jday, &jut);
3635
+ sprintf(sout + strlen(sout), "%2d.%02d.%04d\t%s\t%f km\t%f\t%.6f\n", jday, jmon, jyear, hms(jut,BIT_LZEROES), attr[3], attr[0], tret[0]);
3636
+ sprintf(sout + strlen(sout), "\t%s ", hms_from_tjd(tret[2]));
3637
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3638
+ if (tret[4] != 0)
3639
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[4]));
3640
+ else
3641
+ strcat(sout, " - ");
3642
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3643
+ if (tret[5] != 0)
3644
+ sprintf(sout + strlen(sout), "%s ", hms_from_tjd(tret[5]));
3645
+ else
3646
+ strcat(sout, " - ");
3647
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3648
+ sprintf(sout + strlen(sout), "%s", hms_from_tjd(tret[3]));
3649
+ if (have_gap_parameter) sprintf(sout + strlen(sout), "\t");
3650
+ sprintf(sout + strlen(sout), "dt=%.1f", swe_deltat_ex(tret[0], whicheph, serr) * 86400.0);
3651
+ strcat(sout, "\n");
3652
+ sprintf(sout + strlen(sout), "\t%s\t%s", strcpy(s1, dms(geopos_max[0], BIT_ROUND_MIN)), strcpy(s2, dms(geopos_max[1], BIT_ROUND_MIN)));
3653
+ if (!(eclflag & SE_ECL_PARTIAL) && !(eclflag & SE_ECL_NONCENTRAL)) {
3654
+ if ((eclflag = swe_lun_occult_when_loc(t_ut - 10, ipl, star, whicheph, geopos_max, tret, attr, 0, serr)) == ERR) {
3655
+ do_printf(serr);
3656
+ return ERR;
3657
+ }
3658
+ if (fabs(tret[0] - t_ut) > 2)
3659
+ do_printf("when_loc returns wrong date\n");
3660
+ dt = (tret[3] - tret[2]) * 24 * 60;
3661
+ sprintf(sout + strlen(sout), "\t%d min %4.2f sec", (int) dt, fmod(dt, 1) * 60);
3662
+ }
3663
+ strcat(sout, "\n");
3664
+ if (have_gap_parameter) insert_gap_string_for_tabs(sout, gap);
3665
+ if (special_mode & SP_MODE_HOCAL) {
3666
+ int ihou, imin, isec, isgn;
3667
+ double dfrc;
3668
+ swe_split_deg(jut, SE_SPLIT_DEG_ROUND_MIN, &ihou, &imin, &isec, &dfrc, &isgn);
3669
+ sprintf(sout, "\"%04d %02d %02d %02d.%02d %d\",\n", jyear, jmon, jday, ihou, imin, ecl_type);
3670
+ }
3671
+ do_printf(sout);
3672
+ }
3673
+ t_ut += direction;
3674
+ }
3675
+ return OK;
3676
+ }
3677
+
3678
+ static void do_print_heliacal(double *dret, int32 event_type, char *obj_name)
3679
+ {
3680
+ char *sevtname[] = {"",
3681
+ "heliacal rising ",
3682
+ "heliacal setting",
3683
+ "evening first ",
3684
+ "morning last ",
3685
+ "evening rising ",
3686
+ "morning setting ",};
3687
+ char *stz = "UT";
3688
+ char stim0[40], stim1[40], stim2[40];
3689
+ if (time_flag & BIT_TIME_LMT)
3690
+ stz = "LMT";
3691
+ if (time_flag & BIT_TIME_LAT)
3692
+ stz = "LAT";
3693
+ *sout = '\0';
3694
+ swe_revjul(dret[0], gregflag, &jyear, &jmon, &jday, &jut);
3695
+ if (event_type <= 4) {
3696
+ if (hel_using_AV) {
3697
+ strcpy(stim0, hms_from_tjd(dret[0]));
3698
+ remove_whitespace(stim0);
3699
+ /* The following line displays only the beginning of visibility. */
3700
+ sprintf(sout + strlen(sout), "%s %s: %d/%02d/%02d %s %s (%.5f)\n", obj_name, sevtname[event_type], jyear, jmon, jday, stim0, stz, dret[0]);
3701
+ } else {
3702
+ /* display the moment of beginning and optimum visibility */
3703
+ strcpy(stim0, hms_from_tjd(dret[0]));
3704
+ strcpy(stim1, hms_from_tjd(dret[1]));
3705
+ strcpy(stim2, hms_from_tjd(dret[2]));
3706
+ remove_whitespace(stim0);
3707
+ remove_whitespace(stim1);
3708
+ remove_whitespace(stim2);
3709
+ sprintf(sout + strlen(sout), "%s %s: %d/%02d/%02d %s %s (%.5f), opt %s, end %s, dur %.1f min\n", obj_name, sevtname[event_type], jyear, jmon, jday, stim0, stz, dret[0], stim1, stim2, (dret[2] - dret[0]) * 1440);
3710
+ }
3711
+ } else {
3712
+ strcpy(stim0, hms_from_tjd(dret[0]));
3713
+ remove_whitespace(stim0);
3714
+ sprintf(sout + strlen(sout), "%s %s: %d/%02d/%02d %s %s (%f)\n", obj_name, sevtname[event_type], jyear, jmon, jday, stim0, stz, dret[0]);
3715
+ }
3716
+ do_printf(sout);
3717
+ }
3718
+
3719
+ static int32 call_heliacal_event(double t_ut, int32 ipl, char *star, int32 whicheph, double *geopos, double *datm, double *dobs, char *serr)
3720
+ {
3721
+ int ii, retc = OK, event_type = 0, retflag;
3722
+ double dret[40], tsave1, tsave2 = 0;
3723
+ char obj_name[AS_MAXCH];
3724
+ helflag |= whicheph;
3725
+ /* if invalid heliacal event type was required, set 0 for any type */
3726
+ if (search_flag < 0 || search_flag > 6)
3727
+ search_flag = 0;
3728
+ /* optical instruments used: */
3729
+ if (dobs[3] > 0)
3730
+ helflag |= SE_HELFLAG_OPTICAL_PARAMS;
3731
+ if (hel_using_AV)
3732
+ helflag |= SE_HELFLAG_AV;
3733
+ if (ipl == SE_FIXSTAR) {
3734
+ strcpy(obj_name, star);
3735
+ } else {
3736
+ swe_get_planet_name(ipl, obj_name);
3737
+ }
3738
+ if (with_header) {
3739
+ printf("\ngeo. long %f, lat %f, alt %f", geopos[0], geopos[1], geopos[2]);
3740
+ do_printf("\n");
3741
+ }
3742
+ for (ii = 0; ii < nstep; ii++, t_ut = dret[0] + 1) {
3743
+ *sout = '\0';
3744
+ if (search_flag > 0)
3745
+ event_type = search_flag;
3746
+ else if (ipl == SE_MOON)
3747
+ event_type = SE_EVENING_FIRST;
3748
+ else
3749
+ event_type = SE_HELIACAL_RISING;
3750
+ retflag = swe_heliacal_ut(t_ut, geopos, datm, dobs, obj_name, event_type, helflag, dret, serr);
3751
+ if (retflag == ERR) {
3752
+ do_printf(serr);
3753
+ return ERR;
3754
+ }
3755
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3756
+ retc = ut_to_lmt_lat(dret[0], geopos, &(dret[0]), serr);
3757
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[1], geopos, &(dret[1]), serr);
3758
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[2], geopos, &(dret[2]), serr);
3759
+ if (retc == ERR) {
3760
+ do_printf(serr);
3761
+ return ERR;
3762
+ }
3763
+ }
3764
+ do_print_heliacal(dret, event_type, obj_name);
3765
+ /* list all events within synodic cycle */
3766
+ if (search_flag == 0) {
3767
+ if (ipl == SE_VENUS || ipl == SE_MERCURY) {
3768
+ /* we have heliacal rising (morning first), now find morning last */
3769
+ event_type = SE_MORNING_LAST;
3770
+ retflag = swe_heliacal_ut(dret[0], geopos, datm, dobs, obj_name, event_type, helflag, dret, serr);
3771
+ if (retflag == ERR) {
3772
+ do_printf(serr);
3773
+ return ERR;
3774
+ }
3775
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3776
+ retc = ut_to_lmt_lat(dret[0], geopos, &(dret[0]), serr);
3777
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[1], geopos, &(dret[1]), serr);
3778
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[2], geopos, &(dret[2]), serr);
3779
+ if (retc == ERR) {
3780
+ do_printf(serr);
3781
+ return ERR;
3782
+ }
3783
+ }
3784
+ do_print_heliacal(dret, event_type, obj_name);
3785
+ tsave1 = dret[0];
3786
+ /* mercury can have several evening appearances without any morning
3787
+ * appearances in betweeen. We have to find out when the next
3788
+ * morning appearance is and then find all evening appearances
3789
+ * that take place before that */
3790
+ if (ipl == SE_MERCURY) {
3791
+ event_type = SE_HELIACAL_RISING;
3792
+ retflag = swe_heliacal_ut(dret[0], geopos, datm, dobs, obj_name, event_type, helflag, dret, serr);
3793
+ if (retflag == ERR) {
3794
+ do_printf(serr);
3795
+ return ERR;
3796
+ }
3797
+ tsave2 = dret[0];
3798
+ }
3799
+ repeat_mercury:
3800
+ /* evening first */
3801
+ event_type = SE_EVENING_FIRST;
3802
+ retflag = swe_heliacal_ut(tsave1, geopos, datm, dobs, obj_name, event_type, helflag, dret, serr);
3803
+ if (retflag == ERR) {
3804
+ do_printf(serr);
3805
+ return ERR;
3806
+ }
3807
+ if (ipl == SE_MERCURY && dret[0] > tsave2)
3808
+ continue;
3809
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3810
+ retc = ut_to_lmt_lat(dret[0], geopos, &(dret[0]), serr);
3811
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[1], geopos, &(dret[1]), serr);
3812
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[2], geopos, &(dret[2]), serr);
3813
+ if (retc == ERR) {
3814
+ do_printf(serr);
3815
+ return ERR;
3816
+ }
3817
+ }
3818
+ do_print_heliacal(dret, event_type, obj_name);
3819
+ }
3820
+ if (ipl == SE_MOON) {
3821
+ /* morning last */
3822
+ event_type = SE_MORNING_LAST;
3823
+ retflag = swe_heliacal_ut(dret[0], geopos, datm, dobs, obj_name, event_type, helflag, dret, serr);
3824
+ if (retflag == ERR) {
3825
+ do_printf(serr);
3826
+ return ERR;
3827
+ }
3828
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3829
+ retc = ut_to_lmt_lat(dret[0], geopos, &(dret[0]), serr);
3830
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[1], geopos, &(dret[1]), serr);
3831
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[2], geopos, &(dret[2]), serr);
3832
+ if (retc == ERR) {
3833
+ do_printf(serr);
3834
+ return ERR;
3835
+ }
3836
+ }
3837
+ do_print_heliacal(dret, event_type, obj_name);
3838
+ } else {
3839
+ /* heliacal setting (evening last) */
3840
+ event_type = SE_HELIACAL_SETTING;
3841
+ retflag = swe_heliacal_ut(dret[0], geopos, datm, dobs, obj_name, event_type, helflag, dret, serr);
3842
+ if (retflag == ERR) {
3843
+ do_printf(serr);
3844
+ return ERR;
3845
+ }
3846
+ if (time_flag & (BIT_TIME_LMT | BIT_TIME_LAT)) {
3847
+ retc = ut_to_lmt_lat(dret[0], geopos, &(dret[0]), serr);
3848
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[1], geopos, &(dret[1]), serr);
3849
+ if (retc != ERR) retc = ut_to_lmt_lat(dret[2], geopos, &(dret[2]), serr);
3850
+ if (retc == ERR) {
3851
+ do_printf(serr);
3852
+ return ERR;
3853
+ }
3854
+ }
3855
+ do_print_heliacal(dret, event_type, obj_name);
3856
+ if ((0) && ipl == SE_MERCURY) {
3857
+ tsave1 = dret[0];
3858
+ goto repeat_mercury;
3859
+ }
3860
+ }
3861
+ }
3862
+ }
3863
+ return OK;
3864
+ }
3865
+
3866
+ static int do_special_event(double tjd, int32 ipl, char *star, int32 special_event, int32 special_mode, double *geopos, double *datm, double *dobs, char *serr)
3867
+ {
3868
+ int retc = 0;
3869
+ /* risings, settings, meridian transits */
3870
+ if (special_event == SP_RISE_SET ||
3871
+ special_event == SP_MERIDIAN_TRANSIT)
3872
+ retc = call_rise_set(tjd, ipl, star, whicheph, geopos, serr);
3873
+ /* lunar eclipses */
3874
+ if (special_event == SP_LUNAR_ECLIPSE)
3875
+ retc = call_lunar_eclipse(tjd, whicheph, special_mode, geopos, serr);
3876
+ /* solar eclipses */
3877
+ if (special_event == SP_SOLAR_ECLIPSE)
3878
+ retc = call_solar_eclipse(tjd, whicheph, special_mode, geopos, serr);
3879
+ /* occultations by the moon */
3880
+ if (special_event == SP_OCCULTATION)
3881
+ retc = call_lunar_occultation(tjd, ipl, star, whicheph, special_mode, geopos, serr);
3882
+ /* heliacal event */
3883
+ if (special_event == SP_HELIACAL)
3884
+ retc = call_heliacal_event(tjd, ipl, star, whicheph, geopos, datm, dobs, serr);
3885
+ return retc;
3886
+ }
3887
+
3888
+ static char *hms_from_tjd(double tjd)
3889
+ {
3890
+ static char s[AS_MAXCH];
3891
+ double x;
3892
+ /* tjd may be negative, 0h corresponds to day number 9999999.5 */
3893
+ x = fmod(tjd, 1); /* may be negative ! */
3894
+ x = fmod(x + 1.5, 1); /* is positive day fraction */
3895
+ sprintf(s, "%s ", hms(x * 24, BIT_LZEROES));
3896
+ return s;
3897
+ }
3898
+
3899
+ static char *hms(double x, int32 iflag)
3900
+ {
3901
+ static char s[AS_MAXCH], s2[AS_MAXCH], *sp;
3902
+ char *c = ODEGREE_STRING;
3903
+ x += 0.5 / 36000.0; /* round to 0.1 sec */
3904
+ strcpy(s, dms(x, iflag));
3905
+ sp = strstr(s, c);
3906
+ if (sp != NULL) {
3907
+ *sp = ':';
3908
+ strcpy(s2, sp + strlen(ODEGREE_STRING));
3909
+ strcpy(sp + 1, s2);
3910
+ *(sp + 3) = ':';
3911
+ *(sp + 8) = '\0';
3912
+ }
3913
+ return s;
3914
+ }
3915
+
3916
+ static void do_printf(char *info)
3917
+ {
3918
+ #ifdef _WINDOWS
3919
+ fprintf(fp, info);
3920
+ #else
3921
+ fputs(info,stdout);
3922
+ #endif
3923
+ }
3924
+
3925
+ /* make_ephemeris_path().
3926
+ * ephemeris path includes
3927
+ * current working directory
3928
+ * + program directory
3929
+ * + default path from swephexp.h on current drive
3930
+ * + on program drive
3931
+ * + on drive C:
3932
+ */
3933
+ static int make_ephemeris_path(char *argv0, char *path)
3934
+ {
3935
+ char *sp;
3936
+ char *dirglue = DIR_GLUE;
3937
+ size_t pathlen = 0;
3938
+ /* current working directory */
3939
+ sprintf(path, ".%c", *PATH_SEPARATOR);
3940
+ /* program directory */
3941
+ sp = strrchr(argv0, *dirglue);
3942
+ if (sp != NULL) {
3943
+ pathlen = sp - argv0;
3944
+ if (strlen(path) + pathlen < AS_MAXCH-2) {
3945
+ strncat(path, argv0, pathlen);
3946
+ sprintf(path + strlen(path), "%c", *PATH_SEPARATOR);
3947
+ }
3948
+ }
3949
+ #if MSDOS
3950
+ {
3951
+ char *cpos[20];
3952
+ char s[2 * AS_MAXCH], *s1 = s + AS_MAXCH;
3953
+ char *sp[3];
3954
+ int i, j, np;
3955
+ strcpy(s1, SE_EPHE_PATH);
3956
+ np = cut_str_any(s1, PATH_SEPARATOR, cpos, 20);
3957
+ /*
3958
+ * default path from swephexp.h
3959
+ * - current drive
3960
+ * - program drive
3961
+ * - drive C
3962
+ */
3963
+ *s = '\0';
3964
+ /* current working drive */
3965
+ sp[0] = getcwd(NULL, 0);
3966
+ if (sp[0] == NULL) {
3967
+ printf("error in getcwd()\n");
3968
+ exit(1);
3969
+ }
3970
+ if (*sp[0] == 'C')
3971
+ sp[0] = NULL;
3972
+ /* program drive */
3973
+ if (*argv0 != 'C' && (sp[0] == NULL || *sp[0] != *argv0))
3974
+ sp[1] = argv0;
3975
+ else
3976
+ sp[1] = NULL;
3977
+ /* drive C */
3978
+ sp[2] = "C";
3979
+ for (i = 0; i < np; i++) {
3980
+ strcpy(s, cpos[i]);
3981
+ if (*s == '.') /* current directory */
3982
+ continue;
3983
+ if (s[1] == ':') /* drive already there */
3984
+ continue;
3985
+ for (j = 0; j < 3; j++) {
3986
+ if (sp[j] != NULL && strlen(path) + 2 + strlen(s) < AS_MAXCH-1) {
3987
+ sprintf(path + strlen(path), "%c:%s%c", *sp[j], s, *PATH_SEPARATOR);
3988
+ }
3989
+ }
3990
+ }
3991
+ }
3992
+ #else
3993
+ if (strlen(path) + strlen(SE_EPHE_PATH) < AS_MAXCH-1)
3994
+ strcat(path, SE_EPHE_PATH);
3995
+ #endif
3996
+ return OK;
3997
+ }
3998
+
3999
+ static void remove_whitespace(char *s)
4000
+ {
4001
+ char *sp, s1[AS_MAXCH];
4002
+ if (s == NULL) return;
4003
+ for (sp = s; *sp == ' '; sp++)
4004
+ ;
4005
+ strcpy(s1, sp);
4006
+ while (*(sp = s1 + strlen(s1) - 1) == ' ')
4007
+ *sp = '\0';
4008
+ strcpy(s, s1);
4009
+ }
4010
+
4011
+ static void jd_to_time_string(double jut, char *stimeout)
4012
+ {
4013
+ double t2;
4014
+ t2 = jut + 0.5 / 3600000.0; // rounding to millisec
4015
+ sprintf(stimeout, " % 2d:", (int) t2); // hour
4016
+ t2 = (t2 - (int32) t2) * 60;
4017
+ sprintf(stimeout + strlen(stimeout), "%02d:", (int) t2); // min
4018
+ t2 = (t2 - (int32) t2) * 60;
4019
+ sprintf(stimeout + strlen(stimeout), "%02d", (int) t2); // sec
4020
+ t2 = (t2 - (int32) t2) * 1000;
4021
+ if ((int32) t2 > 0) {
4022
+ sprintf(stimeout + strlen(stimeout), ".%03d", (int) t2); // millisec, if > 0
4023
+ }
4024
+ }
4025
+
4026
+ #if MSDOS
4027
+ /**************************************************************
4028
+ cut the string s at any char in cutlist; put pointers to partial strings
4029
+ into cpos[0..n-1], return number of partial strings;
4030
+ if less than nmax fields are found, the first empty pointer is
4031
+ set to NULL.
4032
+ More than one character of cutlist in direct sequence count as one
4033
+ separator only! cut_str_any("word,,,word2",","..) cuts only two parts,
4034
+ cpos[0] = "word" and cpos[1] = "word2".
4035
+ If more than nmax fields are found, nmax is returned and the
4036
+ last field nmax-1 rmains un-cut.
4037
+ **************************************************************/
4038
+ static int cut_str_any(char *s, char *cutlist, char *cpos[], int nmax)
4039
+ {
4040
+ int n = 1;
4041
+ cpos [0] = s;
4042
+ while (*s != '\0') {
4043
+ if ((strchr(cutlist, (int) *s) != NULL) && n < nmax) {
4044
+ *s = '\0';
4045
+ while (*(s + 1) != '\0' && strchr (cutlist, (int) *(s + 1)) != NULL) s++;
4046
+ cpos[n++] = s + 1;
4047
+ }
4048
+ if (*s == '\n' || *s == '\r') { /* treat nl or cr like end of string */
4049
+ *s = '\0';
4050
+ break;
4051
+ }
4052
+ s++;
4053
+ }
4054
+ if (n < nmax) cpos[n] = NULL;
4055
+ return (n);
4056
+ } /* cutstr */
4057
+ #endif
4058
+
4059
+ static char *our_strcpy(char *to, char *from)
4060
+ {
4061
+ char *sp, s[AS_MAXCH];
4062
+ if (*from == '\0') {
4063
+ *to = '\0';
4064
+ return to;
4065
+ }
4066
+ if (strlen(from) < AS_MAXCH) {
4067
+ strcpy(s, from);
4068
+ strcpy(to, s);
4069
+ } else {
4070
+ sp = strdup(from);
4071
+ if (sp == NULL) {
4072
+ strcpy(to, from);
4073
+ } else {
4074
+ strcpy(to, sp);
4075
+ free(sp);
4076
+ }
4077
+ }
4078
+ return to;
4079
+ }