#! /bin/sh -
# 
# Mach Operating System
# Copyright (c) 1992 Carnegie Mellon University
# All Rights Reserved.
# 
# Permission to use, copy, modify and distribute this software and its
# documentation is hereby granted, provided that both the copyright
# notice and this permission notice appear in all copies of the
# software, derivative works or modified versions, and any portions
# thereof, and that both notices appear in supporting documentation.
# 
# CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
# ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
# 
# Carnegie Mellon requests users of this software to return to
# 
#  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
#  School of Computer Science
#  Carnegie Mellon University
#  Pittsburgh PA 15213-3890
# 
# any improvements or extensions that they make and grant Carnegie Mellon 
# the rights to redistribute these changes.
#
#
# HISTORY
# $Log:	makesyscalls.sh,v $
# Revision 2.3  92/06/25  17:28:53  mrt
# 	Corrected include of param.h
# 	[92/06/17            mrt]
# 
# Revision 2.2  92/05/25  14:44:02  rwd
# 	Fix includes.
# 	[92/05/18            rwd]
# 
# Revision 2.1  92/04/21  17:12:50  rwd
# BSDSS
# 
#
#

#	@(#)makesyscalls.sh	7.6 (Berkeley) 4/20/91

set -e

# name of compat option:
compat=COMPAT_43

# output files:
sysnames="syscalls.c"
syshdr="../sys/syscall.h"
syssw="init_sysent.c"
syse="../emul_sysent.c"

# tmp files:
sysdcl="sysent.dcl"
syscompat="sysent.compat"
sysent="sysent.switch"
emldcl="emlent.dcl"
emlent="emlent.switch"

trap "rm $sysdcl $syscompat $sysent $emldcl $emlent" 0

case $# in
    0)	echo "Usage: $0 input-file" 1>&2
	exit 1
	;;
esac

