/combine_lwa_cmd.c

https://github.com/kstovall/psrfits_utils · C · 788 lines · 553 code · 128 blank · 107 comment · 126 complexity · 56511bdc4a278f62fe13db24b07444ec MD5 · raw file

  1. /*****
  2. command line parser -- generated by clig
  3. (http://wsd.iitb.fhg.de/~kir/clighome/)
  4. The command line parser `clig':
  5. (C) 1995-2004 Harald Kirsch (clig@geggus.net)
  6. *****/
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <errno.h>
  12. #include <limits.h>
  13. #include <float.h>
  14. #include <math.h>
  15. #include "combine_lwa_cmd.h"
  16. char *Program;
  17. /*@-null*/
  18. static Cmdline cmd = {
  19. /***** -o: Basename for the output files */
  20. /* outputbasenameP = */ 0,
  21. /* outputbasename = */ (char*)0,
  22. /* outputbasenameC = */ 0,
  23. /***** uninterpreted rest of command line */
  24. /* argc = */ 0,
  25. /* argv = */ (char**)0,
  26. /***** the original command line concatenated */
  27. /* full_cmd_line = */ NULL
  28. };
  29. /*@=null*/
  30. /***** let LCLint run more smoothly */
  31. /*@-predboolothers*/
  32. /*@-boolops*/
  33. /******************************************************************/
  34. /*****
  35. This is a bit tricky. We want to make a difference between overflow
  36. and underflow and we want to allow v==Inf or v==-Inf but not
  37. v>FLT_MAX.
  38. We don't use fabs to avoid linkage with -lm.
  39. *****/
  40. static void
  41. checkFloatConversion(double v, char *option, char *arg)
  42. {
  43. char *err = NULL;
  44. if( (errno==ERANGE && v!=0.0) /* even double overflowed */
  45. || (v<HUGE_VAL && v>-HUGE_VAL && (v<0.0?-v:v)>(double)FLT_MAX) ) {
  46. err = "large";
  47. } else if( (errno==ERANGE && v==0.0)
  48. || (v!=0.0 && (v<0.0?-v:v)<(double)FLT_MIN) ) {
  49. err = "small";
  50. }
  51. if( err ) {
  52. fprintf(stderr,
  53. "%s: parameter `%s' of option `%s' to %s to represent\n",
  54. Program, arg, option, err);
  55. exit(EXIT_FAILURE);
  56. }
  57. }
  58. int
  59. getIntOpt(int argc, char **argv, int i, int *value, int force)
  60. {
  61. char *end;
  62. long v;
  63. if( ++i>=argc ) goto nothingFound;
  64. errno = 0;
  65. v = strtol(argv[i], &end, 0);
  66. /***** check for conversion error */
  67. if( end==argv[i] ) goto nothingFound;
  68. /***** check for surplus non-whitespace */
  69. while( isspace((int) *end) ) end+=1;
  70. if( *end ) goto nothingFound;
  71. /***** check if it fits into an int */
  72. if( errno==ERANGE || v>(long)INT_MAX || v<(long)INT_MIN ) {
  73. fprintf(stderr,
  74. "%s: parameter `%s' of option `%s' to large to represent\n",
  75. Program, argv[i], argv[i-1]);
  76. exit(EXIT_FAILURE);
  77. }
  78. *value = (int)v;
  79. return i;
  80. nothingFound:
  81. if( !force ) return i-1;
  82. fprintf(stderr,
  83. "%s: missing or malformed integer value after option `%s'\n",
  84. Program, argv[i-1]);
  85. exit(EXIT_FAILURE);
  86. }
  87. /**********************************************************************/
  88. int
  89. getIntOpts(int argc, char **argv, int i,
  90. int **values,
  91. int cmin, int cmax)
  92. /*****
  93. We want to find at least cmin values and at most cmax values.
  94. cmax==-1 then means infinitely many are allowed.
  95. *****/
  96. {
  97. int alloced, used;
  98. char *end;
  99. long v;
  100. if( i+cmin >= argc ) {
  101. fprintf(stderr,
  102. "%s: option `%s' wants at least %d parameters\n",
  103. Program, argv[i], cmin);
  104. exit(EXIT_FAILURE);
  105. }
  106. /*****
  107. alloc a bit more than cmin values. It does not hurt to have room
  108. for a bit more values than cmax.
  109. *****/
  110. alloced = cmin + 4;
  111. *values = (int*)calloc((size_t)alloced, sizeof(int));
  112. if( ! *values ) {
  113. outMem:
  114. fprintf(stderr,
  115. "%s: out of memory while parsing option `%s'\n",
  116. Program, argv[i]);
  117. exit(EXIT_FAILURE);
  118. }
  119. for(used=0; (cmax==-1 || used<cmax) && used+i+1<argc; used++) {
  120. if( used==alloced ) {
  121. alloced += 8;
  122. *values = (int *) realloc(*values, alloced*sizeof(int));
  123. if( !*values ) goto outMem;
  124. }
  125. errno = 0;
  126. v = strtol(argv[used+i+1], &end, 0);
  127. /***** check for conversion error */
  128. if( end==argv[used+i+1] ) break;
  129. /***** check for surplus non-whitespace */
  130. while( isspace((int) *end) ) end+=1;
  131. if( *end ) break;
  132. /***** check for overflow */
  133. if( errno==ERANGE || v>(long)INT_MAX || v<(long)INT_MIN ) {
  134. fprintf(stderr,
  135. "%s: parameter `%s' of option `%s' to large to represent\n",
  136. Program, argv[i+used+1], argv[i]);
  137. exit(EXIT_FAILURE);
  138. }
  139. (*values)[used] = (int)v;
  140. }
  141. if( used<cmin ) {
  142. fprintf(stderr,
  143. "%s: parameter `%s' of `%s' should be an "
  144. "integer value\n",
  145. Program, argv[i+used+1], argv[i]);
  146. exit(EXIT_FAILURE);
  147. }
  148. return i+used;
  149. }
  150. /**********************************************************************/
  151. int
  152. getLongOpt(int argc, char **argv, int i, long *value, int force)
  153. {
  154. char *end;
  155. if( ++i>=argc ) goto nothingFound;
  156. errno = 0;
  157. *value = strtol(argv[i], &end, 0);
  158. /***** check for conversion error */
  159. if( end==argv[i] ) goto nothingFound;
  160. /***** check for surplus non-whitespace */
  161. while( isspace((int) *end) ) end+=1;
  162. if( *end ) goto nothingFound;
  163. /***** check for overflow */
  164. if( errno==ERANGE ) {
  165. fprintf(stderr,
  166. "%s: parameter `%s' of option `%s' to large to represent\n",
  167. Program, argv[i], argv[i-1]);
  168. exit(EXIT_FAILURE);
  169. }
  170. return i;
  171. nothingFound:
  172. /***** !force means: this parameter may be missing.*/
  173. if( !force ) return i-1;
  174. fprintf(stderr,
  175. "%s: missing or malformed value after option `%s'\n",
  176. Program, argv[i-1]);
  177. exit(EXIT_FAILURE);
  178. }
  179. /**********************************************************************/
  180. int
  181. getLongOpts(int argc, char **argv, int i,
  182. long **values,
  183. int cmin, int cmax)
  184. /*****
  185. We want to find at least cmin values and at most cmax values.
  186. cmax==-1 then means infinitely many are allowed.
  187. *****/
  188. {
  189. int alloced, used;
  190. char *end;
  191. if( i+cmin >= argc ) {
  192. fprintf(stderr,
  193. "%s: option `%s' wants at least %d parameters\n",
  194. Program, argv[i], cmin);
  195. exit(EXIT_FAILURE);
  196. }
  197. /*****
  198. alloc a bit more than cmin values. It does not hurt to have room
  199. for a bit more values than cmax.
  200. *****/
  201. alloced = cmin + 4;
  202. *values = (long int *)calloc((size_t)alloced, sizeof(long));
  203. if( ! *values ) {
  204. outMem:
  205. fprintf(stderr,
  206. "%s: out of memory while parsing option `%s'\n",
  207. Program, argv[i]);
  208. exit(EXIT_FAILURE);
  209. }
  210. for(used=0; (cmax==-1 || used<cmax) && used+i+1<argc; used++) {
  211. if( used==alloced ) {
  212. alloced += 8;
  213. *values = (long int*) realloc(*values, alloced*sizeof(long));
  214. if( !*values ) goto outMem;
  215. }
  216. errno = 0;
  217. (*values)[used] = strtol(argv[used+i+1], &end, 0);
  218. /***** check for conversion error */
  219. if( end==argv[used+i+1] ) break;
  220. /***** check for surplus non-whitespace */
  221. while( isspace((int) *end) ) end+=1;
  222. if( *end ) break;
  223. /***** check for overflow */
  224. if( errno==ERANGE ) {
  225. fprintf(stderr,
  226. "%s: parameter `%s' of option `%s' to large to represent\n",
  227. Program, argv[i+used+1], argv[i]);
  228. exit(EXIT_FAILURE);
  229. }
  230. }
  231. if( used<cmin ) {
  232. fprintf(stderr,
  233. "%s: parameter `%s' of `%s' should be an "
  234. "integer value\n",
  235. Program, argv[i+used+1], argv[i]);
  236. exit(EXIT_FAILURE);
  237. }
  238. return i+used;
  239. }
  240. /**********************************************************************/
  241. int
  242. getFloatOpt(int argc, char **argv, int i, float *value, int force)
  243. {
  244. char *end;
  245. double v;
  246. if( ++i>=argc ) goto nothingFound;
  247. errno = 0;
  248. v = strtod(argv[i], &end);
  249. /***** check for conversion error */
  250. if( end==argv[i] ) goto nothingFound;
  251. /***** check for surplus non-whitespace */
  252. while( isspace((int) *end) ) end+=1;
  253. if( *end ) goto nothingFound;
  254. /***** check for overflow */
  255. checkFloatConversion(v, argv[i-1], argv[i]);
  256. *value = (float)v;
  257. return i;
  258. nothingFound:
  259. if( !force ) return i-1;
  260. fprintf(stderr,
  261. "%s: missing or malformed float value after option `%s'\n",
  262. Program, argv[i-1]);
  263. exit(EXIT_FAILURE);
  264. }
  265. /**********************************************************************/
  266. int
  267. getFloatOpts(int argc, char **argv, int i,
  268. float **values,
  269. int cmin, int cmax)
  270. /*****
  271. We want to find at least cmin values and at most cmax values.
  272. cmax==-1 then means infinitely many are allowed.
  273. *****/
  274. {
  275. int alloced, used;
  276. char *end;
  277. double v;
  278. if( i+cmin >= argc ) {
  279. fprintf(stderr,
  280. "%s: option `%s' wants at least %d parameters\n",
  281. Program, argv[i], cmin);
  282. exit(EXIT_FAILURE);
  283. }
  284. /*****
  285. alloc a bit more than cmin values.
  286. *****/
  287. alloced = cmin + 4;
  288. *values = (float*)calloc((size_t)alloced, sizeof(float));
  289. if( ! *values ) {
  290. outMem:
  291. fprintf(stderr,
  292. "%s: out of memory while parsing option `%s'\n",
  293. Program, argv[i]);
  294. exit(EXIT_FAILURE);
  295. }
  296. for(used=0; (cmax==-1 || used<cmax) && used+i+1<argc; used++) {
  297. if( used==alloced ) {
  298. alloced += 8;
  299. *values = (float *) realloc(*values, alloced*sizeof(float));
  300. if( !*values ) goto outMem;
  301. }
  302. errno = 0;
  303. v = strtod(argv[used+i+1], &end);
  304. /***** check for conversion error */
  305. if( end==argv[used+i+1] ) break;
  306. /***** check for surplus non-whitespace */
  307. while( isspace((int) *end) ) end+=1;
  308. if( *end ) break;
  309. /***** check for overflow */
  310. checkFloatConversion(v, argv[i], argv[i+used+1]);
  311. (*values)[used] = (float)v;
  312. }
  313. if( used<cmin ) {
  314. fprintf(stderr,
  315. "%s: parameter `%s' of `%s' should be a "
  316. "floating-point value\n",
  317. Program, argv[i+used+1], argv[i]);
  318. exit(EXIT_FAILURE);
  319. }
  320. return i+used;
  321. }
  322. /**********************************************************************/
  323. int
  324. getDoubleOpt(int argc, char **argv, int i, double *value, int force)
  325. {
  326. char *end;
  327. if( ++i>=argc ) goto nothingFound;
  328. errno = 0;
  329. *value = strtod(argv[i], &end);
  330. /***** check for conversion error */
  331. if( end==argv[i] ) goto nothingFound;
  332. /***** check for surplus non-whitespace */
  333. while( isspace((int) *end) ) end+=1;
  334. if( *end ) goto nothingFound;
  335. /***** check for overflow */
  336. if( errno==ERANGE ) {
  337. fprintf(stderr,
  338. "%s: parameter `%s' of option `%s' to %s to represent\n",
  339. Program, argv[i], argv[i-1],
  340. (*value==0.0 ? "small" : "large"));
  341. exit(EXIT_FAILURE);
  342. }
  343. return i;
  344. nothingFound:
  345. if( !force ) return i-1;
  346. fprintf(stderr,
  347. "%s: missing or malformed value after option `%s'\n",
  348. Program, argv[i-1]);
  349. exit(EXIT_FAILURE);
  350. }
  351. /**********************************************************************/
  352. int
  353. getDoubleOpts(int argc, char **argv, int i,
  354. double **values,
  355. int cmin, int cmax)
  356. /*****
  357. We want to find at least cmin values and at most cmax values.
  358. cmax==-1 then means infinitely many are allowed.
  359. *****/
  360. {
  361. int alloced, used;
  362. char *end;
  363. if( i+cmin >= argc ) {
  364. fprintf(stderr,
  365. "%s: option `%s' wants at least %d parameters\n",
  366. Program, argv[i], cmin);
  367. exit(EXIT_FAILURE);
  368. }
  369. /*****
  370. alloc a bit more than cmin values.
  371. *****/
  372. alloced = cmin + 4;
  373. *values = (double*)calloc((size_t)alloced, sizeof(double));
  374. if( ! *values ) {
  375. outMem:
  376. fprintf(stderr,
  377. "%s: out of memory while parsing option `%s'\n",
  378. Program, argv[i]);
  379. exit(EXIT_FAILURE);
  380. }
  381. for(used=0; (cmax==-1 || used<cmax) && used+i+1<argc; used++) {
  382. if( used==alloced ) {
  383. alloced += 8;
  384. *values = (double *) realloc(*values, alloced*sizeof(double));
  385. if( !*values ) goto outMem;
  386. }
  387. errno = 0;
  388. (*values)[used] = strtod(argv[used+i+1], &end);
  389. /***** check for conversion error */
  390. if( end==argv[used+i+1] ) break;
  391. /***** check for surplus non-whitespace */
  392. while( isspace((int) *end) ) end+=1;
  393. if( *end ) break;
  394. /***** check for overflow */
  395. if( errno==ERANGE ) {
  396. fprintf(stderr,
  397. "%s: parameter `%s' of option `%s' to %s to represent\n",
  398. Program, argv[i+used+1], argv[i],
  399. ((*values)[used]==0.0 ? "small" : "large"));
  400. exit(EXIT_FAILURE);
  401. }
  402. }
  403. if( used<cmin ) {
  404. fprintf(stderr,
  405. "%s: parameter `%s' of `%s' should be a "
  406. "double value\n",
  407. Program, argv[i+used+1], argv[i]);
  408. exit(EXIT_FAILURE);
  409. }
  410. return i+used;
  411. }
  412. /**********************************************************************/
  413. /**
  414. force will be set if we need at least one argument for the option.
  415. *****/
  416. int
  417. getStringOpt(int argc, char **argv, int i, char **value, int force)
  418. {
  419. i += 1;
  420. if( i>=argc ) {
  421. if( force ) {
  422. fprintf(stderr, "%s: missing string after option `%s'\n",
  423. Program, argv[i-1]);
  424. exit(EXIT_FAILURE);
  425. }
  426. return i-1;
  427. }
  428. if( !force && argv[i][0] == '-' ) return i-1;
  429. *value = argv[i];
  430. return i;
  431. }
  432. /**********************************************************************/
  433. int
  434. getStringOpts(int argc, char **argv, int i,
  435. char* **values,
  436. int cmin, int cmax)
  437. /*****
  438. We want to find at least cmin values and at most cmax values.
  439. cmax==-1 then means infinitely many are allowed.
  440. *****/
  441. {
  442. int alloced, used;
  443. if( i+cmin >= argc ) {
  444. fprintf(stderr,
  445. "%s: option `%s' wants at least %d parameters\n",
  446. Program, argv[i], cmin);
  447. exit(EXIT_FAILURE);
  448. }
  449. alloced = cmin + 4;
  450. *values = (char**)calloc((size_t)alloced, sizeof(char*));
  451. if( ! *values ) {
  452. outMem:
  453. fprintf(stderr,
  454. "%s: out of memory during parsing of option `%s'\n",
  455. Program, argv[i]);
  456. exit(EXIT_FAILURE);
  457. }
  458. for(used=0; (cmax==-1 || used<cmax) && used+i+1<argc; used++) {
  459. if( used==alloced ) {
  460. alloced += 8;
  461. *values = (char **)realloc(*values, alloced*sizeof(char*));
  462. if( !*values ) goto outMem;
  463. }
  464. if( used>=cmin && argv[used+i+1][0]=='-' ) break;
  465. (*values)[used] = argv[used+i+1];
  466. }
  467. if( used<cmin ) {
  468. fprintf(stderr,
  469. "%s: less than %d parameters for option `%s', only %d found\n",
  470. Program, cmin, argv[i], used);
  471. exit(EXIT_FAILURE);
  472. }
  473. return i+used;
  474. }
  475. /**********************************************************************/
  476. void
  477. checkIntLower(char *opt, int *values, int count, int max)
  478. {
  479. int i;
  480. for(i=0; i<count; i++) {
  481. if( values[i]<=max ) continue;
  482. fprintf(stderr,
  483. "%s: parameter %d of option `%s' greater than max=%d\n",
  484. Program, i+1, opt, max);
  485. exit(EXIT_FAILURE);
  486. }
  487. }
  488. /**********************************************************************/
  489. void
  490. checkIntHigher(char *opt, int *values, int count, int min)
  491. {
  492. int i;
  493. for(i=0; i<count; i++) {
  494. if( values[i]>=min ) continue;
  495. fprintf(stderr,
  496. "%s: parameter %d of option `%s' smaller than min=%d\n",
  497. Program, i+1, opt, min);
  498. exit(EXIT_FAILURE);
  499. }
  500. }
  501. /**********************************************************************/
  502. void
  503. checkLongLower(char *opt, long *values, int count, long max)
  504. {
  505. int i;
  506. for(i=0; i<count; i++) {
  507. if( values[i]<=max ) continue;
  508. fprintf(stderr,
  509. "%s: parameter %d of option `%s' greater than max=%ld\n",
  510. Program, i+1, opt, max);
  511. exit(EXIT_FAILURE);
  512. }
  513. }
  514. /**********************************************************************/
  515. void
  516. checkLongHigher(char *opt, long *values, int count, long min)
  517. {
  518. int i;
  519. for(i=0; i<count; i++) {
  520. if( values[i]>=min ) continue;
  521. fprintf(stderr,
  522. "%s: parameter %d of option `%s' smaller than min=%ld\n",
  523. Program, i+1, opt, min);
  524. exit(EXIT_FAILURE);
  525. }
  526. }
  527. /**********************************************************************/
  528. void
  529. checkFloatLower(char *opt, float *values, int count, float max)
  530. {
  531. int i;
  532. for(i=0; i<count; i++) {
  533. if( values[i]<=max ) continue;
  534. fprintf(stderr,
  535. "%s: parameter %d of option `%s' greater than max=%f\n",
  536. Program, i+1, opt, max);
  537. exit(EXIT_FAILURE);
  538. }
  539. }
  540. /**********************************************************************/
  541. void
  542. checkFloatHigher(char *opt, float *values, int count, float min)
  543. {
  544. int i;
  545. for(i=0; i<count; i++) {
  546. if( values[i]>=min ) continue;
  547. fprintf(stderr,
  548. "%s: parameter %d of option `%s' smaller than min=%f\n",
  549. Program, i+1, opt, min);
  550. exit(EXIT_FAILURE);
  551. }
  552. }
  553. /**********************************************************************/
  554. void
  555. checkDoubleLower(char *opt, double *values, int count, double max)
  556. {
  557. int i;
  558. for(i=0; i<count; i++) {
  559. if( values[i]<=max ) continue;
  560. fprintf(stderr,
  561. "%s: parameter %d of option `%s' greater than max=%f\n",
  562. Program, i+1, opt, max);
  563. exit(EXIT_FAILURE);
  564. }
  565. }
  566. /**********************************************************************/
  567. void
  568. checkDoubleHigher(char *opt, double *values, int count, double min)
  569. {
  570. int i;
  571. for(i=0; i<count; i++) {
  572. if( values[i]>=min ) continue;
  573. fprintf(stderr,
  574. "%s: parameter %d of option `%s' smaller than min=%f\n",
  575. Program, i+1, opt, min);
  576. exit(EXIT_FAILURE);
  577. }
  578. }
  579. /**********************************************************************/
  580. static char *
  581. catArgv(int argc, char **argv)
  582. {
  583. int i;
  584. size_t l;
  585. char *s, *t;
  586. for(i=0, l=0; i<argc; i++) l += (1+strlen(argv[i]));
  587. s = (char *)malloc(l);
  588. if( !s ) {
  589. fprintf(stderr, "%s: out of memory\n", Program);
  590. exit(EXIT_FAILURE);
  591. }
  592. strcpy(s, argv[0]);
  593. t = s;
  594. for(i=1; i<argc; i++) {
  595. t = t+strlen(t);
  596. *t++ = ' ';
  597. strcpy(t, argv[i]);
  598. }
  599. return s;
  600. }
  601. /**********************************************************************/
  602. void
  603. usage(void)
  604. {
  605. fprintf(stderr,"%s"," [-o outputbasename] [--] infile ...\n");
  606. fprintf(stderr,"%s"," \n");
  607. fprintf(stderr,"%s"," Combine two frequency bands of Mock spectrometer data.\n");
  608. fprintf(stderr,"%s"," \n");
  609. fprintf(stderr,"%s"," -o: Basename for the output files\n");
  610. fprintf(stderr,"%s"," 1 char* value\n");
  611. fprintf(stderr,"%s"," infile: Input file name(s) of the PSRFITs datafiles\n");
  612. fprintf(stderr,"%s"," 1...2000 values\n");
  613. fprintf(stderr,"%s"," version: 18Nov13\n");
  614. fprintf(stderr,"%s"," ");
  615. exit(EXIT_FAILURE);
  616. }
  617. /**********************************************************************/
  618. Cmdline *
  619. parseCmdline(int argc, char **argv)
  620. {
  621. int i;
  622. Program = argv[0];
  623. cmd.full_cmd_line = catArgv(argc, argv);
  624. for(i=1, cmd.argc=1; i<argc; i++) {
  625. if( 0==strcmp("--", argv[i]) ) {
  626. while( ++i<argc ) argv[cmd.argc++] = argv[i];
  627. continue;
  628. }
  629. if( 0==strcmp("-o", argv[i]) ) {
  630. int keep = i;
  631. cmd.outputbasenameP = 1;
  632. i = getStringOpt(argc, argv, i, &cmd.outputbasename, 1);
  633. cmd.outputbasenameC = i-keep;
  634. continue;
  635. }
  636. if( argv[i][0]=='-' ) {
  637. fprintf(stderr, "\n%s: unknown option `%s'\n\n",
  638. Program, argv[i]);
  639. usage();
  640. }
  641. argv[cmd.argc++] = argv[i];
  642. }/* for i */
  643. /*@-mustfree*/
  644. cmd.argv = argv+1;
  645. /*@=mustfree*/
  646. cmd.argc -= 1;
  647. if( 1>cmd.argc ) {
  648. fprintf(stderr, "%s: there should be at least 1 non-option argument(s)\n",
  649. Program);
  650. exit(EXIT_FAILURE);
  651. }
  652. if( 2000<cmd.argc ) {
  653. fprintf(stderr, "%s: there should be at most 2000 non-option argument(s)\n",
  654. Program);
  655. exit(EXIT_FAILURE);
  656. }
  657. /*@-compmempass*/ return &cmd;
  658. }