1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
/**
* VOTCOPY -- Copy a VOTable to a different format.
*
* Usage:
* votcopp [-f <fmt>] [-o <fname>] <votable>
* Where
* -f <fmt> Output format (XML, CSV, TSV, HTML, etc)
* -h Print help summary
* -i <N> Indention at each level for VOTable output
* -o <fname> Name of output file
*
* --noheader Don't write a header
* --help Print help summary
*
* <votable> Name of input file to compress
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "votParse.h"
int votcopy (int argc, char **argv);
/**
* Program Main. This is just a wrapper around the interface routine.
*/
int
main (int argc, char **argv)
{
return votcopy (argc, argv);
}
/************************************************************************
* *
* VOTCOPY -- Copy a votable to a new format, converting format if *
* needed. *
* *
************************************************************************/
#define FORMATS "|vot|asv|bsv|csv|tsv|html|shtml|fits|xml"
#define VOT 0 /* A new VOTable */
#define ASV 1 /* ascii separated values */
#define BSV 2 /* bar separated values */
#define CSV 3 /* comma separated values */
#define TSV 4 /* tab separated values */
#define HTML 5 /* standalone HTML document */
#define SHTML 6 /* single HTML <table> */
#define FITS 7 /* FITS binary table */
#define XML 8 /* VOTable alias */
#define SZ_FORMAT 32
char *fmt = NULL; /* format string */
int vot = 0; /* VOTable root handle */
int indent = 0; /* indention at each level */
int ofmt = CSV; /* format */
int hdr = TRUE;
static int strdic (char *in_str, char *out_str, int maxchars, char *dict);
/**
* Application entry point.
*/
int
votcopy (int argc, char **argv)
{
register int i;
int stat = OK;
char *ifname = NULL, *name = NULL, *ofname = NULL, format[SZ_FORMAT];
/* Parse the argument list.
*/
if (argc < 2) {
fprintf (stderr, "Usage: votcopy [-o <fname>] [-f <fmt>] <votable>\n");
return (1);
} else if (argc >= 2) {
for (i=1; i < argc; i++) {
if (argv[i][0] == '-' && strlen (argv[i]) > 1) {
switch (argv[i][1]) {
case 'f': fmt = argv[++i]; break;
case 'i': indent = atoi (argv[++i]); break;
case 'o': name = argv[++i]; break;
default:
fprintf (stderr, "Invalid argument '%c'\n", argv[i][1]);
return (1);
}
} else
ifname = argv[i];
}
}
ofname = (name ? name : "stdout");
/* Open and parse the input table.
*/
if ( (vot = vot_openVOTABLE (ifname) ) <= 0) {
fprintf (stderr, "Error opening VOTable '%s'\n", ifname);
return (ERR);
}
/* Output the new format.
*/
switch (strdic (fmt, format, SZ_FORMAT, FORMATS)) {
case VOT: vot_writeVOTable (vot, ofname, indent); break;
case ASV: vot_writeASV (vot, ofname); break;
case BSV: vot_writeBSV (vot, ofname); break;
case CSV: vot_writeCSV (vot, ofname); break;
case TSV: vot_writeTSV (vot, ofname); break;
case HTML: vot_writeHTML (vot, ifname, ofname); break;
case SHTML: vot_writeSHTML (vot, ifname, ofname); break;
case FITS: vot_writeFITS (vot, ofname); break;
case XML: vot_writeVOTable (vot, ofname, indent); break;
default:
fprintf (stderr, "Unknown output format '%s'\n", format);
stat = ERR;
}
vot_closeVOTABLE (vot); /* close the table */
return (stat);
}
/**
* STRDIC -- Search a dictionary string for a match with an input string.
* The input string may be an abbreviation of a dictionary entry, however,
* it is an error if the abbreviation is not unique. The entries in the
* dictionary string are separated by a delimiter character which is the
* first character of the dictionary string. The full name of the matched
* dictionary entry found is returned in out_str; the function value is
* the word index of the dictionary entry. The output string may be the
* same as the input string.
*/
#include <ctype.h>
static int strdic (
char *in_str, /* Input string, always lower case */
char *out_str, /* Output string as found in dictionary */
int maxchars, /* Maximum length of output string */
char *dict /* Dictionary string */
)
{
char ch, fch;
int start, len, ip, i, match, entry;
if (dict == NULL || dict[0] == '\0')
return (0);
for (i=0; isspace(in_str[i]); i++)
;
start = i;
match = 0;
ip = 1;
len = strlen (&in_str[start]);
fch = in_str[start];
/* Search the dictionary string. If the input string matches a
* dictionary entry it is either an exact match (len = dictionary
* entry length) or a legal abbreviation. If an abbreviation
* matches two entries it is ambiguous and an error.
*/
for (entry=0; dict[ip] != '\0'; entry=entry+1) {
if (dict[ip] == fch) {
if (strncmp (&dict[ip], &in_str[start], len) == 0) {
for (i=0; i < maxchars; i++) {
ch = dict[ip+i-1];
if ((ch == dict[0]) || (ch == '\0'))
break;
out_str[i] = ch;
}
out_str[i] = '\0';
if ((dict[ip+len] == dict[0]) || (dict[ip+len] == '\0'))
return (entry); /* exact match */
else {
/* If we already have a match and the new match is not
* exact, then the abbreviation is ambiguous.
*/
if (match != 0)
return (0);
else
match = entry;
}
}
}
do {
ip = ip + 1;
} while (dict[ip-1] != dict[0] && dict[ip] != '\0');
}
return (match);
}
|