matrixio.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. /**************************************************************************
  2. **
  3. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  4. **
  5. ** Meschach Library
  6. **
  7. ** This Meschach Library is provided "as is" without any express
  8. ** or implied warranty of any kind with respect to this software.
  9. ** In particular the authors shall not be liable for any direct,
  10. ** indirect, special, incidental or consequential damages arising
  11. ** in any way from use of the software.
  12. **
  13. ** Everyone is granted permission to copy, modify and redistribute this
  14. ** Meschach Library, provided:
  15. ** 1. All copies contain this copyright notice.
  16. ** 2. All modified copies shall carry a notice stating who
  17. ** made the last modification and the date of such modification.
  18. ** 3. No charge is made for this software or works derived from it.
  19. ** This clause shall not be construed as constraining other software
  20. ** distributed on the same medium as this software, nor is a
  21. ** distribution fee considered a charge.
  22. **
  23. ***************************************************************************/
  24. /* 1.6 matrixio.c 11/25/87 */
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include "matrix.h"
  28. static char rcsid[] = "$Id: matrixio.c,v 1.4 1994/01/13 05:31:10 des Exp $";
  29. /* local variables */
  30. static char line[MAXLINE];
  31. /**************************************************************************
  32. Input routines
  33. **************************************************************************/
  34. /* skipjunk -- skips white spaces and strings of the form #....\n
  35. Here .... is a comment string */
  36. #ifndef ANSI_C
  37. int skipjunk(fp)
  38. FILE *fp;
  39. #else
  40. int skipjunk(FILE *fp)
  41. #endif
  42. {
  43. int c;
  44. for ( ; ; ) /* forever do... */
  45. {
  46. /* skip blanks */
  47. do
  48. c = getc(fp);
  49. while ( isspace(c) );
  50. /* skip comments (if any) */
  51. if ( c == '#' )
  52. /* yes it is a comment (line) */
  53. while ( (c=getc(fp)) != '\n' )
  54. ;
  55. else
  56. {
  57. ungetc(c,fp);
  58. break;
  59. }
  60. }
  61. return 0;
  62. }
  63. /* m_finput -- input matrix
  64. -- input from a terminal is handled interactively
  65. -- batch/file input has the same format as produced by m_foutput
  66. except that whitespace and comments ("#..\n") are skipped
  67. -- returns a, which is created if a == NULL on entry */
  68. #ifndef ANSI_C
  69. MAT *m_finput(fp,a)
  70. FILE *fp;
  71. MAT *a;
  72. #else
  73. MAT *m_finput(FILE *fp, MAT *a)
  74. #endif
  75. {
  76. MAT *im_finput(),*bm_finput();
  77. if ( isatty(fileno(fp)) )
  78. return im_finput(fp,a);
  79. else
  80. return bm_finput(fp,a);
  81. }
  82. /* im_finput -- interactive input of matrix */
  83. #ifndef ANSI_C
  84. MAT *im_finput(fp,mat)
  85. FILE *fp;
  86. MAT *mat;
  87. #else
  88. MAT *im_finput(FILE *fp,MAT *mat)
  89. #endif
  90. {
  91. char c;
  92. unsigned int i, j, m, n, dynamic;
  93. /* dynamic set to TRUE if memory allocated here */
  94. /* get matrix size */
  95. if ( mat != (MAT *)NULL && mat->m<MAXDIM && mat->n<MAXDIM )
  96. { m = mat->m; n = mat->n; dynamic = FALSE; }
  97. else
  98. {
  99. dynamic = TRUE;
  100. do
  101. {
  102. fprintf(stderr,"Matrix: rows cols:");
  103. if ( fgets(line,MAXLINE,fp)==NULL )
  104. error(E_INPUT,"im_finput");
  105. } while ( sscanf(line,"%u%u",&m,&n)<2 || m>MAXDIM || n>MAXDIM );
  106. mat = m_get(m,n);
  107. }
  108. /* input elements */
  109. for ( i=0; i<m; i++ )
  110. {
  111. redo:
  112. fprintf(stderr,"row %u:\n",i);
  113. for ( j=0; j<n; j++ )
  114. do
  115. {
  116. redo2:
  117. fprintf(stderr,"entry (%u,%u): ",i,j);
  118. if ( !dynamic )
  119. fprintf(stderr,"old %14.9g new: ",
  120. mat->me[i][j]);
  121. if ( fgets(line,MAXLINE,fp)==NULL )
  122. error(E_INPUT,"im_finput");
  123. if ( (*line == 'b' || *line == 'B') && j > 0 )
  124. { j--; dynamic = FALSE; goto redo2; }
  125. if ( (*line == 'f' || *line == 'F') && j < n-1 )
  126. { j++; dynamic = FALSE; goto redo2; }
  127. #if REAL == DOUBLE
  128. } while ( *line=='\0' || sscanf(line,"%lf",&mat->me[i][j])<1 );
  129. #elif REAL == FLOAT
  130. } while ( *line=='\0' || sscanf(line,"%f",&mat->me[i][j])<1 );
  131. #endif
  132. fprintf(stderr,"Continue: ");
  133. fscanf(fp,"%c",&c);
  134. if ( c == 'n' || c == 'N' )
  135. { dynamic = FALSE; goto redo; }
  136. if ( (c == 'b' || c == 'B') /* && i > 0 */ )
  137. { if ( i > 0 )
  138. i--;
  139. dynamic = FALSE; goto redo;
  140. }
  141. }
  142. return (mat);
  143. }
  144. /* bm_finput -- batch-file input of matrix */
  145. #ifndef ANSI_C
  146. MAT *bm_finput(fp,mat)
  147. FILE *fp;
  148. MAT *mat;
  149. #else
  150. MAT *bm_finput(FILE *fp,MAT *mat)
  151. #endif
  152. {
  153. unsigned int i,j,m,n,dummy;
  154. int io_code;
  155. /* get dimension */
  156. skipjunk(fp);
  157. if ((io_code=fscanf(fp," Matrix: %u by %u",&m,&n)) < 2 ||
  158. m>MAXDIM || n>MAXDIM )
  159. error(io_code==EOF ? E_EOF : E_FORMAT,"bm_finput");
  160. /* allocate memory if necessary */
  161. if ( mat==(MAT *)NULL )
  162. mat = m_resize(mat,m,n);
  163. /* get entries */
  164. for ( i=0; i<m; i++ )
  165. {
  166. skipjunk(fp);
  167. if ( fscanf(fp," row %u:",&dummy) < 1 )
  168. error(E_FORMAT,"bm_finput");
  169. for ( j=0; j<n; j++ )
  170. #if REAL == DOUBLE
  171. if ((io_code=fscanf(fp,"%lf",&mat->me[i][j])) < 1 )
  172. #elif REAL == FLOAT
  173. if ((io_code=fscanf(fp,"%f",&mat->me[i][j])) < 1 )
  174. #endif
  175. error(io_code==EOF ? 7 : 6,"bm_finput");
  176. }
  177. return (mat);
  178. }
  179. /* px_finput -- inputs permutation from file/stream fp
  180. -- input from a terminal is handled interactively
  181. -- batch/file input has the same format as produced by px_foutput
  182. except that whitespace and comments ("#..\n") are skipped
  183. -- returns px, which is created if px == NULL on entry */
  184. #ifndef ANSI_C
  185. PERM *px_finput(fp,px)
  186. FILE *fp;
  187. PERM *px;
  188. #else
  189. PERM *px_finput(FILE *fp,PERM *px)
  190. #endif
  191. {
  192. PERM *ipx_finput(),*bpx_finput();
  193. if ( isatty(fileno(fp)) )
  194. return ipx_finput(fp,px);
  195. else
  196. return bpx_finput(fp,px);
  197. }
  198. /* ipx_finput -- interactive input of permutation */
  199. #ifndef ANSI_C
  200. PERM *ipx_finput(fp,px)
  201. FILE *fp;
  202. PERM *px;
  203. #else
  204. PERM *ipx_finput(FILE *fp,PERM *px)
  205. #endif
  206. {
  207. unsigned int i,j,size,dynamic; /* dynamic set if memory allocated here */
  208. unsigned int entry,ok;
  209. /* get permutation size */
  210. if ( px!=(PERM *)NULL && px->size<MAXDIM )
  211. { size = px->size; dynamic = FALSE; }
  212. else
  213. {
  214. dynamic = TRUE;
  215. do
  216. {
  217. fprintf(stderr,"Permutation: size: ");
  218. if ( fgets(line,MAXLINE,fp)==NULL )
  219. error(E_INPUT,"ipx_finput");
  220. } while ( sscanf(line,"%u",&size)<1 || size>MAXDIM );
  221. px = px_get(size);
  222. }
  223. /* get entries */
  224. i = 0;
  225. while ( i<size )
  226. {
  227. /* input entry */
  228. do
  229. {
  230. redo:
  231. fprintf(stderr,"entry %u: ",i);
  232. if ( !dynamic )
  233. fprintf(stderr,"old: %u->%u new: ",
  234. i,px->pe[i]);
  235. if ( fgets(line,MAXLINE,fp)==NULL )
  236. error(E_INPUT,"ipx_finput");
  237. if ( (*line == 'b' || *line == 'B') && i > 0 )
  238. { i--; dynamic = FALSE; goto redo; }
  239. } while ( *line=='\0' || sscanf(line,"%u",&entry) < 1 );
  240. /* check entry */
  241. ok = (entry < size);
  242. for ( j=0; j<i; j++ )
  243. ok &= (entry != px->pe[j]);
  244. if ( ok )
  245. {
  246. px->pe[i] = entry;
  247. i++;
  248. }
  249. }
  250. return (px);
  251. }
  252. /* bpx_finput -- batch-file input of permutation */
  253. #ifndef ANSI_C
  254. PERM *bpx_finput(fp,px)
  255. FILE *fp;
  256. PERM *px;
  257. #else
  258. PERM *bpx_finput(FILE *fp,PERM *px)
  259. #endif
  260. {
  261. unsigned int i,j,size,entry,ok;
  262. int io_code;
  263. /* get size of permutation */
  264. skipjunk(fp);
  265. if ((io_code=fscanf(fp," Permutation: size:%u",&size)) < 1 ||
  266. size>MAXDIM )
  267. error(io_code==EOF ? 7 : 6,"bpx_finput");
  268. /* allocate memory if necessary */
  269. if ( px==(PERM *)NULL || px->size<size )
  270. px = px_resize(px,size);
  271. /* get entries */
  272. skipjunk(fp);
  273. i = 0;
  274. while ( i<size )
  275. {
  276. /* input entry */
  277. if ((io_code=fscanf(fp,"%*u -> %u",&entry)) < 1 )
  278. error(io_code==EOF ? 7 : 6,"bpx_finput");
  279. /* check entry */
  280. ok = (entry < size);
  281. for ( j=0; j<i; j++ )
  282. ok &= (entry != px->pe[j]);
  283. if ( ok )
  284. {
  285. px->pe[i] = entry;
  286. i++;
  287. }
  288. else
  289. error(E_BOUNDS,"bpx_finput");
  290. }
  291. return (px);
  292. }
  293. /* v_finput -- inputs vector from file/stream fp
  294. -- input from a terminal is handled interactively
  295. -- batch/file input has the same format as produced by px_foutput
  296. except that whitespace and comments ("#..\n") are skipped
  297. -- returns x, which is created if x == NULL on entry */
  298. #ifndef ANSI_C
  299. VEC *v_finput(fp,x)
  300. FILE *fp;
  301. VEC *x;
  302. #else
  303. VEC *v_finput(FILE *fp,VEC *x)
  304. #endif
  305. {
  306. VEC *ifin_vec(),*bfin_vec();
  307. if ( isatty(fileno(fp)) )
  308. return ifin_vec(fp,x);
  309. else
  310. return bfin_vec(fp,x);
  311. }
  312. /* ifin_vec -- interactive input of vector */
  313. #ifndef ANSI_C
  314. VEC *ifin_vec(fp,vec)
  315. FILE *fp;
  316. VEC *vec;
  317. #else
  318. VEC *ifin_vec(FILE *fp,VEC *vec)
  319. #endif
  320. {
  321. unsigned int i,dim,dynamic; /* dynamic set if memory allocated here */
  322. /* get vector dimension */
  323. if ( vec != (VEC *)NULL && vec->dim<MAXDIM )
  324. { dim = vec->dim; dynamic = FALSE; }
  325. else
  326. {
  327. dynamic = TRUE;
  328. do
  329. {
  330. fprintf(stderr,"Vector: dim: ");
  331. if ( fgets(line,MAXLINE,fp)==NULL )
  332. error(E_INPUT,"ifin_vec");
  333. } while ( sscanf(line,"%u",&dim)<1 || dim>MAXDIM );
  334. vec = v_get(dim);
  335. }
  336. /* input elements */
  337. for ( i=0; i<dim; i++ )
  338. do
  339. {
  340. redo:
  341. fprintf(stderr,"entry %u: ",i);
  342. if ( !dynamic )
  343. fprintf(stderr,"old %14.9g new: ",vec->ve[i]);
  344. if ( fgets(line,MAXLINE,fp)==NULL )
  345. error(E_INPUT,"ifin_vec");
  346. if ( (*line == 'b' || *line == 'B') && i > 0 )
  347. { i--; dynamic = FALSE; goto redo; }
  348. if ( (*line == 'f' || *line == 'F') && i < dim-1 )
  349. { i++; dynamic = FALSE; goto redo; }
  350. #if REAL == DOUBLE
  351. } while ( *line=='\0' || sscanf(line,"%lf",&vec->ve[i]) < 1 );
  352. #elif REAL == FLOAT
  353. } while ( *line=='\0' || sscanf(line,"%f",&vec->ve[i]) < 1 );
  354. #endif
  355. return (vec);
  356. }
  357. /* bfin_vec -- batch-file input of vector */
  358. #ifndef ANSI_C
  359. VEC *bfin_vec(fp,vec)
  360. FILE *fp;
  361. VEC *vec;
  362. #else
  363. VEC *bfin_vec(FILE *fp,VEC *vec)
  364. #endif
  365. {
  366. unsigned int i,dim;
  367. int io_code;
  368. /* get dimension */
  369. skipjunk(fp);
  370. if ((io_code=fscanf(fp," Vector: dim:%u",&dim)) < 1 ||
  371. dim>MAXDIM )
  372. error(io_code==EOF ? 7 : 6,"bfin_vec");
  373. /* allocate memory if necessary */
  374. if ( vec==(VEC *)NULL )
  375. vec = v_resize(vec,dim);
  376. /* get entries */
  377. skipjunk(fp);
  378. for ( i=0; i<dim; i++ )
  379. #if REAL == DOUBLE
  380. if ((io_code=fscanf(fp,"%lf",&vec->ve[i])) < 1 )
  381. #elif REAL == FLOAT
  382. if ((io_code=fscanf(fp,"%f",&vec->ve[i])) < 1 )
  383. #endif
  384. error(io_code==EOF ? 7 : 6,"bfin_vec");
  385. return (vec);
  386. }
  387. /**************************************************************************
  388. Output routines
  389. **************************************************************************/
  390. static const char *format = "%14.9g ";
  391. /* setformat -- sets the printf format string for the Meschach I/O operations
  392. -- returns the previous format string */
  393. #ifndef ANSI_C
  394. char *setformat(f_string)
  395. char *f_string;
  396. #else
  397. const char *setformat(const char *f_string)
  398. #endif
  399. {
  400. const char *old_f_string;
  401. old_f_string = format;
  402. if ( f_string != (char *)NULL && *f_string != '\0' )
  403. format = f_string;
  404. return old_f_string;
  405. }
  406. /* m_foutput -- prints a representation of the matrix a onto file/stream fp */
  407. #ifndef ANSI_C
  408. void m_foutput(fp,a)
  409. FILE *fp;
  410. MAT *a;
  411. #else
  412. void m_foutput(FILE *fp, const MAT *a)
  413. #endif
  414. {
  415. unsigned int i, j, tmp;
  416. if ( a == (MAT *)NULL )
  417. { fprintf(fp,"Matrix: NULL\n"); return; }
  418. fprintf(fp,"Matrix: %d by %d\n",a->m,a->n);
  419. if ( a->me == (Real **)NULL )
  420. { fprintf(fp,"NULL\n"); return; }
  421. for ( i=0; i<a->m; i++ ) /* for each row... */
  422. {
  423. fprintf(fp,"row %u: ",i);
  424. for ( j=0, tmp=2; j<a->n; j++, tmp++ )
  425. { /* for each col in row... */
  426. fprintf(fp,format,a->me[i][j]);
  427. if ( ! (tmp % 5) ) putc('\n',fp);
  428. }
  429. if ( tmp % 5 != 1 ) putc('\n',fp);
  430. }
  431. }
  432. /* px_foutput -- prints a representation of px onto file/stream fp */
  433. #ifndef ANSI_C
  434. void px_foutput(fp,px)
  435. FILE *fp;
  436. PERM *px;
  437. #else
  438. void px_foutput(FILE *fp, const PERM *px)
  439. #endif
  440. {
  441. unsigned int i;
  442. if ( px == (PERM *)NULL )
  443. { fprintf(fp,"Permutation: NULL\n"); return; }
  444. fprintf(fp,"Permutation: size: %u\n",px->size);
  445. if ( px->pe == (unsigned int *)NULL )
  446. { fprintf(fp,"NULL\n"); return; }
  447. for ( i=0; i<px->size; i++ )
  448. if ( ! (i % 8) && i != 0 )
  449. fprintf(fp,"\n %u->%u ",i,px->pe[i]);
  450. else
  451. fprintf(fp,"%u->%u ",i,px->pe[i]);
  452. fprintf(fp,"\n");
  453. }
  454. /* v_foutput -- prints a representation of x onto file/stream fp */
  455. #ifndef ANSI_C
  456. void v_foutput(fp,x)
  457. FILE *fp;
  458. VEC *x;
  459. #else
  460. void v_foutput(FILE *fp, const VEC *x)
  461. #endif
  462. {
  463. unsigned int i, tmp;
  464. if ( x == (VEC *)NULL )
  465. { fprintf(fp,"Vector: NULL\n"); return; }
  466. fprintf(fp,"Vector: dim: %d\n",x->dim);
  467. if ( x->ve == (Real *)NULL )
  468. { fprintf(fp,"NULL\n"); return; }
  469. for ( i=0, tmp=0; i<x->dim; i++, tmp++ )
  470. {
  471. fprintf(fp,format,x->ve[i]);
  472. if ( tmp % 5 == 4 ) putc('\n',fp);
  473. }
  474. if ( tmp % 5 != 0 ) putc('\n',fp);
  475. }
  476. /* m_dump -- prints a dump of all pointers and data in a onto fp
  477. -- suitable for low-level debugging */
  478. #ifndef ANSI_C
  479. void m_dump(fp,a)
  480. FILE *fp;
  481. MAT *a;
  482. #else
  483. void m_dump(FILE *fp, const MAT *a)
  484. #endif
  485. {
  486. unsigned int i, j, tmp;
  487. if ( a == (MAT *)NULL )
  488. { fprintf(fp,"Matrix: NULL\n"); return; }
  489. fprintf(fp,"Matrix: %d by %d @ 0x%lx\n",a->m,a->n,(long)a);
  490. fprintf(fp,"\tmax_m = %d, max_n = %d, max_size = %d\n",
  491. a->max_m, a->max_n, a->max_size);
  492. if ( a->me == (Real **)NULL )
  493. { fprintf(fp,"NULL\n"); return; }
  494. fprintf(fp,"a->me @ 0x%lx\n",(long)(a->me));
  495. fprintf(fp,"a->base @ 0x%lx\n",(long)(a->base));
  496. for ( i=0; i<a->m; i++ ) /* for each row... */
  497. {
  498. fprintf(fp,"row %u: @ 0x%lx ",i,(long)(a->me[i]));
  499. for ( j=0, tmp=2; j<a->n; j++, tmp++ )
  500. { /* for each col in row... */
  501. fprintf(fp,format,a->me[i][j]);
  502. if ( ! (tmp % 5) ) putc('\n',fp);
  503. }
  504. if ( tmp % 5 != 1 ) putc('\n',fp);
  505. }
  506. }
  507. /* px_dump -- prints a dump of all pointers and data in a onto fp
  508. -- suitable for low-level debugging */
  509. #ifndef ANSI_C
  510. void px_dump(fp,px)
  511. FILE *fp;
  512. PERM *px;
  513. #else
  514. void px_dump(FILE *fp, const PERM *px)
  515. #endif
  516. {
  517. unsigned int i;
  518. if ( ! px )
  519. { fprintf(fp,"Permutation: NULL\n"); return; }
  520. fprintf(fp,"Permutation: size: %u @ 0x%lx\n",px->size,(long)(px));
  521. if ( ! px->pe )
  522. { fprintf(fp,"NULL\n"); return; }
  523. fprintf(fp,"px->pe @ 0x%lx\n",(long)(px->pe));
  524. for ( i=0; i<px->size; i++ )
  525. fprintf(fp,"%u->%u ",i,px->pe[i]);
  526. fprintf(fp,"\n");
  527. }
  528. /* v_dump -- prints a dump of all pointers and data in a onto fp
  529. -- suitable for low-level debugging */
  530. #ifndef ANSI_C
  531. void v_dump(fp,x)
  532. FILE *fp;
  533. VEC *x;
  534. #else
  535. void v_dump(FILE *fp, const VEC *x)
  536. #endif
  537. {
  538. unsigned int i, tmp;
  539. if ( ! x )
  540. { fprintf(fp,"Vector: NULL\n"); return; }
  541. fprintf(fp,"Vector: dim: %d @ 0x%lx\n",x->dim,(long)(x));
  542. if ( ! x->ve )
  543. { fprintf(fp,"NULL\n"); return; }
  544. fprintf(fp,"x->ve @ 0x%lx\n",(long)(x->ve));
  545. for ( i=0, tmp=0; i<x->dim; i++, tmp++ )
  546. {
  547. fprintf(fp,format,x->ve[i]);
  548. if ( tmp % 5 == 4 ) putc('\n',fp);
  549. }
  550. if ( tmp % 5 != 0 ) putc('\n',fp);
  551. }
  552. /* iv_foutput -- print a representation of iv on stream fp */
  553. #ifndef ANSI_C
  554. void iv_foutput(fp,iv)
  555. FILE *fp;
  556. IVEC *iv;
  557. #else
  558. void iv_foutput(FILE *fp, const IVEC *iv)
  559. #endif
  560. {
  561. int i;
  562. fprintf(fp,"IntVector: ");
  563. if ( iv == IVNULL )
  564. {
  565. fprintf(fp,"**** NULL ****\n");
  566. return;
  567. }
  568. fprintf(fp,"dim: %d\n",iv->dim);
  569. for ( i = 0; i < iv->dim; i++ )
  570. {
  571. if ( (i+1) % 8 )
  572. fprintf(fp,"%8d ",iv->ive[i]);
  573. else
  574. fprintf(fp,"%8d\n",iv->ive[i]);
  575. }
  576. if ( i % 8 )
  577. fprintf(fp,"\n");
  578. }
  579. /* iv_finput -- input integer vector from stream fp
  580. -- input from a terminal is handled interactively
  581. -- batch/file input has the same format as produced by
  582. iv_foutput except that whitespace and comments ("#...\n")
  583. are skipped */
  584. #ifndef ANSI_C
  585. IVEC *iv_finput(fp,x)
  586. FILE *fp;
  587. IVEC *x;
  588. #else
  589. IVEC *iv_finput(FILE *fp, IVEC *x)
  590. #endif
  591. {
  592. IVEC *iiv_finput(),*biv_finput();
  593. if ( isatty(fileno(fp)) )
  594. return iiv_finput(fp,x);
  595. else
  596. return biv_finput(fp,x);
  597. }
  598. /* iiv_finput -- interactive input of IVEC iv */
  599. #ifndef ANSI_C
  600. IVEC *iiv_finput(fp,iv)
  601. FILE *fp;
  602. IVEC *iv;
  603. #else
  604. IVEC *iiv_finput(FILE *fp, IVEC *iv)
  605. #endif
  606. {
  607. unsigned int i,dim,dynamic; /* dynamic set if memory allocated here */
  608. /* get dimension */
  609. if ( iv != (IVEC *)NULL && iv->dim<MAXDIM )
  610. { dim = iv->dim; dynamic = FALSE; }
  611. else
  612. {
  613. dynamic = TRUE;
  614. do
  615. {
  616. fprintf(stderr,"IntVector: dim: ");
  617. if ( fgets(line,MAXLINE,fp)==NULL )
  618. error(E_INPUT,"iiv_finput");
  619. } while ( sscanf(line,"%u",&dim)<1 || dim>MAXDIM );
  620. iv = iv_get(dim);
  621. }
  622. /* input elements */
  623. for ( i=0; i<dim; i++ )
  624. do
  625. {
  626. redo:
  627. fprintf(stderr,"entry %u: ",i);
  628. if ( !dynamic )
  629. fprintf(stderr,"old: %-9d new: ",iv->ive[i]);
  630. if ( fgets(line,MAXLINE,fp)==NULL )
  631. error(E_INPUT,"iiv_finput");
  632. if ( (*line == 'b' || *line == 'B') && i > 0 )
  633. { i--; dynamic = FALSE; goto redo; }
  634. if ( (*line == 'f' || *line == 'F') && i < dim-1 )
  635. { i++; dynamic = FALSE; goto redo; }
  636. } while ( *line=='\0' || sscanf(line,"%d",&iv->ive[i]) < 1 );
  637. return (iv);
  638. }
  639. /* biv_finput -- batch-file input of IVEC iv */
  640. #ifndef ANSI_C
  641. IVEC *biv_finput(fp,iv)
  642. FILE *fp;
  643. IVEC *iv;
  644. #else
  645. IVEC *biv_finput(FILE *fp, IVEC *iv)
  646. #endif
  647. {
  648. unsigned int i,dim;
  649. int io_code;
  650. /* get dimension */
  651. skipjunk(fp);
  652. if ((io_code=fscanf(fp," IntVector: dim:%u",&dim)) < 1 ||
  653. dim>MAXDIM )
  654. error(io_code==EOF ? 7 : 6,"biv_finput");
  655. /* allocate memory if necessary */
  656. if ( iv==(IVEC *)NULL || iv->dim<dim )
  657. iv = iv_resize(iv,dim);
  658. /* get entries */
  659. skipjunk(fp);
  660. for ( i=0; i<dim; i++ )
  661. if ((io_code=fscanf(fp,"%d",&iv->ive[i])) < 1 )
  662. error(io_code==EOF ? 7 : 6,"biv_finput");
  663. return (iv);
  664. }
  665. /* iv_dump -- dumps all the contents of IVEC iv onto stream fp */
  666. #ifndef ANSI_C
  667. void iv_dump(fp,iv)
  668. FILE*fp;
  669. IVEC*iv;
  670. #else
  671. void iv_dump(FILE *fp, const IVEC *iv)
  672. #endif
  673. {
  674. int i;
  675. fprintf(fp,"IntVector: ");
  676. if ( ! iv )
  677. {
  678. fprintf(fp,"**** NULL ****\n");
  679. return;
  680. }
  681. fprintf(fp,"dim: %d, max_dim: %d\n",iv->dim,iv->max_dim);
  682. fprintf(fp,"ive @ 0x%lx\n",(long)(iv->ive));
  683. for ( i = 0; i < iv->max_dim; i++ )
  684. {
  685. if ( (i+1) % 8 )
  686. fprintf(fp,"%8d ",iv->ive[i]);
  687. else
  688. fprintf(fp,"%8d\n",iv->ive[i]);
  689. }
  690. if ( i % 8 )
  691. fprintf(fp,"\n");
  692. }