slatec-internal.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. // FIXME patch the i/o functions.
  2. // FIXME remove all remaining flag-first-init type patterns in the routines.
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <cmath>
  7. #include "slatec.hpp"
  8. #include "mach.hpp"
  9. using integer = int;
  10. using logical = int;
  11. using ftnlen = int;
  12. using ftnint = int;
  13. using flag = int;
  14. using address = char *;
  15. constexpr logical TRUE_ = 1;
  16. constexpr logical FALSE_ = 0;
  17. /*internal read, write*/
  18. struct icilist
  19. {
  20. flag icierr;
  21. char *iciunit;
  22. flag iciend;
  23. char const *icifmt;
  24. ftnint icirlen;
  25. ftnint icirnum;
  26. };
  27. /*external read, write*/
  28. struct cilist
  29. {
  30. flag cierr;
  31. ftnint ciunit;
  32. flag ciend;
  33. char const *cifmt;
  34. ftnint cirec;
  35. };
  36. using std::log, std::sqrt, std::exp, std::sin, std::cos, std::sinh, std::cosh,
  37. std::abs, std::atan, std::min, std::max;
  38. namespace f2c {
  39. inline double d_sign(double const *a, double const *b)
  40. {
  41. double x;
  42. x = (*a >= 0 ? *a : - *a);
  43. return (*b >= 0 ? x : -x);
  44. }
  45. inline double d_int(double const *x)
  46. {
  47. return( (*x>0) ? floor(*x) : -floor(- *x) );
  48. }
  49. inline integer do_fio(integer const *, char const *, ftnlen)
  50. {
  51. return 0; // FIXME from fmt.c, but replace
  52. }
  53. inline integer e_wsfe() // write sequential formatted external??
  54. {
  55. return 0;
  56. }
  57. inline integer e_wsfi() // internal I guess
  58. {
  59. return 0;
  60. }
  61. inline integer s_wsfe(cilist *)
  62. {
  63. return 0;
  64. }
  65. inline integer s_wsfi(icilist *)
  66. {
  67. return 0;
  68. }
  69. inline integer i_len(char const *s, ftnlen const n)
  70. {
  71. return (n);
  72. }
  73. inline integer i_indx(char const *a, char const *b, ftnlen const la, ftnlen const lb)
  74. {
  75. ftnlen i, n;
  76. char const *s;
  77. char const *t;
  78. char const *bend;
  79. n = la - lb + 1;
  80. bend = b + lb;
  81. for (i = 0 ; i < n ; ++i) {
  82. s = a + i;
  83. t = b;
  84. while(t < bend)
  85. if(*s++ != *t++)
  86. goto no;
  87. return(i+1);
  88. no: ;
  89. }
  90. return(0);
  91. }
  92. /* Unless compiled with -DNO_OVERWRITE, this variant of s_copy allows the
  93. * target of an assignment to appear on its right-hand side (contrary
  94. * to the Fortran 77 Standard, but in accordance with Fortran 90),
  95. * as in a(2:5) = a(4:7) .
  96. */
  97. /* assign strings: a = b */
  98. inline void s_copy(char *a, char const *b, ftnlen const la, ftnlen const lb)
  99. {
  100. char *aend;
  101. char const *bend;
  102. aend = a + la;
  103. if(la <= lb)
  104. #ifndef NO_OVERWRITE
  105. if (a <= b || a >= b + la)
  106. #endif
  107. while(a < aend)
  108. *a++ = *b++;
  109. #ifndef NO_OVERWRITE
  110. else
  111. for(b += la; a < aend; )
  112. *--aend = *--b;
  113. #endif
  114. else {
  115. bend = b + lb;
  116. #ifndef NO_OVERWRITE
  117. if (a <= b || a >= bend)
  118. #endif
  119. while(b < bend)
  120. *a++ = *b++;
  121. #ifndef NO_OVERWRITE
  122. else {
  123. a += lb;
  124. while(b < bend)
  125. *--a = *--bend;
  126. a += lb;
  127. }
  128. #endif
  129. while(a < aend)
  130. *a++ = ' ';
  131. }
  132. }
  133. inline integer s_cmp(char const *a0, char const *b0, ftnlen const la, ftnlen const lb)
  134. {
  135. unsigned char *a, *aend, *b, *bend;
  136. a = (unsigned char *)a0;
  137. b = (unsigned char *)b0;
  138. aend = a + la;
  139. bend = b + lb;
  140. if(la <= lb)
  141. {
  142. while(a < aend)
  143. if(*a != *b)
  144. return( *a - *b );
  145. else
  146. { ++a; ++b; }
  147. while(b < bend)
  148. if(*b != ' ')
  149. return( ' ' - *b );
  150. else ++b;
  151. }
  152. else
  153. {
  154. while(b < bend)
  155. if(*a == *b)
  156. { ++a; ++b; }
  157. else
  158. return( *a - *b );
  159. while(a < aend)
  160. if(*a != ' ')
  161. return(*a - ' ');
  162. else ++a;
  163. }
  164. return(0);
  165. }
  166. inline char *
  167. F77_aloc(integer const Len, char const *whence)
  168. {
  169. char *rv;
  170. unsigned int uLen = (unsigned int) Len; /* for K&R C */
  171. if (!(rv = (char*)malloc(uLen))) {
  172. fprintf(stderr, "malloc(%u) failure in %s\n", uLen, whence);
  173. std::exit(3);
  174. }
  175. return rv;
  176. }
  177. inline void s_cat(char * lp, char *rpp[], ftnint const rnp[], ftnint const *np, ftnlen ll)
  178. {
  179. ftnlen i, nc;
  180. char const *rp;
  181. ftnlen n = *np;
  182. #ifndef NO_OVERWRITE
  183. ftnlen L, m;
  184. char *lp0, *lp1;
  185. lp0 = 0;
  186. lp1 = lp;
  187. L = ll;
  188. i = 0;
  189. while(i < n) {
  190. rp = rpp[i];
  191. m = rnp[i++];
  192. if (rp >= lp1 || rp + m <= lp) {
  193. if ((L -= m) <= 0) {
  194. n = i;
  195. break;
  196. }
  197. lp1 += m;
  198. continue;
  199. }
  200. lp0 = lp;
  201. lp = lp1 = F77_aloc(L = ll, "s_cat");
  202. break;
  203. }
  204. lp1 = lp;
  205. #endif /* NO_OVERWRITE */
  206. for(i = 0 ; i < n ; ++i) {
  207. nc = ll;
  208. if(rnp[i] < nc)
  209. nc = rnp[i];
  210. ll -= nc;
  211. rp = rpp[i];
  212. while(--nc >= 0)
  213. *lp++ = *rp++;
  214. }
  215. while(--ll >= 0)
  216. *lp++ = ' ';
  217. #ifndef NO_OVERWRITE
  218. if (lp0) {
  219. std::memcpy(lp0, lp1, L);
  220. free(lp1);
  221. }
  222. #endif
  223. }
  224. inline int s_stop(char const *s, ftnlen n)
  225. {
  226. int i;
  227. if(n > 0) {
  228. fprintf(stderr, "STOP ");
  229. for(i = 0; i<n ; ++i)
  230. putc(*s++, stderr);
  231. fprintf(stderr, " statement executed\n");
  232. }
  233. exit(0);
  234. /* We cannot avoid (useless) compiler diagnostics here: */
  235. /* some compilers complain if there is no return statement, */
  236. /* and others complain that this one cannot be reached. */
  237. return 0; /* NOT REACHED */
  238. }
  239. inline double pow_dd(double const *ap, double const *bp)
  240. {
  241. return(std::pow(*ap, *bp) );
  242. }
  243. inline double pow_di(double const *ap, integer const *bp)
  244. {
  245. double pow, x;
  246. integer n;
  247. unsigned long u;
  248. pow = 1;
  249. x = *ap;
  250. n = *bp;
  251. if(n != 0) {
  252. if(n < 0) {
  253. n = -n;
  254. x = 1/x;
  255. }
  256. for(u = n; ; ) {
  257. if(u & 01)
  258. pow *= x;
  259. if(u >>= 1)
  260. x *= x;
  261. else
  262. break;
  263. }
  264. }
  265. return(pow);
  266. }
  267. inline int i_dnnt(double const *x)
  268. {
  269. return (integer)(*x >= 0. ? floor(*x + .5) : -floor(.5 - *x));
  270. }
  271. } // namespace f2c
  272. extern "C" {
  273. int xercnt_(char *librar, char *subrou, char *messg, integer
  274. *nerr, integer *level, integer *kontrl, ftnlen librar_len, ftnlen
  275. subrou_len, ftnlen messg_len);
  276. int xerhlt_(char const *messg, ftnlen const messg_len);
  277. int xermsg_(char const *librar, char const *subrou, char const *messg,
  278. integer const *nerr, integer const *level,
  279. ftnlen const librar_len, ftnlen const subrou_len, ftnlen const messg_len);
  280. int xerprn_(char const *prefix, integer const *npref, char const *messg,
  281. integer const *nwrap, ftnlen prefix_len, ftnlen messg_len);
  282. int xersve_(char const *librar, char const *subrou, char const *messg, integer
  283. const *kflag, integer const *nerr, integer const *level, integer *icount, ftnlen
  284. librar_len, ftnlen subrou_len, ftnlen messg_len);
  285. int xgetua_(integer *iunita, integer *n);
  286. integer j4save_(integer const *iwhich, integer const *ivalue, logical const *iset);
  287. int fdump_();
  288. } // extern "C"