[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