From owner-freebsd-questions@FreeBSD.ORG Fri Dec 18 11:22:17 2009 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 967B11065692 for ; Fri, 18 Dec 2009 11:22:17 +0000 (UTC) (envelope-from nb@ravenbrook.com) Received: from raven.ravenbrook.com (raven.ravenbrook.com [193.164.110.8]) by mx1.freebsd.org (Postfix) with ESMTP id 20A4C8FC08 for ; Fri, 18 Dec 2009 11:22:16 +0000 (UTC) Received: from thrush.ravenbrook.com (thrush.ravenbrook.com [193.164.110.145]) by raven.ravenbrook.com (8.14.3/8.14.2) with ESMTP id nBIBM6J3034023; Fri, 18 Dec 2009 11:22:06 GMT (envelope-from nb@ravenbrook.com) Received: from thrush.ravenbrook.com (localhost [127.0.0.1]) by thrush.ravenbrook.com (8.13.4/8.13.4) with ESMTP id nBIBM6cM011405; Fri, 18 Dec 2009 11:22:06 GMT (envelope-from nb@thrush.ravenbrook.com) From: Nick Barnes To: Giorgos Keramidas In-Reply-To: <87d42cve53.fsf@kobe.laptop> from Giorgos Keramidas of "Fri, 18 Dec 2009 11:13:12 +0200" Date: Fri, 18 Dec 2009 11:22:06 +0000 Message-ID: <11404.1261135326@thrush.ravenbrook.com> Sender: nb@ravenbrook.com X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.3 (raven.ravenbrook.com [193.164.110.8]); Fri, 18 Dec 2009 11:22:07 +0000 (GMT) X-Virus-Scanned: ClamAV 0.94.1/10197/Fri Dec 18 01:59:38 2009 on raven.ravenbrook.com X-Virus-Status: Clean X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on raven.ravenbrook.com X-Spam-Level: X-Spam-Status: No, score=-4.0 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.2.5 Cc: Anton Shterenlikht , freebsd-questions@freebsd.org Subject: Re: editing a binary file X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Dec 2009 11:22:17 -0000 If your Fortran file has the same word size and enddian-ness as your C, this simple program convert.c will strip all the record length fields. I just knocked it up now, no warranty, etc, but it works for me. Use as a pipe: $ ls convert.c test.f $ gcc -Wall -Werror -ansi -pedantic convert.c -o convert $ gfortran44 test.f -o test $ ./test $ ls -l test-output -rw-r--r-- 1 nb nb 2460 Dec 18 11:17 test-output $ ./convert < test-output > test-converted $ ls -l test-converted -rw-r--r-- 1 nb nb 2420 Dec 18 11:18 test-converted $ The code does a fair amount of checking; if you get one of the error messages, let us know. The most obvious unchecked problem is a short read, which will complain about mismatched lengths. If your Fortran has different word sizes or enddian-ness (e.g. most of the Fortran output files I use on the Clear Climate Code project are generated on big-endian machines), you will need to add code to tweak the 'size' value after reading it, and when checking the record-end marker. Nick B /* convert.c: remove record length fields from Fortran output file. */ /* Nick Barnes, Ravenbrook Limited, 2009-12-18 */ #include #include #include #include int main(void) { long size; char *buf; ssize_t bytes; assert(sizeof(size) == 4); while(bytes = read(0, (void*)&size, sizeof(size))) { if (bytes < 0) { fprintf(stderr, "read() returned %ld\n", bytes); exit(1); } if (size <= 0) { fprintf(stderr, "Read bad record length %ld\n", size); exit(1); } buf = (char*)malloc(size + sizeof(size)); if (!buf) { fprintf(stderr, "Couldn't allocate buffer of %ld bytes\n", size + sizeof(size)); exit(1); } bytes = read(0, buf, size + sizeof(size)); if (bytes <= 0) { fprintf(stderr, "read() returned %ld\n", bytes); exit(1); } if ((*(long*)(buf+size)) != size) { fprintf(stderr, "Mismatched record lengths: %ld, %ld\n", size, *(long*)(buf+size)); exit(1); } write(1, buf, size); free(buf); } return 0; }