#! /bin/awk -f
#
# Copyright (c) 1989 Stanford University
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided
# that the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of Stanford not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission.  Stanford makes no representations about
# the suitability of this software for any purpose.  It is provided "as is"
# without express or implied warranty.
#
# STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

#
# munch - find initialization/finalization functions in an executable and
#     generate a table of pointers to them.  The exit status is 1 if
#     no functions are found, 0 otherwise.
#

BEGIN { i = 0; d = 0; }
/T ___sti__/ { sti[i++] = substr($3, 2, length($3)-1); }
/T ___std__/ { std[d++] = substr($3, 2, length($3)-1); }
/T __sti__/ { sti[i++] = $3; }
/T __std__/ { std[d++] = $3; }
END {
    printf("typedef void (*PF)();\n\n");
    status = 1;
    if (i > 0) {
	for (k = 0; k < i; k++) {
	    printf("extern void %s();\n", sti[k]);
	}
	printf("struct { int n; PF f[%d]; } __CTOR_LIST__ = { %d,\n", i+1, i);
	for (k = 0; k < i; k++) {
	    printf("    %s,\n", sti[k]);
	}
	printf("    0\n");
	printf("};\n");
	status = 0;
    }
    if (d > 0) {
	for (k = 0; k < d; k++) {
	    printf("extern void %s();\n", std[k]);
	}
	printf("struct { int n; PF f[%d]; } __DTOR_LIST__ = { %d,\n", d+1, d);
	for (k = 0; k < d; k++) {
	    printf("    %s,\n", std[k]);
	}
	printf("    0\n");
	printf("};\n");
	status = 0;
    }
    exit(status);
}
