-
Notifications
You must be signed in to change notification settings - Fork 1
/
convert_vms_vl.cxx
120 lines (115 loc) · 2.89 KB
/
convert_vms_vl.cxx
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
///
/// Convert VMS VL format file into UNIX format
/// @author Freddie Akeroyd, STFC ISIS Facility
///
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <unistd.h>
// convert 16 bit length field of VMS variable length(VL) to \n
int main(int argc, char* argv[])
{
std::fstream f;
int c;
opterr = 0;
bool nocc = false;
const char* cvalue = "\n";
while ((c = getopt (argc, argv, "nc:")) != -1)
switch (c)
{
case 'n':
nocc = true;
break;
case 'c':
switch(optarg[0])
{
case 'l':
cvalue = "\n";
break;
case 'm':
cvalue = "\r";
break;
case 'w':
cvalue = "\r\n";
break;
default:
cvalue = "\n";
break;
}
break;
case '?':
if (optopt == 'c')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return -1;
default:
return -1;
}
if ((argc - optind) < 1)
{
std::cerr << "No filename given" << std::endl;
return -1;
}
if (nocc)
{
cvalue = "\0";
}
const char* filein = argv[optind];
f.open(filein, std::ios::in | std::ios::binary);
if (!f.good())
{
std::cerr << "File open error for \"" << filein << "\"" << std::endl;
return -1;
}
f.seekg (0, f.end);
int length = f.tellg();
if (length % 2 != 0)
{
std::cerr << "File length not multiple of 2 bytes for file \"" << filein << "\"" << std::endl;
return -1;
}
f.seekg (0, f.beg);
char * buffer = new char [length+2];
f.read (buffer,length);
buffer[length] = '\0';
buffer[length+1] = '\0';
unsigned short* sbuffer = (unsigned short*)buffer;
int slength = length / 2;
int l, i;
for(i = 0; i < slength; )
{
l = sbuffer[i]; // record length in bytes
sbuffer[i] = cvalue[0] + 256 * cvalue[1]; // replace length with CC
i += 1; // length field
i += (l + 1) / 2; // record data, but padded to even byte number
if (l % 2 != 0)
{
buffer[2*i-1] = '\0'; // overwrite padding byte, probably already a NULL
}
}
if (i != slength)
{
std::cerr << "record length mismatch - maybe not OpenVMS VL file format? for file \"" << filein << "\"" << std::endl;
return -1;
}
for(i = 2; i < length; ++i)
{
switch(buffer[i])
{
case '\0':
break;
default:
std::cout << buffer[i];
break;
}
}
// add final CC
std::cout << cvalue;
return 0;
}