(root)/
gawk-5.2.2/
extension/
revoutput.c
       1  /*
       2   * revoutput.c --- Provide an output wrapper that reverses lines.
       3   *
       4   * Arnold Robbins
       5   * arnold@skeeve.com
       6   * Written 8/2012
       7   */
       8  
       9  /*
      10   * Copyright (C) 2012, 2013, 2015, 2018 the Free Software Foundation, Inc.
      11   *
      12   * This file is part of GAWK, the GNU implementation of the
      13   * AWK Programming Language.
      14   *
      15   * GAWK is free software; you can redistribute it and/or modify
      16   * it under the terms of the GNU General Public License as published by
      17   * the Free Software Foundation; either version 3 of the License, or
      18   * (at your option) any later version.
      19   *
      20   * GAWK is distributed in the hope that it will be useful,
      21   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      22   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      23   * GNU General Public License for more details.
      24   *
      25   * You should have received a copy of the GNU General Public License
      26   * along with this program; if not, write to the Free Software
      27   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
      28   */
      29  
      30  #ifdef HAVE_CONFIG_H
      31  #include <config.h>
      32  #endif
      33  
      34  #include <stdio.h>
      35  #include <stdlib.h>
      36  #include <string.h>
      37  #include <unistd.h>
      38  
      39  #include <sys/types.h>
      40  #include <sys/stat.h>
      41  
      42  #include "gawkapi.h"
      43  
      44  #include "gettext.h"
      45  #define _(msgid)  gettext(msgid)
      46  #define N_(msgid) msgid
      47  
      48  static const gawk_api_t *api;	/* for convenience macros to work */
      49  static awk_ext_id_t ext_id;
      50  static const char *ext_version = "revoutput extension: version 1.1";
      51  
      52  static awk_bool_t init_revoutput(void);
      53  static awk_bool_t (*init_func)(void) = init_revoutput;
      54  
      55  int plugin_is_GPL_compatible;
      56  
      57  /* rev_fwrite --- write out characters in reverse order */
      58  
      59  static size_t
      60  rev_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque)
      61  {
      62  	const char *cp = buf;
      63  	int nbytes = size * count;
      64  
      65  	(void) opaque;
      66  
      67  	for (; nbytes >= 1; nbytes--)
      68  		putc(cp[nbytes-1], fp);
      69  
      70  	return (size * count);
      71  }
      72  
      73  
      74  /* revoutput_can_take_file --- return true if we want the file */
      75  
      76  static awk_bool_t
      77  revoutput_can_take_file(const awk_output_buf_t *outbuf)
      78  {
      79  	awk_value_t value;
      80  
      81  	if (outbuf == NULL)
      82  		return awk_false;
      83  
      84  	if (! sym_lookup("REVOUT", AWK_NUMBER, & value))
      85  		return awk_false;
      86  
      87  	return (value.num_value != 0);
      88  }
      89  
      90  /*
      91   * revoutput_take_control_of --- set up output wrapper.
      92   * We can assume that revoutput_can_take_file just returned true,
      93   * and no state has changed since then.
      94   */
      95  
      96  static awk_bool_t
      97  revoutput_take_control_of(awk_output_buf_t *outbuf)
      98  {
      99  	if (outbuf == NULL)
     100  		return awk_false;
     101  
     102  	outbuf->gawk_fwrite = rev_fwrite;
     103  	outbuf->redirected = awk_true;
     104  	return awk_true;
     105  }
     106  
     107  static awk_output_wrapper_t output_wrapper = {
     108  	"revoutput",
     109  	revoutput_can_take_file,
     110  	revoutput_take_control_of,
     111  	NULL
     112  };
     113  
     114  /* init_revoutput --- set things ups */
     115  
     116  static awk_bool_t
     117  init_revoutput()
     118  {
     119  	awk_value_t value;
     120  
     121  	register_output_wrapper(& output_wrapper);
     122  
     123  	if (! sym_lookup("REVOUT", AWK_SCALAR, & value)) {
     124  		/* only install it if not there, e.g. -v REVOUT=1 */
     125  		make_number(0.0, & value);	/* init to false */
     126  		if (! sym_update("REVOUT", & value)) {
     127  			warning(ext_id, _("revoutput: could not initialize REVOUT variable"));
     128  
     129  			return awk_false;
     130  		}
     131  	}
     132  
     133  	return awk_true;
     134  }
     135  
     136  static awk_ext_func_t func_table[] = {
     137  	{ NULL, NULL, 0, 0, awk_false, NULL }
     138  };
     139  
     140  /* define the dl_load function using the boilerplate macro */
     141  
     142  dl_load_func(func_table, revoutput, "")