forked from equinor/segyio
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsegyio-cath.c
More file actions
161 lines (130 loc) · 5.05 KB
/
Copy pathsegyio-cath.c
File metadata and controls
161 lines (130 loc) · 5.05 KB
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
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include "apputils.c"
#include <segyio/segy.h>
static int help(void) {
puts( "Usage: segyio-cath [OPTION]... [FILE]...\n"
"Concatenate the textual header(s) from FILE(s) to standard output.\n"
"\n"
"-n, --num the textual header to show, starts at 0\n"
"-a, --all all textual headers\n"
"-s, --strict abort if a header or file is not found\n"
" primarily meant for shell scripts\n"
"-S, --nonstrict ignore missing headers\n"
" this is the default behaviour\n"
" --version output version information and exit\n"
" --help display this help and exit\n"
"\n"
"By default, only the non-extended header is printed, which is\n"
"equivalent to --num 0\n"
);
return 0;
}
static int ext_headers( segy_file* fp ) {
char binary[ SEGY_BINARY_HEADER_SIZE ];
int err = segy_binheader( fp, binary );
if( err ) return -1;
int ext;
err = segy_get_field_int( binary, SEGY_BIN_EXT_HEADERS, &ext );
if( err ) return -2;
return ext;
}
static void print_header( const char* header ) {
for( int line = 0, ch = 0; line < 40; ++line ) {
for( int c = 0; c < 80; ++c, ++ch ) putchar( header[ ch ] );
putchar( '\n' );
}
}
int main( int argc, char** argv ) {
static int all = false;
static int strict = false;
static int version = 0;
static struct option long_options[] = {
{ "num", required_argument, 0, 'n' },
{ "all", no_argument, &all, 1 },
{ "strict", no_argument, &strict, 1 },
{ "nonstrict", no_argument, &strict, 0 },
{ "version", no_argument, &version, 1 },
{ "help", no_argument, 0, 'h' },
{ 0, 0, 0, 0 }
};
int num_alloc_sz = 32;
int* num = calloc( sizeof( int ), num_alloc_sz );
int num_sz = 0;
while( true ) {
int option_index = 0;
int c = getopt_long( argc, argv, "n:asS",
long_options, &option_index );
if( c == -1 ) break;
char* endptr;
switch( c ) {
case 0: break;
case 'h': exit( help() );
case 's': strict = 1; break;
case 'S': strict = 0; break;
case 'a': all = 1; break;
case 'n':
if( version ) break;
if( num_sz == num_alloc_sz - 1 ) {
num_alloc_sz *= 2;
int* re = realloc( num, num_alloc_sz * sizeof( int ) );
if( !re ) exit( errmsg( errno, "Unable to alloc" ) );
num = re;
}
num[ num_sz ] = strtol( optarg, &endptr, 10 );
if( *endptr != '\0' )
exit( errmsg( EINVAL, "num must be an integer" ) );
if( num[ num_sz ] < 0 )
exit( errmsg( EINVAL, "num must be non-negative" ) );
break;
default:
exit( help() );
}
}
if( version ) exit( printversion( "segyio-cath" ) );
char header[ SEGY_TEXT_HEADER_SIZE + 1 ] = { 0 };
if( argc - optind < 1 )
exit( errmsg( 2, "missing file operand\n"
"Try 'segyio-cath --help' for more information." ) );
for( int i = optind; i < argc; ++i ) {
segy_file* fp = segy_open( argv[ i ], "r" );
if( !fp ) fprintf( stderr, "segyio-cath: %s: No such file or directory\n",
argv[ i ] );
if( !fp && strict ) exit( errmsg( 2, NULL ) );
if( !fp ) continue;
if( num_sz == 0 ) num_sz = 1;
const int exts = ext_headers( fp );
if( exts < 0 )
exit( errmsg( 1, "Unable to read binary header" ) );
if( all ) {
/* just create the list 0,1,2... as if it was passed explicitly */
if( exts >= num_alloc_sz ) {
num_alloc_sz = exts * 2;
int* re = realloc( num, num_alloc_sz * sizeof( int ) );
if( !re ) exit( errmsg( errno, "Unable to alloc" ) );
num = re;
}
num_sz = exts + 1;
num[ 0 ] = 0;
for( int j = 0; j < exts; ++j )
num[ j + 1 ] = j;
}
for( int j = 0; j < num_sz; ++j ) {
if( strict && ( num[ j ] < 0 || num[ j ] > exts ) )
exit( errmsg( EINVAL, "Header index out of range" ) );
if( num[ j ] < 0 || num[ j ] > exts ) continue;
int err = num[ j ] == 0
? segy_read_textheader( fp, header )
: segy_read_ext_textheader( fp, num[ j ] - 1, header );
if( err != 0 ) exit( errmsg( errno, "Unable to read header" ) );
print_header( header );
}
segy_close( fp );
}
free( num );
return 0;
}