#!/bin/sh
# function.sh    10/2024    Public Domain   Wesley Ebisuzaki
#
# wgrib2 options are translated into function calls.
#  this script reads the source code and finds all the options
#  and creates the header for the options (fnlist.h) and
#  a structure that associates the name of the option with
#   the address of the option, number of arguements, option type,
#   brief description and a integer which is the prority in
#   the help screens (fnlist.c)
#
# function.sh makes fnlist.c, fnlist.h
#
# needs to be rerun when adding new options, option headers are changed
#
# all information for fnlist.c and fnlist.h are in the HEADER line
#
# set -x

# get list of all functions that are associated with options

export LC_ALL=C
grep "^ \* HEADER:" [A-Z]*.c | cut -f3- -d: | sort -t: -k3,3 -k2,2 >fnlist

cat >fnlist.c <<EOF
#include <stdio.h>
#include <stdlib.h>
#include "wgrib2.h"
#include "fnlist.h"

/* this file was generated by function.sh */

struct function functions[] = {
EOF

#  enum fntype {inv, output, inv_output, misc, setup, If, Else, Elseif, Endif};

cat >fnlist.h <<EOF
/* headers wgrib2 options */

/* this file was generated by function.sh */

struct function {const char *name; int (*fn)(ARG8); enum fntype type; int nargs; const char *desc; int sort;};

extern struct function functions[];

extern int nfunctions;

EOF


{
   read line
   while [ "$line" != "" ]
   do
      sort="`echo $line | cut -f1 -d:`"
      v="`echo $line | cut -f2 -d:`"
#     check for alias
      if [ `echo "$v" | grep -c =` -eq 0 ] ; then
          var="$v";
          var1="f_`echo "$v" | sed -e 's/\./_/g'`"
      else
          var=`echo "$v" | sed 's/=.*//'`
          var1=`echo "$v" | sed 's/.*=//'`
      fi
echo "var=$v $var $var1"
      type="`echo $line | cut -f3 -d:`"
      nargs="`echo $line | cut -f4 -d:`"
      desc="`echo $line | cut -f5- -d:`"
#      echo " var=$var  type=$type  desc=($desc)"
      echo "   {\"$var\",$var1, $type, $nargs, \"$desc\", $sort}," >>fnlist.c

      t="int $var1(int mode, unsigned char **sec, float *data, unsigned int ndata, char *inv, void **local"

      arg=1
      while [ $nargs -gt 0 ] ; do
          t="$t, const char *arg$arg"
          nargs="`expr $nargs - 1`"
          arg=`expr $arg + 1`
      done
      t="$t);"
#       echo "$t"
      ARG="ARG`expr $arg - 1`"
      echo "int $var1($ARG);" >> fnlist.h
      read line
   done
} < fnlist

grep "^ \* HEADER:" ../extra/[A-Z]*.c | cut -f3- -d: | sort -t: -k3,3 -k2,2 >fnlist_extra

echo "   #ifdef BUILD_EXTRA" >>fnlist.c

{
   read line
   while [ "$line" != "" ]
   do
      sort="`echo $line | cut -f1 -d:`"
      v="`echo $line | cut -f2 -d:`"
#     check for alias
      if [ `echo "$v" | grep -c =` -eq 0 ] ; then
          var="$v";
          var1="f_`echo "$v" | sed -e 's/\./_/g'`"
      else
          var=`echo "$v" | sed 's/=.*//'`
          var1=`echo "$v" | sed 's/.*=//'`
      fi
echo "var=$v $var $var1"
      type="`echo $line | cut -f3 -d:`"
      nargs="`echo $line | cut -f4 -d:`"
      desc="`echo $line | cut -f5- -d:`"
#      echo " var=$var  type=$type  desc=($desc)"
      echo "   {\"$var\",$var1, $type, $nargs, \"$desc\", $sort}," >>fnlist.c

      t="int $var1(int mode, unsigned char **sec, float *data, unsigned int ndata, char *inv, void **local"

      arg=1
      while [ $nargs -gt 0 ] ; do
          t="$t, const char *arg$arg"
          nargs="`expr $nargs - 1`"
          arg=`expr $arg + 1`
      done
      t="$t);"
#       echo "$t"
      echo "$t" >> fnlist.h
      read line
   done
} < fnlist_extra

echo "   #endif" >>fnlist.c
echo "};" >>fnlist.c

echo " " >> fnlist.c
echo "int nfunctions = sizeof functions / sizeof functions[0];" >> fnlist.c
rm fnlist
