[segyio] 315/376: Add applications/segycath
Jørgen Kvalsvik
jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:51 UTC 2017
This is an automated email from the git hooks/post-receive script.
jokva-guest pushed a commit to branch debian
in repository segyio.
commit 6bfdcaaa2e52d11ab6e6b5e405ccaf4c077c3f1a
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date: Mon Jun 26 14:34:41 2017 +0200
Add applications/segycath
The segycath program is a simple cat-like program that prints textual
and extended headers to stdout or to file.
---
applications/CMakeLists.txt | 14 ++++
applications/segycath.c | 168 ++++++++++++++++++++++++++++++++++++++++++++
cmake/check_includes.cmake | 6 +-
3 files changed, 186 insertions(+), 2 deletions(-)
diff --git a/applications/CMakeLists.txt b/applications/CMakeLists.txt
index b3728df..85823dc 100644
--- a/applications/CMakeLists.txt
+++ b/applications/CMakeLists.txt
@@ -1,5 +1,10 @@
project(segyio-apps)
+if( NOT HAVE_GETOPT_H OR NOT HAVE_GETOPT_LONG )
+ message(WARNING "Could not find getopt. Not building applications.")
+ return ()
+endif ()
+
if (NOT MSVC)
set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}")
endif()
@@ -10,5 +15,14 @@ target_link_libraries(segyinfo segyio)
add_executable(segyinspect segyinspect.c)
target_link_libraries(segyinspect segyio)
+add_executable(segycath segycath.c)
+target_link_libraries(segycath segyio)
+target_compile_definitions(segycath PRIVATE
+ -Dsegyio_MAJOR=${segyio_MAJOR}
+ -Dsegyio_MINOR=${segyio_MINOR}
+)
+
install(TARGETS segyinfo DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(TARGETS segyinspect DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
+
+install(TARGETS segycath DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/applications/segycath.c b/applications/segycath.c
new file mode 100644
index 0000000..0b48616
--- /dev/null
+++ b/applications/segycath.c
@@ -0,0 +1,168 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include <segyio/segy.h>
+
+static int help() {
+ puts( "Usage: segycath [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 ouput 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 printversion() {
+ printf( "segycath (segyio version %d.%d)\n", segyio_MAJOR, segyio_MINOR );
+ 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;
+
+ int32_t ext;
+ err = segy_get_bfield( binary, SEGY_BIN_EXT_HEADERS, &ext );
+ if( err ) return -2;
+ return ext;
+}
+
+static int exit_error( int errcode, const char* msg ) {
+ if( !msg ) return errcode;
+
+ fputs( msg, stderr );
+ fputc( '\n', stderr );
+ return errcode;
+}
+
+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': return 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 ) return exit_error( errno, "Unable to alloc" );
+ num = re;
+ }
+
+ num[ num_sz ] = strtol( optarg, &endptr, 10 );
+ if( *endptr != '\0' )
+ return exit_error( EINVAL, "num must be an integer" );
+ if( num[ num_sz ] < 0 )
+ return exit_error( EINVAL, "num must be non-negative" );
+ break;
+
+ default: return help();
+ }
+ }
+
+ if( version ) return printversion();
+
+ char header[ SEGY_TEXT_HEADER_SIZE + 1 ] = { 0 };
+
+ for( int i = optind; i < argc; ++i ) {
+ segy_file* fp = segy_open( argv[ i ], "r" );
+
+ if( !fp ) fprintf( stderr, "segycath: %s: No such file or directory\n",
+ argv[ i ] );
+
+ if( !fp && strict ) return exit_error( errno, NULL );
+ if( !fp ) continue;
+
+ if( num_sz == 0 ) num_sz = 1;
+
+ const int exts = ext_headers( fp );
+ if( exts < 0 )
+ return exit_error( errno, "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 ) return exit_error( 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 ) )
+ return exit_error( 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 ) return exit_error( errno, "Unable to read header" );
+ print_header( header );
+ }
+
+ segy_close( fp );
+ }
+
+ free( num );
+ return 0;
+}
diff --git a/cmake/check_includes.cmake b/cmake/check_includes.cmake
index 01e64b8..6224c27 100644
--- a/cmake/check_includes.cmake
+++ b/cmake/check_includes.cmake
@@ -3,8 +3,10 @@ include(CheckFunctionExists)
# Portability checks; look for htons function
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
-check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
-check_include_file("winsock2.h" HAVE_WINSOCK2_H)
+check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
+check_include_file("winsock2.h" HAVE_WINSOCK2_H)
+check_include_file("getopt.h" HAVE_GETOPT_H)
+check_function_exists(getopt_long HAVE_GETOPT_LONG)
if (HAVE_NETINET_IN_H)
add_definitions("-DHAVE_NETINET_IN_H")
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git
More information about the debian-science-commits
mailing list