-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.cpp
121 lines (106 loc) · 3.9 KB
/
main.cpp
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
#include <iostream>
#include <vector>
#include <sstream>
#include <iomanip>
#include <boost/filesystem/operations.hpp>
#include "DbfTable.h"
#include "Version.h"
using namespace std;
typedef enum Mode {
kVersion,
kSummary,
kCsv
} Mode;
void print_usage() {
cout << "usage: dbf2csv [-h|-v|-s|-c|-k] filename" << endl;
cout << " -a = append CSV header and data (format: '<header><separator><data>', separator: \\t, \\r, \\n, ;)" << endl;
cout << " -c = create a CSV file" << endl;
cout << " -h = print this message" << endl;
cout << " -k = skip deleted records (default: true)" << endl;
cout << " -l = output csv header names in lowercase (default: false)" << endl;
cout << " -s = print summary information" << endl;
cout << " -v = print the program version" << endl;
}
int main(int argc, char *argv[]) {
Mode mode = kVersion;
bool skip_deleted = true;
bool lowercase_header_names = false;
std::string append_csv_header;
std::string append_csv_data;
int opt;
while ((opt = getopt(argc, argv, "a:chk:l:sv")) != -1) {
switch (opt) {
case 'a': {
std::vector<std::string> parts;
boost::split(parts, optarg, boost::is_any_of("\t\r\n;"));
if (parts.size() == 2) {
append_csv_header = parts[0];
append_csv_data = parts[1];
}
else {
cerr << "Invalid append option: '" << optopt << "'" << endl;
return 1;
}
break;
}
case 'c':
mode = kCsv;
break;
case 'h':
print_usage();
return 0;
case 'k':
skip_deleted = (optarg[0] == 'Y' || optarg[0] == 'y');
break;
case 'l':
lowercase_header_names = (optarg[0] == 'Y' || optarg[0] == 'y');
break;
case 's':
mode = kSummary;
break;
case 'v':
mode = kVersion;
break;
default:
cerr << "Unrecognized option: '" << optopt << "'" << endl;
print_usage();
return 1;
}
}
if (mode == kVersion) {
cout << "dbf2csv version: " << Version << endl;
print_usage();
return 0;
}
string dbf_filename = argv[optind];
DbfTablePtr dbf_table = DbfTablePtr(new DbfTable(dbf_filename, skip_deleted));
if (!dbf_table->good()) {
cerr << "Unable to open file: " << dbf_filename << endl;
return 1;
}
if (mode == kSummary) {
cout << "Database: " << dbf_filename << endl;
const DbfHeaderPtr header = dbf_table->header();
cout << "Type: (" << hex << header->version() << dec << ") " << header->version_description() << endl;
cout << "Memo File: " << (dbf_table->has_memo_file() ? "true" : "false") << endl;
cout << "Records: " << header->record_count() << endl;
cout << "Last updated at: " << header->updated_at() << endl;
cout << endl;
cout << "Fields:" << endl;
cout << "Name Type Length Decimal" << endl;
cout << "------------------------------------------------------------------------------" << endl;
std::vector<DbfColumnPtr> columns = dbf_table->columns();
for (auto it = std::begin(columns); it != std::end(columns); ++it) {
DbfColumnPtr column(*it);
cout << left << setw(17) << column->name();
cout << left << setw(11) << (char)column->type();
cout << left << setw(11) << column->length();
cout << left << column->decimal();
cout << endl;
}
}
else {
dbf_table->to_csv(cout, lowercase_header_names, append_csv_header, append_csv_data);
}
return 0;
}