From Newsgroup: comp.lang.awk
In article <10qdg8r$3gdh5$
1@news.xmission.com>,
Kenny McCormack <
gazelle@shell.xmission.com> wrote:
In article <10q99ai$ph7$1@news.muc.de>, Alan Mackenzie <acm@muc.de> wrote: >>I think the Subject: line says it all. I have a text source file to >>convert into a binary output file. For example, I want to be able to >>output a 32-bit integer as a four byte little-endian binary integer.
Can AWK do this? (It is supposed to by Turing complete, isn't it?)
...
Now, if I were doing this myself, I'd write a short GAWK extension library >function that wraps the "fwrite" function, then use that. The gist of it
is that the extension lib would do:
fwrite(&num,4,1,stdout);
I would do it this way because I like AWK/GAWK a lot and would want to >continue using it and have no interest in learning any of those other >languages. You may or may not agree with me on this.
Since I had an hour to kill, I threw together the code shown below. Note
that it may have more includes than it needs and also other extraneous stuff; this is because every GAWK extension is just a copy of the previous one,
with the active code changed out. Note also that this is for GAWK 4.1;
since they keep changing the API, you may have to modify it if yuu are
using a different version of GAWK.
Usage would be like:
gawk4 -l ./fwrite32 'BEGIN { printf "12345678 in binary is: ";fwrite32(12345678);print "" }'
Developed under Linux, but I am told this stuff works seamlessly under
Windows GAWK as well. OP has yet to clarify which OS/environment he is
using.
--- Cut Here ---
/*
* fwrite32.c - Provide fwrite for GAWK
* Compile command:
gcc -shared -I.. -W -Wall -Werror -fPIC -o fwrite32.so fwrite32.c
*/
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <alloca.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdarg.h>
#include "gawkapi.h"
#define STR str_value.str
#define LEN str_value.len
static const gawk_api_t *api; /* for convenience macros to work */
static awk_ext_id_t *ext_id;
static const char *ext_version = "fwrite32 extension: version 1.0";
#include "lintwarn.h"
int plugin_is_GPL_compatible;
static int checkArgNum(char *fn_name,int nargs,int wantedArgs)
{
if (nargs == wantedArgs) return 0;
lintwarn(ext_id,"%s: wrong # of arguments (%d) - should be %d!",
fn_name,nargs,wantedArgs);
return 1;
}
/* do_fwrite32_version */
static awk_value_t *
do_fwrite32_version(int nargs, awk_value_t *result)
{
if (checkArgNum("fwrite32_version",nargs,0))
goto the_end;
return make_const_string(ext_version,strlen(ext_version),result);
the_end:
return make_const_string("<ERROR>",7,result);
}
/* do_fwrite32 */
static awk_value_t *
do_fwrite32(int nargs, awk_value_t *result)
{
awk_value_t arg;
int num;
if (nargs == 0) {
puts("fwrite32: Need at least one arg!");
goto the_end;
}
for (int i=0; i<nargs; i++) {
if (!get_argument(i, AWK_NUMBER , &arg)) {
lintwarn(ext_id,"fwrite32: Fatal error retrieving arg #%d!",i+1);
goto the_end;
}
num = arg.num_value;
fwrite(&num,4,1,stdout);
}
return make_number(0, result);
the_end:
return make_const_string("<ERROR>",7,result);
}
static awk_ext_func_t func_table[] = {
{ "fwrite32_version", do_fwrite32_version, 0 },
{ "fwrite32", do_fwrite32, 4 },
};
/* define the dl_load function using the boilerplate macro */
dl_load_func(func_table, fwrite32, "")
--- Cut Here ---
--
The randomly chosen signature file that would have appeared here is more than 4 lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/Mandela
--- Synchronet 3.21f-Linux NewsLink 1.2