#!/usr/bin/mawk -We
# *********************************************************************
#  Written by and copyright Carlo Strozzi <carlos@linux.it>.
#
#  tabletoform: take a NoSQL table and use the values from the last
#		record to replace special tags on a template file.
#  Copyright (C) 2000-2001 Carlo Strozzi <carlos@linux.it>
# 
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
# 
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
# 
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#  2001-01-03 Ported to NoSQL v3
#  2001-01-07 Added option '-R'
#  2001-04-17 Added inline help
#  2001-06-02 Added file-encoding capabilities
#  2001-08-17 Added stdio portability
#
#  $Id$
# *********************************************************************

BEGIN {
  NULL = "" ; FS = OFS = "\t"

  while (ARGV[++i] != NULL) {
    if (ARGV[i] == "-p" || ARGV[i] == "--prefix") prefix = ARGV[++i]
    else if (ARGV[i] == "-T" || ARGV[i] == "--content-type") {
       mime_type = ARGV[++i]
    }
    else if (ARGV[i] == "-a" || ARGV[i] == "--advertise") {
       adv_text = ARGV[++i]	
    }
    else if (ARGV[i] == "-C" || ARGV[i] == "--strip-comments") {
      no_comments = 1
    }
    else if (ARGV[i] == "-l" || ARGV[i] == "--last") pick_last = 1
    else if (ARGV[i] == "-e" || ARGV[i] == "--eval") {
       split(ARGV[++i], eval, ",")
    }
    else if (ARGV[i] == "-R" || ARGV[i] == "--file-root") {
       file_root = ARGV[++i]
    }
    else if (ARGV[i] == "-t" || ARGV[i] == "--trim") trim = 1
    else if (ARGV[i] == "-i" || ARGV[i] == "--input") i_file = ARGV[++i]
    else if (ARGV[i] == "-o" || ARGV[i] == "--output") o_file = ARGV[++i]
    else if (ARGV[i] == "-h" || ARGV[i] == "--help") {
       system("grep -v '^#' @NOSQLPATH@/nosql/help/tabletoform.txt")
       rc = 1
       exit(rc)
    }
    else t_file = ARGV[i]
  }

  ARGC = 1					# Fix argv[]

  if (t_file == NULL) {
     print "Usage: tabletoform [options] template" > "@STDERR@"
     exit(1)
  }

  if (o_file == NULL) o_file = "@STDOUT@"
  if (i_file != NULL) { ARGV[1] = i_file; ARGC = 2 }
}

#
# Load the associative array with the replacement directives.
#

# Column names.
NR == 1 {
  i = 0
  while (++i <= NF) {
    if (!P[$i]) { 
      if (i == 1) auto_col = $i
      else auto_col = auto_col " " $i
    }

    if (pick_last) P[$i] = i
    else {
      if (!P[$i]) P[$i] = i
    }
  }
  split(auto_col, c_names, " ")
}

# Dashline.
NR == 2 { next }

#
# Perform the replacements.
#

END {
  if (rc) exit(rc)
  if (NR > 2) {
    i = 0
    while ( P[c_names[++i]] ) {		# Process each field in turn.
      field = $P[c_names[i]]

      # Load the main associative array.

      c_values[prefix c_names[i]] = field

      # Debug.
      # print prefix c_names[i] " = " field
    }
  }
  else {
    # No data rows in the input table; set empty replacements.
    i = 0
    while (P[c_names[++i]]) c_values[prefix c_names[i]] = NULL
  }

  # Process the template file here.

  # Print a MIME header if necessary.
  if (mime_type != NULL) {
     if (adv_text != NULL) printf("X-Powered-By: %s\n", adv_text) > o_file
     printf("Content-Type: %s\n\n", mime_type) > o_file
  }

  while (getline < t_file > 0) {
     if (no_comments && /^#/) continue
     nl = 1
     do {
        s_tag = match($0,/\$\[[-A-Za-z0-9_\/.:]+\]/)
        if (s_tag) {
	   e_tag = index($0, "]")
	   tag_len = e_tag - s_tag  - 2
	   printf("%s", substr($0, 1, s_tag - 1)) > o_file
	   tag = substr($0, s_tag + 2, tag_len)

	   for (i in eval) {			# Is "tag" to be eval'ed ?
	       if (eval[i] == tag) {
		  tag = ENVIRON[tag]		# Get tag value from env.
		  break
	       }
	   }

	   if (tag ~ /\//) {			# Catch file patterns.
	      if (tag ~ /\.\./) {		# Catch any '..' pattern.
		 printf("$[%s]", tag) > o_file	# Print tag literally.
	      }
	      else {
		 # Read external file, if it exists.
		 if (file_root != NULL && tag !~ /^\//) {
		    tag = file_root "/" tag
		    gsub(/\/\//, "/", tag)	# Turn any "//" into "/".
		 }
		 if (sub(/:m$/,NULL,tag)) {		# Base64.
		    system("exec mimencode " tag) > o_file
		 }
		 else if (sub(/:q$/,NULL,tag)) {	# Quoted printable.
		    system("exec mimencode -q " tag) > o_file
		 }
		 else if (sub(/:u$/,NULL,tag)) {	# uuencode.
		    file_name = tag
		    gsub(/^.*\//,NULL,file_name)
		    if (file_name != NULL) {
		       system("exec uuencode " tag " " file_name) > o_file
		    }
		 }
		 else {
		    while (getline record < tag > 0) print record > o_file
		    close(tag)
		 }
		 nl = 0
	      }
	   }
	   else {
	      if (tag == NULL) {
		 if (mime_type ~ /html$/) tag = "<!-- -->"
	      }
	      printf("%s", c_values[tag]) > o_file
	   }

	   $0 = substr($0, e_tag + 1)
	}
	else {
	   printf("%s", $0) > o_file
	   $0 = NULL		# Not to loop forever.
	}
     }  while (length($0))

     if (nl) printf("\n") > o_file
  }
}

#
# End of program.
#
