#!/usr/bin/perl
# -*- perl -*-
#  $Id: gather-actions,v 1.1 2004/04/27 19:08:25 djdelorie Exp $
#
#                            COPYRIGHT
#  PCB, interactive printed circuit board design
#  Copyright (C) 2004 DJ Delorie
# 
#  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.
# 
#  Contact addresses for paper mail and Email:
#  DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA
#  dj@delorie.com

#-----------------------------------------------------------------------------
#  Include a comment like this anywhere in your source to automatically
#  register an action.  The gather-actions script looks for these and
#  generates the list, but the comment keeps it from actually doing
#  anything in your source.  Note: do not quote the name, and include no
#  extra spaces.
# 
#  /* ACTION(name,func) */
# 
#  Similarly, but for menu flags.  The parm is passed to the func, so
#  you can have one function support multiple flags.  */
# 
#  /* FLAG(name,func,parm) */
# 
#  Similarly, but for menu generators.  In the menu resource, entries of
#  the form "@func" will call the func named in this table to include a
#  dynamically generated set of buttons.  */
# 
#  /* MENU(name,func) */
#-----------------------------------------------------------------------------

$verbose = 0;

open(OUT, "> actionlist.c");
select OUT;

print "/* This file is generated by gather-actions.  DO NOT EDIT.  */\n";
print "\n";
print "#include \"global.h\"\n";
print "#include \"X11/Intrinsic.h\"\n";
print "\n";

foreach $file (@ARGV) {
    next if $file =~ /\.h$/;
    open(F, $file);
    while (<F>) {
	if (/\/\* ACTION\((.*)\) *(POPUP|CREATE)?/) {
	    print STDERR "action: $1 $2\n" if $verbose;
	    ($name, $func) = split(',', $1, 2);
	    push(@actions, "$name\0$func\0$2");
	    push(@actionfuncs, "$func");
	} elsif (/\/\* FLAG\((.*)\)/) {
	    print STDERR "flag: $1\n" if $verbose;
	    ($name, $func, $parm) = split(',', $1, 3);
	    $parm = 0 unless $parm =~ /\S/;
	    push(@flags, "$name\0$func\0$parm");
	    push(@flagfuncs, "$func");
	} elsif (/\/\* MENU\((.*)\)/) {
	    print STDERR "menu: $1\n" if $verbose;
	    ($name, $func) = split(',', $1,2);
	    push(@menus, "$name\0$func");
	    push(@menufuncs, "$func");
	}
    }
    close(F);
}

#-----------------------------------------------------------------------------

for $func (sort @actionfuncs) {
    print "extern void $func(Widget,XEvent *,String *, Cardinal *);\n";
}

print "\n";
print "XtActionsRec ActionList[] = {\n";
for $a (sort @actions) {
    ($name, $func, $types) = split(/\0/, $a);
    print "  {\"$name\", $func},\n";
}

print "  {0,0}\n";
print "};\n";
print "\n";

print "struct { char *name; int type; } ActionTypeList[] = {\n";
for $a (sort @actions) {
    ($name, $func, $types) = split(/\0/, $a);
    $type = 0;
    $type = "'p'" if $types =~ /popup/i;
    $type = "'c'" if $types =~ /create/i;
    print "  {\"$name\", $type},\n";
}
print "  {0,0}\n";
print "};\n";
print "\n";

$n = $#actions + 1;
print "int ActionListSize = $n;\n";

#-----------------------------------------------------------------------------

for $func (sort @flagfuncs) {
    print "extern int $func(int);\n";
}

print "\n";
print "struct {\n";
print "  char *name;\n";
print "  int (*func)(int);\n";
print "  int parm;\n";
print "} FlagFuncList[] = {\n";

for $f (sort @flags) {
    ($name, $func, $parm) = split(/\0/, $f);
    print "  {\"$name\", $func, $parm },\n";
}

print "  {0,0,0}\n";
print "};\n";
print "\n";

$n = $#flags + 1;
print "int FlagFuncListSize = $n;\n";

#-----------------------------------------------------------------------------

print "struct Resource;\n";
for $func (sort @menufuncs) {
    print "extern void $func(struct Resource *);\n";
}

print "\n";
print "struct {\n";
print "  char *name;\n";
print "  void (*func)(struct Resource *);\n";
print "} MenuFuncList[] = {\n";

for $f (sort @menus) {
    ($name, $func) = split(/\0/, $f);
    print "  {\"$name\", $func },\n";
}

print "  {0,0}\n";
print "};\n";
print "\n";

$n = $#menus + 1;
print "int MenuFuncListSize = $n;\n";

#-----------------------------------------------------------------------------

close(OUT);