awk < $1 "
	BEGIN {
		sysdcl = \"$sysdcl\"
		syscompat = \"$syscompat\"
		sysent = \"$sysent\"
		sysnames = \"$sysnames\"
		syshdr = \"$syshdr\"
		compat = \"$compat\"
		emldcl = \"$emldcl\"
		emlent = \"$emlent\"
		infile = \"$1\"
		"'

		printf "/*\n * System call switch table.\n *\n" > sysdcl
		printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl

		printf "\n#ifdef %s\n", compat > syscompat
		printf "#define compat(n, name) n, __CONCAT(o,name)\n\n" > syscompat

		printf "/*\n * System call names.\n *\n" > sysnames
		printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames

		printf "/*\n * System call numbers.\n *\n" > syshdr
		printf " * DO NOT EDIT-- this file is automatically generated.\n" > syshdr

		printf "/*\n * System call switch table.\n *\n" > emldcl
		printf " * DO NOT EDIT-- this file is automatically generated.\n" > emldcl

	}
	NR == 1 {
		printf " * created from%s\n */\n\n", $0 > sysdcl
		printf "#include <sys/param.h>\n" > sysdcl
		printf "#include <sys/systm.h>\n\n" > sysdcl
		printf "int\tnosys();\n\n" > sysdcl

		printf "struct sysent sysent[] = {\n" > sysent

		printf " * created from%s\n */\n\n", $0 > sysnames
		printf "char *syscallnames[] = {\n" > sysnames

		printf " * created from%s\n */\n\n", $0 > syshdr

		printf " * created from%s\n */\n\n", $0 > emldcl
		printf "#include <syscall_table.h>\n" > emldcl
		printf "#define syss(routine, nargs)    { nargs, routine }\n" >emldcl
		printf "#define sysg                    { E_GENERIC, emul_generic }\n" > emldcl
		printf "#define sysr(routine)           { E_CHANGE_REGS, routine }\n" > emldcl
		printf "int emul_generic();\n" > emldcl
		printf "int e_htg_syscall();\n" > emldcl
		printf "int bsd_pid_by_task();\n" > emldcl
		printf "int bsd_task_by_pid();\n" > emldcl
		printf "int bsd_init_process();\n" > emldcl
		printf "#define e_setgroups	bsd_setgroups\n" > emldcl
		printf "#define e_sethostname	bsd_sethostname\n" > emldcl
		printf "#define e_connect	bsd_connect\n" > emldcl
		printf "#define e_bind		bsd_bind\n" > emldcl
		printf "#define e_adjtime	bsd_adjtime\n" > emldcl
		printf "#define e_setrlimit	bsd_setrlimit\n" > emldcl
		printf "#define e_vfork		e_fork\n" > emldcl

		printf "struct sysent sysent[] = {\n" > emlent

		next
	}
	NF == 0 || $1 ~ /^;/ {
		next
	}
	$1 ~ /^#[ 	]*if/ {
		print > sysent
		print > sysdcl
		print > syscompat
		print > sysnames
		print > emldcl
		print > emlent
		savesyscall = syscall
		next
	}
	$1 ~ /^#[ 	]*else/ {
		print > sysent
		print > sysdcl
		print > syscompat
		print > sysnames
		print > emldcl
		print > emlent
		syscall = savesyscall
		next
	}
	$1 ~ /^#/ {
		print > sysent
		print > sysdcl
		print > syscompat
		print > sysnames
		print > emldcl
		print > emlent
		next
	}
	syscall != $1 {
		printf "%s: line %d: syscall number out of sync at %d\n", \
		   infile, NR, syscall
		printf "line is:\n"
		print
		exit 1
	}
	{	comment = $5
		for (i = 6; i <= NF; i++)
			comment = comment " " $i
		if (NF < 6)
			$6 = $5
	}
	$3 == "SYSG" {
		printf("\tsysg,\t\t\t\t/* %d */\n",syscall) > emlent
	}
	$3 == "SYSR" {
		printf("\tsysr(e_%s),\t\t\t/* %d */\n",$5,syscall) > emlent
		printf("int e_%s();\n",$5) > emldcl
	}
	$3 == "SYSS" {
		printf("\tsyss(e_%s, %d),\t\t/* %d */\n",$5,$4,syscall) > emlent
		printf("int e_%s();\n",$5) > emldcl
	}
	$2 == "STD" {
		printf("int\t%s();\n", $5) > sysdcl
		printf("\t%d, %s,\t\t\t/* %d = %s */\n", \
		    $3, $5, syscall, $6) > sysent
		printf("\t\"%s\",\t\t\t/* %d = %s */\n", \
		    $6, syscall, $6) > sysnames
		printf("#define\tSYS_%s\t%d\n", \
		    $6, syscall) > syshdr
		syscall++
		next
	}
	$2 == "COMPAT" {
		printf("int\to%s();\n", $5) > syscompat
		printf("\tcompat(%d,%s),\t\t/* %d = old %s */\n", \
		    $4, $5, syscall, $6) > sysent
		printf("\t\"old.%s\",\t\t/* %d = old %s */\n", \
		    $6, syscall, $6) > sysnames
		printf("#define\tSYS_o%s\t%d\n", \
		    $6, syscall) > syshdr
		printf("\t\t\t\t/* %d is old %s */\n", \
		    syscall, comment) > syshdr
		syscall++
		next
	}
	$2 == "LIBCOMPAT" {
		printf("int\to%s();\n", $5) > syscompat
		printf("\tcompat(%d,%s),\t\t/* %d = old %s */\n", \
		    $4, $5, syscall, $6) > sysent
		printf("\t\"old.%s\",\t\t/* %d = old %s */\n", \
		    $6, syscall, $6) > sysnames
		printf("#define\tSYS_%s\t%d\t/* compatibility; still used by libc */\n", \
		    $6, syscall) > syshdr
		syscall++
		next
	}
	$2 == "OBSOL" {
		printf("\t0, nosys,\t\t\t/* %d = obsolete %s */\n", \
		    syscall, comment) > sysent
		printf("\t\"obs_%s\",\t\t\t/* %d = obsolete %s */\n", \
		    $5, syscall, comment) > sysnames
		printf("\t\t\t\t/* %d is obsolete %s */\n", \
		    syscall, comment) > syshdr
		syscall++
		next
	}
	$2 == "UNIMPL" {
		printf("\t0, nosys,\t\t\t/* %d = %s */\n", \
		    syscall, comment) > sysent
		printf("\t\"#%d\",\t\t\t/* %d = %s */\n", \
		    syscall, syscall, comment) > sysnames
		syscall++
		next
	}
	{
		printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2
		exit 1
	}
	END {
		printf("\n#else /* %s */\n", compat) > syscompat
		printf("#define compat(n, name) 0, nosys\n") > syscompat
		printf("#endif /* %s */\n\n", compat) > syscompat

		printf("};\n\n") > sysent
		printf("int\tnsysent = sizeof(sysent) / sizeof(sysent[0]);\n") > sysent

		printf("};\n") > sysnames
	} '

cat $sysdcl $syscompat $sysent >$syssw

cat $emldcl $emlent > $syse

cat >> $syse <<+EOF+ #------------------------------------------------------
};

int	nsysent = sizeof(sysent)/sizeof(struct sysent);

struct sysent   sysent_task_by_pid =
        syss(bsd_task_by_pid, 1);

struct sysent   sysent_pid_by_task =
        syss(bsd_pid_by_task, 4);

struct sysent   sysent_htg_ux_syscall =
        sysr(e_htg_syscall);

struct sysent   sysent_init_process =
        syss(bsd_init_process, 1);

+EOF+

chmod 444 $sysnames $syshdr $syssw
