#!/bin/bash
#
#help
#Syntax:   portmanteau [srcedir] [outfile] 
#Function: Generate 'outfile' from rule definition files in 'srcedir'.
#          'srcedir' and 'outfile' default to the values defined
#          in portmanteau.conf
#Options:  none
#end

if [ "$1" == '-?' ]
then
	script_help $0
	exit 1
fi

CONFDIR="/etc /usr/local/etc ."
CONFIG=portmanteau.conf
CFOUND="no"
for c in $CONFDIR
do
	if [ -r $c/$CONFIG ]
	then
		CFOUND="yes"
		source $c/$CONFIG
	fi
done
if [ $CFOUND == 'no' ]
then
	echo "Error: $CONFIG not found in: $CONFDIR"
	exit 1
fi

srcedir=${1:-$SRCEDIR}
outfile=${2:-$OUTFILE}

if [ ! -d $srcedir ]
then
	echo "Error: can't find $srcedir"
	exit 1
fi

rm -rf $outfile
for f in $srcedir/*.def
do
   echo "Processing $f"
   cat $f | gawk '
   BEGIN       {
                 alt_count = 0;
                 caseless = "no";
                 described = "no";
                 describe_count = 0;
                 err_count = 0;
                 meta_used = "no"; 
                 meta_count = 0; 
                 scan_count = 0;
                 score = 1.0;
                 tflags_used = "no";
                 wordlim = "no";
               }
   /^#/        { print $0; next; }
   /^rule/     { rule = $2; next; }
   /^describe/ { if (length(rule) == 0)
                 { error("no rule name supplied"); }

                 printf("describe %s", rule);
                 for (i = 2; i <= NF; i++)
                 { 
                   printf(" %s", $i); 
                   desc_count++; 
                 }

                 printf("\n");
                 if (desc_count == 0)
                 { error("blank description supplied"); }

                 described = "yes";
                 next;
               }
   /^score/    { score = $2; next; }
   /^wordlim/  { wordlim = $2; next; }
   /^caseless/ { caseless = $2; next; }
   /^meta/     { meta = $2; meta_used = "yes"; next; }
   /^tflags/   { tflags = $2; tflags_used = "yes"; next; }
   /^scan/     {
                 scan = $2;
                 if (described == "no")
                 { error("no description supplied") };

                 if (scan == "header")
		 { header = $3; }
                 else
                 { header = ""; }

                 close_test();
                 open_test();
                 scan_count++;
                 next; 
               }

               {
                 if (NF == 0)
                 { next; } 

                 if (first == "no")
                 { printf("|"); }

                 printf("%s", $0);
                 first="no";
                 alt_count++;
               }

   END         { 
                 close_test();
                 if (length(rule) == 0)
                 { error("no rule name supplied") };

                 if (meta_used == "yes")
                 {
                   printf("meta     %s (", rule);
                   for (i = 0; i < meta_count; i++)
                   {
                     if (i > 0)
                     { printf("||"); }

                     printf("__%s%d", meta, i);
                   }

                   printf(")\n");
                 }
 
                 if (tflags_used == "yes")
                 { printf("tflags   %s %s\n", rule, tflags); }
 
                 printf("score    %s %s\n", rule, score); 
	         printf("\n"); 
                 if (scan_count < 1)
                 { error("no scan directives"); }

                 if (meta_used == "yes" && meta_count < 2)
                 { error("meta used but only one subrule found"); }

                 if (meta_used == "no" && scan_count > 1)
                 { 
                   fmt = "meta not used but %s subrules found";
                   error(sprintf(fmt, scan_count));
                 }

                 if (err_count > 0)
                 { 
                   error(sprintf("%d errors found", err_count));
                   exit(err_count - 1); 
                 }
               }

   function error(str)
   {
      printf("**** Error: %s ****\n", str);
      err_count++;
   }

   function open_test()
   {
      if (meta_used == "yes")
      { 
        printf("%-8s __%s%d ", scan, meta, meta_count);
        meta_count++;
      }
      else
      { printf("%-8s %s ", scan, rule); }

      
      if (scan == "header")
      {
          printf("%s =~ ", header);
      }

      printf("/");
      write_wordbreak();
      printf("(");
      generating="yes";
      first="yes";
      alt_count = 0;
   }

   function close_test()
   {
      if (generating=="yes")
      {
         printf(")");
         write_wordbreak();
         printf("/");
         if (caseless=="yes")
         {
            printf("i");
         }

         printf("\n");
         if (alt_count < 1)
         { error("no alternates found"); }
      }

      generating="no";
   }

   function write_wordbreak()
   {
      if (wordlim == "yes")
      {
         printf("\\b");
      }
   }
   ' >>$outfile
   err=$?
   if [ "$err" -ge 1 ]
   then
     echo "$err errors found"
   fi
done
