gawk: Output Wrappers
1
1 16.4.5.5 Customized Output Wrappers
1 ...................................
1
1 An "output wrapper" is the mirror image of an input parser. It allows
1 an extension to take over the output to a file opened with the '>' or
1 '>>' I/O redirection operators (⇒Redirection).
1
1 The output wrapper is very similar to the input parser structure:
1
1 typedef struct awk_output_wrapper {
1 const char *name; /* name of the wrapper */
1 awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);
1 awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);
1 awk_const struct awk_output_wrapper *awk_const next; /* for gawk */
1 } awk_output_wrapper_t;
1
1 The members are as follows:
1
1 'const char *name;'
1 This is the name of the output wrapper.
1
1 'awk_bool_t (*can_take_file)(const awk_output_buf_t *outbuf);'
1 This points to a function that examines the information in the
1 'awk_output_buf_t' structure pointed to by 'outbuf'. It should
1 return true if the output wrapper wants to take over the file, and
1 false otherwise. It should not change any state (variable values,
1 etc.) within 'gawk'.
1
1 'awk_bool_t (*take_control_of)(awk_output_buf_t *outbuf);'
1 The function pointed to by this field is called when 'gawk' decides
1 to let the output wrapper take control of the file. It should fill
1 in appropriate members of the 'awk_output_buf_t' structure, as
1 described next, and return true if successful, false otherwise.
1
1 'awk_const struct output_wrapper *awk_const next;'
1 This is for use by 'gawk'; therefore it is marked 'awk_const' so
1 that the extension cannot modify it.
1
1 The 'awk_output_buf_t' structure looks like this:
1
1 typedef struct awk_output_buf {
1 const char *name; /* name of output file */
1 const char *mode; /* mode argument to fopen */
1 FILE *fp; /* stdio file pointer */
1 awk_bool_t redirected; /* true if a wrapper is active */
1 void *opaque; /* for use by output wrapper */
1 size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,
1 FILE *fp, void *opaque);
1 int (*gawk_fflush)(FILE *fp, void *opaque);
1 int (*gawk_ferror)(FILE *fp, void *opaque);
1 int (*gawk_fclose)(FILE *fp, void *opaque);
1 } awk_output_buf_t;
1
1 Here too, your extension will define 'XXX_can_take_file()' and
1 'XXX_take_control_of()' functions that examine and update data members
1 in the 'awk_output_buf_t'. The data members are as follows:
1
1 'const char *name;'
1 The name of the output file.
1
1 'const char *mode;'
1 The mode string (as would be used in the second argument to
1 'fopen()') with which the file was opened.
1
1 'FILE *fp;'
1 The 'FILE' pointer from '<stdio.h>'. 'gawk' opens the file before
1 attempting to find an output wrapper.
1
1 'awk_bool_t redirected;'
1 This field must be set to true by the 'XXX_take_control_of()'
1 function.
1
1 'void *opaque;'
1 This pointer is opaque to 'gawk'. The extension should use it to
1 store a pointer to any private data associated with the file.
1
1 'size_t (*gawk_fwrite)(const void *buf, size_t size, size_t count,'
1 ' FILE *fp, void *opaque);'
1 'int (*gawk_fflush)(FILE *fp, void *opaque);'
1 'int (*gawk_ferror)(FILE *fp, void *opaque);'
1 'int (*gawk_fclose)(FILE *fp, void *opaque);'
1 These pointers should be set to point to functions that perform the
1 equivalent function as the '<stdio.h>' functions do, if
1 appropriate. 'gawk' uses these function pointers for all output.
1 'gawk' initializes the pointers to point to internal "pass-through"
1 functions that just call the regular '<stdio.h>' functions, so an
1 extension only needs to redefine those functions that are
1 appropriate for what it does.
1
1 The 'XXX_can_take_file()' function should make a decision based upon
1 the 'name' and 'mode' fields, and any additional state (such as 'awk'
1 variable values) that is appropriate.
1
1 When 'gawk' calls 'XXX_take_control_of()', that function should fill
1 in the other fields as appropriate, except for 'fp', which it should
1 just use normally.
1
1 You register your output wrapper with the following function:
1
1 'void register_output_wrapper(awk_output_wrapper_t *output_wrapper);'
1 Register the output wrapper pointed to by 'output_wrapper' with
1 'gawk'.
1