1 /*
2 fitstab.c
3
4 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 *
6 * Part of: The LDAC Tools
7 *
8 * Author: E.BERTIN, DeNIS/LDAC
9 *
10 * Contents: general functions for handling LDAC FITS catalogs.
11 *
12 * Last modify: 15/08/2003
13 *
14 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "fitscat_defs.h"
26 #include "fitscat.h"
27
28 /****** about_tab **************************************************************
29 PROTO int about_tab(catstruct *cat, char *tabname, FILE *stream)
30 PURPOSE Print information concerning a tab structure.
31 INPUT Pointer to the input catalog,
32 table name,
33 an output stream.
34 OUTPUT RETURN_OK if the table was found, RETURN_ERROR otherwise.
35 NOTES -.
36 AUTHOR E.R. Deul(Leiden observatory),
37 E. Bertin (IAP & Leiden observatory): return value modified.
38 E.R. Deul(Leiden observatory): output units
39 VERSION 15/08/2003
40 ***/
about_tab(catstruct * cat,char * tabname,FILE * stream)41 int about_tab(catstruct *cat, char *tabname, FILE *stream)
42 {
43 tabstruct *tab;
44 keystruct *key;
45 int i, j;
46
47 if ((tab = name_to_tab(cat, tabname, 0))) {
48 fprintf(stream, "Table %s\n", tabname);
49 for (i=0, key=tab->key; i<tab->nkey; i++,key=key->nextkey)
50 {
51 fprintf(stream,
52 "****** Key #%d\n", i+1);
53 fprintf(stream,
54 " Key name:...............%s\n", key->name);
55 fprintf(stream,
56 " Key comment:............%s\n", key->comment);
57 fprintf(stream,
58 " Key type:...............");
59 switch (key->ttype) {
60 case T_BYTE: fprintf(stream,"Byte"); break;
61 case T_SHORT: fprintf(stream,"Short Int"); break;
62 case T_LONG: fprintf(stream,"Long Int"); break;
63 case T_FLOAT: fprintf(stream,"Float"); break;
64 case T_DOUBLE: fprintf(stream,"Double"); break;
65 case T_STRING: fprintf(stream,"String"); break;
66 }
67 fprintf(stream,"\n");
68 fprintf(stream,
69 " Key dimension:..........%d ", key->naxis);
70 if (key->naxis) fprintf(stream, "(");
71 for (j=0;j<key->naxis;j++) {
72 if (j>0) fprintf(stream, " ");
73 fprintf(stream, "%d", key->naxisn[j]);
74 }
75 if (key->naxis) fprintf(stream, ")");
76 fprintf(stream, "\n");
77 if (key->unit[0] != '\0')
78 fprintf(stream,
79 " Key unit:...............%s\n", key->unit);
80 }
81 } else return RETURN_ERROR;
82
83 return RETURN_OK;
84 }
85
86 /****** add_tab ****************************************************************
87 PROTO int add_tab(tabstruct *tab, catstruct *cat, int pos)
88 PURPOSE Add a table to a catalog.
89 INPUT Pointer to the table,
90 Pointer to the destination catalog,
91 Position (1= first after the primary HDU, <=0 = at the end).
92 OUTPUT RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
93 NOTES Only 1-segment tables are accepted. To copy multi-segment tables,
94 use copy_tab() instead.
95 If a table with the same name and basic attributes already exists in
96 the destination catalog, then the new table is appended to it.
97 AUTHOR E. Bertin (IAP & Leiden observatory)
98 VERSION 15/08/2003
99 ***/
add_tab(tabstruct * tab,catstruct * cat,int pos)100 int add_tab(tabstruct *tab, catstruct *cat, int pos)
101
102 {
103 tabstruct *outtab, *prevtab;
104 int i;
105
106 /*Check if a similar table doesn't already exist in the dest. cat */
107 if ((outtab = name_to_tab(cat, tab->extname, 0)))
108 {
109 if ((outtab->naxis != 2)
110 || (outtab->bitpix!=8)
111 || strcmp(outtab->xtension,tab->xtension)
112 || (outtab->tfields != tab->tfields)
113 || (outtab->naxisn[0] != tab->naxisn[0]))
114 return RETURN_ERROR;
115
116 prevtab = outtab;
117 for (i=outtab->nseg-1; i--;)
118 prevtab = prevtab->nexttab;
119 tab->seg = prevtab->seg+1;
120 tab->nseg = 0;
121 outtab->nseg++;
122 }
123 else
124 {
125 if ((prevtab = pos_to_tab(cat, pos, 0)))
126 prevtab = prevtab->prevtab;
127 else
128 tab->nexttab = tab->prevtab = prevtab = tab;
129 cat->ntab++;
130 }
131
132 (tab->nexttab = (tab->prevtab = prevtab)->nexttab)->prevtab = tab;
133 prevtab->nexttab = tab;
134
135 return RETURN_OK;
136 }
137
138
139 /****** copy_tab **************************************************************
140 PROTO int copy_tab(catstruct *catin, char *tabname, int seg,
141 catstruct *catout, int pos)
142 PURPOSE Copy a table from one catalog to another.
143 INPUT Pointer to the original catalog,
144 Name of the table,
145 Table segment (0 = all),
146 Pointer to the destination catalog,
147 Position (1= first after the primary HDU, <=0 = at the end)
148 OUTPUT RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
149 NOTES If a table with the same name and basic attributes already exists in
150 the destination catalog, then the original table is appended to it.
151 AUTHOR E. Bertin (IAP & Leiden observatory)
152 VERSION 15/08/2003
153 ***/
copy_tab(catstruct * catin,char * tabname,int seg,catstruct * catout,int pos)154 int copy_tab(catstruct *catin, char *tabname, int seg,
155 catstruct *catout, int pos)
156
157 {
158 keystruct *key;
159 tabstruct *outtab, *prevtab, *nexttab, *tabin,*tabout;
160 int i,j, nseg;
161
162 /*Convert the table name to a pointer*/
163 if (!(tabin = name_to_tab(catin, tabname, seg)))
164 return RETURN_ERROR;
165
166 nseg = seg?1:tabin->nseg;
167 /*Check if a similar table doesn't already exist in the dest. cat */
168 if (*tabname && (outtab = name_to_tab(catout, tabname, 0)))
169 {
170 if ((outtab->naxis != 2)
171 || (outtab->bitpix!=8)
172 || strcmp(outtab->xtension,tabin->xtension)
173 || (outtab->tfields != tabin->tfields)
174 || (outtab->naxisn[0] != tabin->naxisn[0]))
175 return RETURN_ERROR;
176 prevtab = outtab;
177 for (i=0; i<outtab->nseg-1; i++)
178 prevtab = prevtab->nexttab;
179 nexttab = prevtab->nexttab;
180 outtab->nseg += nseg;
181 }
182 else
183 {
184 prevtab = nexttab = outtab = NULL;
185 catout->ntab++;
186 }
187
188 /*Now copy each segment of the original table*/
189 tabout = NULL; /* to satisfy gcc -Wall */
190 for (i=nseg; i--;)
191 {
192 /*---First, allocate memory and copy data */
193 QCALLOC(tabout, tabstruct, 1);
194 *tabout = *tabin;
195 if (tabin->naxis)
196 QMEMCPY(tabin->naxisn, tabout->naxisn, int, tabin->naxis);
197 if (tabin->headbuf)
198 QMEMCPY(tabin->headbuf, tabout->headbuf, char, tabin->headnblock*FBSIZE);
199 if (tabin->bodybuf)
200 QMEMCPY(tabin->bodybuf, tabout->bodybuf, char, tabin->tabsize);
201
202 key = tabin->key;
203 tabout->key = NULL;
204 tabout->nkey = 0;
205 for (j=tabin->nkey; j--;)
206 {
207 copy_key(tabin, key->name, tabout, 0);
208 key = key->nextkey;
209 }
210
211 /*---Then, update the links */
212 if (prevtab)
213 {
214 prevtab->nexttab = tabout;
215 tabout->prevtab = prevtab;
216 tabout->seg = prevtab->seg+1;
217 tabout->nseg = 0;
218 }
219 else
220 {
221 outtab = tabout;
222 outtab->prevtab = NULL;
223 tabout->seg = 1;
224 }
225 tabin = tabin->nexttab;
226 prevtab = tabout;
227 }
228
229 /*place the new chain of table-segments within the catalog (tricky, isn't it?)*/
230 if (!nexttab)
231 /*--if the table is new */
232 {
233 nexttab = pos_to_tab(catout, pos, 0);
234 if (!nexttab)
235 nexttab = catout->tab = tabout;
236 else
237 {
238 outtab->prevtab = nexttab->prevtab;
239 nexttab->prevtab->nexttab = outtab;
240 }
241 }
242
243 prevtab->nexttab = nexttab;
244 nexttab->prevtab = prevtab;
245
246 return RETURN_OK;
247 }
248
249
250 /****** copy_tab_fromptr ******************************************************
251 PROTO void copy_tab_fromptr(tabstruct *tabin, catstruct *catout, int pos)
252 PURPOSE Copy a table from one catalog to another.
253 INPUT Pointer to the original catalog,
254 Pointer to the table,
255 Pointer to the destination catalog,
256 Position (1= first after the primary HDU, <=0 = at the end)
257 OUTPUT -.
258 NOTES -.
259 AUTHOR E. Bertin (IAP & Leiden observatory)
260 VERSION 22/06/2001
261 ***/
copy_tab_fromptr(tabstruct * tabin,catstruct * catout,int pos)262 void copy_tab_fromptr(tabstruct *tabin, catstruct *catout, int pos)
263
264 {
265 keystruct *key;
266 tabstruct *prevtab, *nexttab,*tabout;
267 int j;
268
269 catout->ntab++;
270
271 /* First, allocate memory and copy data */
272 QCALLOC(tabout, tabstruct, 1);
273 *tabout = *tabin;
274 if (tabin->naxis)
275 QMEMCPY(tabin->naxisn, tabout->naxisn, int, tabin->naxis);
276 if (tabin->headbuf)
277 QMEMCPY(tabin->headbuf, tabout->headbuf, char, tabin->headnblock*FBSIZE);
278 if (tabin->bodybuf)
279 QMEMCPY(tabin->bodybuf, tabout->bodybuf, char, tabin->tabsize);
280
281 key = tabin->key;
282 tabout->key = NULL;
283 tabout->nkey = 0;
284 for (j=tabin->nkey; j--;)
285 {
286 copy_key(tabin, key->name, tabout, 0);
287 key = key->nextkey;
288 }
289
290 /* Then, update the links */
291 tabout->prevtab = NULL;
292 tabout->seg = 1;
293 tabin = tabin->nexttab;
294 prevtab = tabout;
295
296 if (!(nexttab = pos_to_tab(catout, pos, 0)))
297 nexttab = catout->tab = tabout;
298 else
299 {
300 tabout->prevtab = nexttab->prevtab;
301 nexttab->prevtab->nexttab = tabout;
302 }
303
304 prevtab->nexttab = nexttab;
305 nexttab->prevtab = prevtab;
306
307 return;
308 }
309
310
311 /****** copy_tabs **************************************************************
312 PROTO int copy_tabs(catstruct *catin, catstruct *catout)
313 PURPOSE Copy all tables from one catalog to another.
314 INPUT Pointer to the original catalog,
315 Pointer to the destination catalog,
316 OUTPUT RETURN_OK if everything went as expected, and RETURN_ERROR otherwise
317 (for instance if there were tabs that were not binary-tables, and
318 therefore that were not copied).
319 NOTES If a table with the same name and basic attributes already exists in
320 the destination catalog, then the original table is appended to it.
321 AUTHOR E. Bertin (IAP & Leiden observatory)
322 VERSION 12/06/2001
323 ***/
copy_tabs(catstruct * catin,catstruct * catout)324 int copy_tabs(catstruct *catin, catstruct *catout)
325
326 {
327 tabstruct *tab;
328 int i, flag, ntab;
329
330 if (!catin->tab)
331 return RETURN_ERROR;
332
333 tab = catin->tab->nexttab; /* skip the primary header */
334 flag = RETURN_OK;
335 ntab = catin->ntab-1;
336 if (!ntab)
337 ntab = 1;
338 for (i=ntab; i--;)
339 {
340 flag |= copy_tab(catin, tab->extname, 0, catout, 0);
341 while (!(tab=tab->nexttab)->nseg);
342 }
343
344 return flag;
345 }
346
347
348 /****** copy_tabs_blind *******************************************************
349 PROTO int copy_tabs(catstruct *catin, catstruct *catout)
350 PURPOSE Copy all tables from one catalog to another, without trying to append.
351 INPUT Pointer to the original catalog,
352 Pointer to the destination catalog,
353 OUTPUT RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
354 NOTES -.
355 AUTHOR E. Bertin (IAP & Leiden observatory)
356 VERSION 07/05/2002
357 ***/
copy_tabs_blind(catstruct * catin,catstruct * catout)358 int copy_tabs_blind(catstruct *catin, catstruct *catout)
359
360 {
361 tabstruct *tab;
362 int i, ntab;
363
364 if (!catin->tab)
365 return RETURN_ERROR;
366
367 tab = catin->tab; /* don't skip the primary header */
368 ntab = catin->ntab;
369 for (i=ntab; i--;)
370 {
371 copy_tab_fromptr(tab, catout, 0);
372 tab=tab->nexttab;
373 }
374
375 return RETURN_OK;
376 }
377
378
379 /****** free_tab ***************************************************************
380 PROTO void free_tab(tabstruct *tab)
381 PURPOSE Free memory associated to a table pointer.
382 INPUT Pointer to the table.
383 OUTPUT -.
384 NOTES -.
385 AUTHOR E. Bertin (IAP & Leiden observatory)
386 VERSION 28/02/2000
387 ***/
free_tab(tabstruct * tab)388 void free_tab(tabstruct *tab)
389
390 {
391 free_body(tab);
392 free(tab->naxisn);
393 free(tab->headbuf);
394 free(tab->compress_buf);
395 remove_keys(tab);
396 free(tab);
397
398 return;
399 }
400
401
402 /****** new_tab ****************************************************************
403 PROTO tabstruct *new_tab(char *tabname)
404 PURPOSE Create a new binary table.
405 INPUT Name.
406 OUTPUT A pointer to the new table.
407 NOTES A defaut header is also created.
408 No links are initialized.
409 AUTHOR E. Bertin (IAP & Leiden observatory)
410 VERSION 25/04/97
411 ***/
new_tab(char * tabname)412 tabstruct *new_tab(char *tabname)
413
414 {
415 static char bintabtemplate[][80] = {
416 "XTENSION= 'BINTABLE' / THIS IS A BINARY TABLE (FROM THE LDACTOOLS)",
417 "BITPIX = 8 / ",
418 "NAXIS = 2 / ",
419 "NAXIS1 = 0 / BYTES PER ROW",
420 "NAXIS2 = 0 / NUMBER OF ROWS",
421 "PCOUNT = 0 / RANDOM PARAMETER COUNT",
422 "GCOUNT = 1 / GROUP COUNT",
423 "TFIELDS = 0 / FIELDS PER ROWS",
424 "EXTNAME = 'WHOCARES' / TABLE NAME",
425 "END "};
426 tabstruct *tab;
427 char *buf;
428 int i;
429
430 QCALLOC(tab, tabstruct, 1);
431 strcpy(tab->xtension, "BINTABLE");
432 strcpy(tab->extname, tabname);
433 tab->naxis = 2;
434 QCALLOC(tab->naxisn, int, tab->naxis);
435 tab->bitpix = 8;
436 tab->bytepix = 1;
437 tab->pcount = 0;
438 tab->gcount = 1;
439 tab->seg = 1;
440 tab->nseg = 1;
441 /*Provide a new header*/
442 QCALLOC(tab->headbuf, char, FBSIZE);
443 memcpy(tab->headbuf, bintabtemplate, sizeof(bintabtemplate));
444 for (buf = tab->headbuf, i=FBSIZE; i--; buf++)
445 if (!*buf)
446 *buf = ' ';
447 tab->headnblock = 1;
448
449 return tab;
450 }
451
452
453 /****** remove_tab *************************************************************
454 PROTO int remove_tab(catstruct *cat, char *tabname, int seg)
455 PURPOSE Remove a table from a catalog.
456 INPUT Pointer to the catalog,
457 Name of the table,
458 Table segment (0 = all).
459 OUTPUT RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
460 NOTES If tabname = "", the last table from the list is removed.
461 AUTHOR E. Bertin (IAP & Leiden observatory)
462 VERSION 15/08/2003
463 ***/
remove_tab(catstruct * cat,char * tabname,int seg)464 int remove_tab(catstruct *cat, char *tabname, int seg)
465
466 {
467 tabstruct *tab, *prevtab, *nexttab;
468 int i,nseg;
469
470 if (!tabname || !cat->ntab || !cat->tab)
471 return RETURN_ERROR;
472
473 if (tabname[0])
474 {
475 /*--Convert the table name to a pointer*/
476 if (!(tab = name_to_tab(cat, tabname, seg)))
477 return RETURN_ERROR;
478 /*--a small trick to simplify decisions afterwards*/
479 if (seg && tab->nseg==1)
480 seg = 0;
481 }
482 else
483 {
484 tab = cat->tab->prevtab;
485 if (!seg)
486 for (;!tab->nseg; tab = tab->prevtab);
487 }
488
489 prevtab = tab->prevtab;
490 nseg = seg?1:tab->nseg;
491
492 /*Free memory for each table segment*/
493 nexttab = NULL; /* to satisfy gcc -Wall */
494 for (i=nseg; i--;)
495 {
496 nexttab = tab->nexttab;
497 if (cat->tab == tab)
498 cat->tab = nexttab;
499 free_tab(tab);
500 tab = nexttab;
501 }
502
503 if (!seg)
504 if (!--cat->ntab)
505 {
506 cat->tab = NULL;
507 return RETURN_OK;
508 }
509
510 /*update the links of neighbours*/
511 nexttab->prevtab = prevtab;
512 prevtab->nexttab = nexttab;
513
514 if (seg)
515 /*--update status for each table segment*/
516 {
517 for (tab=prevtab;!tab->nseg; tab = tab->prevtab);
518 for (nexttab=tab->nexttab,i=2;!nexttab->nseg;nexttab=nexttab->nexttab,i++);
519 nexttab->seg = i;
520 tab->nseg = i;
521 tab->seg = 1;
522 }
523
524 return RETURN_OK;
525 }
526
527
528 /****** remove_tabs ************************************************************
529 PROTO int remove_tabs(catstruct *cat)
530 PURPOSE Remove all tables from a catalog.
531 INPUT Pointer to the catalog.
532 OUTPUT RETURN_OK if tabs were found, and RETURN_ERROR otherwise.
533 NOTES -.
534 AUTHOR E. Bertin (IAP & Leiden observatory)
535 VERSION 25/05/97
536 ***/
remove_tabs(catstruct * cat)537 int remove_tabs(catstruct *cat)
538
539 {
540 int t;
541
542 if (!cat->tab)
543 return RETURN_ERROR;
544
545 for (t=cat->ntab; t--;)
546 remove_tab(cat, "",0);
547
548 return RETURN_OK;
549 }
550
551
552 /****** update_tab ************************************************************
553 PROTO int update_tab(tabstruct *tab)
554 PURPOSE Update a table according to what's in the keys.
555 INPUT Table structure.
556 OUTPUT RETURN_OK if tab is a binary table, or RETURN_ERROR otherwise.
557 NOTES The headbuf pointer in the catstruct might be reallocated.
558 AUTHOR E. Bertin (IAP & Leiden observatory)
559 VERSION 08/02/97
560 ***/
update_tab(tabstruct * tab)561 int update_tab(tabstruct *tab)
562
563 {
564 tabstruct *keytab;
565 keystruct *key;
566 int i,j, nobj, nbytes;
567
568 /*Just pass if not a binary table*/
569 if ((tab->naxis != 2)
570 || (tab->bitpix!=8)
571 || strncmp(tab->xtension, "BINTABLE", 8))
572 return RETURN_ERROR;
573
574 /*Well, not much to do if there are no keys!*/
575 if (!(key = tab->key))
576 return RETURN_OK;
577
578 nobj = -1;
579 keytab = NULL;
580 nbytes = 0;
581 for (i=tab->nkey; i--;)
582 {
583 if (keytab && !key->ptr && key->tab != keytab)
584 error(EXIT_FAILURE, "*Error*: wrong reference table in ",
585 key->name);
586 if (nobj!=-1 && (nobj != key->nobj))
587 error(EXIT_FAILURE, "*Error*: wrong number of elements in key ",
588 key->name);
589 keytab = key->tab;
590 nobj = key->nobj;
591 /*-- If the number of bytes per element is not set, recover it */
592 if (!key->nbytes)
593 {
594 key->nbytes = t_size[key->ttype];
595 for (j=key->naxis; j--;)
596 key->nbytes *= key->naxisn[j];
597 }
598 nbytes += key->nbytes;
599 key = key->nextkey;
600 }
601
602 tab->tabsize = nobj*nbytes;
603 tab->naxisn[0] = nbytes;
604 tab->naxisn[1] = nobj;
605 tab->tfields = tab->nkey;
606
607 return RETURN_OK;
608 }
609
610
611 /****** name_to_tab ***********************************************************
612 PROTO tabstruct *name_to_tab(catstruct *cat, char *tabname, int seg)
613 PURPOSE Name search of a table in a catalog.
614 INPUT Pointer to the catalog,
615 Table name,
616 Table segment (0 = first).
617 OUTPUT The table pointer if the name was matched, and NULL otherwise.
618 NOTES -
619 VERSION 12/06/2001
620 ***/
name_to_tab(catstruct * cat,char * tabname,int seg)621 tabstruct *name_to_tab(catstruct *cat, char *tabname, int seg)
622
623 {
624 tabstruct *tab;
625 int i;
626
627 if (!(tab = cat->tab))
628 return NULL;
629
630 for (i=cat->ntab; strcmp(tabname,tab->extname) && i--;)
631 while (!(tab=tab->nexttab)->nseg);
632
633 if (i<0)
634 return NULL;
635
636 if (seg)
637 {
638 for (;tab->seg!=seg && !tab->nexttab->nseg; tab=tab->nexttab);
639 return tab->seg==seg?tab:NULL;
640 }
641
642 return tab;
643 }
644
645
646 /****** pos_to_tab *************************************************************
647 PROTO tabstruct *pos_to_tab(catstruct *cat, int pos, int seg)
648 PURPOSE Position search of a table in a catalog.
649 INPUT Pointer to the catalog,
650 Position of the table,
651 Table segment (0 = first).
652 OUTPUT The table pointer if the table exists at the given position, and the
653 pointer to the primary ``table'' otherwise.
654 NOTES pos = 1 means the first table after the primary one.
655 AUTHOR E. Bertin (IAP & Leiden observatory)
656 VERSION 15/02/96
657 ***/
pos_to_tab(catstruct * cat,int pos,int seg)658 tabstruct *pos_to_tab(catstruct *cat, int pos, int seg)
659
660 {
661 tabstruct *tab;
662 int i;
663
664 tab = cat->tab;
665 for (i=0; i!=pos && i<cat->ntab; i++)
666 while (!(tab=tab->nexttab)->nseg);
667
668 if (seg)
669 for (;tab->seg!=seg && !tab->nexttab->nseg; tab=tab->nexttab);
670
671 return i<cat->ntab?tab:cat->tab;
672 }
673
674 /****** tabs_list **************************************************************
675 PROTO char **tabs_list(catstruct *cat, int *n)
676 PURPOSE List all tables in a catalog.
677 INPUT Pointer to the catalog,
678 Pointer to the number of names in that list.
679 OUTPUT A list of all table names.
680 NOTES -.
681 AUTHOR E.R. Deul (Leiden observatory)
682 VERSION ??/??/96
683 ***/
tabs_list(catstruct * cat,int * n)684 char **tabs_list(catstruct *cat, int *n)
685
686 {
687 tabstruct *tab;
688 int i;
689 char **names;
690
691 tab = cat->tab;
692 QCALLOC(names, char *, cat->ntab);
693 for (i=0; i<cat->ntab; i++) {
694 QCALLOC(names[i], char, MAXCHARS);
695 strcpy(names[i],tab->extname);
696 while (!(tab=tab->nexttab)->nseg);
697 }
698 *n = cat->ntab;
699 return names;
700 }
701
702 /****** tabs_row_len ***********************************************************
703 PROTO int tab_row_len(char *file, char *tabname)
704 PURPOSE Return the row length in bytes of a given table in a given catalog.
705 INPUT File pointer.
706 OUTPUT Table size (bytes)
707 NOTES -.
708 AUTHOR E.R. Deul (Leiden observatory)
709 VERSION 05/06/200`
710 ***/
tab_row_len(char * file,char * tabname)711 int tab_row_len(char *file, char *tabname)
712
713 {
714 catstruct *tcat;
715 tabstruct *tab;
716 int retcode = -1;
717
718 if ((tcat = read_cat(file)) != NULL) {
719 if ((tab = name_to_tab(tcat, tabname, 0)) != NULL) {
720 retcode = tab->naxisn[0];
721 free_tab(tab);
722 }
723 close_cat(tcat);
724 free_cat(&tcat,1);
725 }
726 return retcode;
727 }
728
729