[Midnightbsd-cvs] src [7395] trunk/usr.bin/migcom: add migcom(1)

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Jan 3 12:31:37 EST 2016


Revision: 7395
          http://svnweb.midnightbsd.org/src/?rev=7395
Author:   laffer1
Date:     2016-01-03 12:31:36 -0500 (Sun, 03 Jan 2016)
Log Message:
-----------
add migcom(1)

Added Paths:
-----------
    trunk/usr.bin/migcom/
    trunk/usr.bin/migcom/Makefile
    trunk/usr.bin/migcom/POWERMAC/
    trunk/usr.bin/migcom/POWERMAC/machdep.mk
    trunk/usr.bin/migcom/alloc.h
    trunk/usr.bin/migcom/alpha/
    trunk/usr.bin/migcom/alpha/mig_machine.h
    trunk/usr.bin/migcom/error.c
    trunk/usr.bin/migcom/error.h
    trunk/usr.bin/migcom/global.c
    trunk/usr.bin/migcom/global.h
    trunk/usr.bin/migcom/header.c
    trunk/usr.bin/migcom/hp_pa/
    trunk/usr.bin/migcom/hp_pa/mig_machine.h
    trunk/usr.bin/migcom/i386/
    trunk/usr.bin/migcom/i386/mig_machine.h
    trunk/usr.bin/migcom/include/
    trunk/usr.bin/migcom/lexxer.h
    trunk/usr.bin/migcom/lexxer.l
    trunk/usr.bin/migcom/mig.c
    trunk/usr.bin/migcom/mig.sh
    trunk/usr.bin/migcom/migcom.1
    trunk/usr.bin/migcom/parser.y
    trunk/usr.bin/migcom/ppc/
    trunk/usr.bin/migcom/ppc/mig_machine.h
    trunk/usr.bin/migcom/routine.c
    trunk/usr.bin/migcom/routine.h
    trunk/usr.bin/migcom/server.c
    trunk/usr.bin/migcom/shims/
    trunk/usr.bin/migcom/shims/errno.h
    trunk/usr.bin/migcom/shims/stdarg.h
    trunk/usr.bin/migcom/shims/stdint.h
    trunk/usr.bin/migcom/statement.c
    trunk/usr.bin/migcom/statement.h
    trunk/usr.bin/migcom/strdefs.h
    trunk/usr.bin/migcom/string.c
    trunk/usr.bin/migcom/test.c
    trunk/usr.bin/migcom/type.c
    trunk/usr.bin/migcom/type.h
    trunk/usr.bin/migcom/user.c
    trunk/usr.bin/migcom/utils.c
    trunk/usr.bin/migcom/utils.h
    trunk/usr.bin/migcom/write.h

Added: trunk/usr.bin/migcom/Makefile
===================================================================
--- trunk/usr.bin/migcom/Makefile	                        (rev 0)
+++ trunk/usr.bin/migcom/Makefile	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,55 @@
+# $MidnightBSD$
+#
+# Copyright 1991-1998 by Open Software Foundation, Inc. 
+#              All Rights Reserved 
+#  
+# Permission to use, copy, modify, and distribute this software and 
+# its documentation for any purpose and without fee is hereby granted, 
+# provided that the above copyright notice appears in all copies and 
+# that both the copyright notice and this permission notice appear in 
+# supporting documentation. 
+#  
+# OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+# FOR A PARTICULAR PURPOSE. 
+#  
+# IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+# NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+# 
+# 
+# cmk1.1
+
+.include <bsd.own.mk>
+PROG= migcom
+SCRIPTS=mig.sh
+SRCS= ident.c error.c global.c header.c \
+	lexxer.l mig.c parser.y routine.c server.c \
+	statement.c string.c type.c user.c utils.c
+
+
+CFLAGS+= -nostdinc -I./include -I${.CURDIR} -I${.CURDIR}/shims -I./include
+CFLAGS+= -I${.CURDIR}/../../include -I${.CURDIR}/../../sys 
+CFLAGS+= -I${.CURDIR} -DYY_NO_UNPUT -DYY_NO_INPUT -I${.CURDIR}/../../apsl/include
+
+
+.PATH: i386
+CFLAGS+= -I${.CURDIR}/i386
+include/x86: ${.CURDIR}/Makefile
+	mkdir -p include
+	ln -sf ${.CURDIR}/../../sys/x86/include include/x86
+
+include/machine:  ${.CURDIR}/Makefile
+	mkdir -p include
+	ln -sf ${.CURDIR}/../../sys/${MACHINE_CPUARCH}/include include/machine
+
+ident.c: include/machine include/x86 
+	echo "#include \"alloc.h\" " >${.TARGET}
+	echo "const char *MigGenerationDate = \""`date`"\";" >>${.TARGET}
+	echo "const char *MigMoreData = \""`whoami`"@"`hostname`"\";" >>${.TARGET}
+
+CLEANFILES+= ident.c *.o *~ *.gz cscope.* include/machine include/x86
+
+.include <bsd.prog.mk>


Property changes on: trunk/usr.bin/migcom/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/POWERMAC/machdep.mk
===================================================================
--- trunk/usr.bin/migcom/POWERMAC/machdep.mk	                        (rev 0)
+++ trunk/usr.bin/migcom/POWERMAC/machdep.mk	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,38 @@
+#
+# Copyright 1991-1998 by Open Software Foundation, Inc. 
+#              All Rights Reserved 
+#  
+# Permission to use, copy, modify, and distribute this software and 
+# its documentation for any purpose and without fee is hereby granted, 
+# provided that the above copyright notice appears in all copies and 
+# that both the copyright notice and this permission notice appear in 
+# supporting documentation. 
+#  
+# OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+# FOR A PARTICULAR PURPOSE. 
+#  
+# IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+# NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+# 
+# 
+# cmk1.1
+
+# PowerMac work is done by cross compiling from a HP host. We must
+# use the host compiler with the target's include files when
+# generating migcom
+
+CCTYPE=host
+INCFLAGS+=-I.
+
+
+${TARGET_MACHINE}_VPATH         = ${TARGET_MACHINE}
+${TARGET_MACHINE}_INCDIRS       = ${TARGET_MACHINE}
+
+LOCAL_CFLAGS            = -msoft-float -fno-omit-frame-pointer
+                                   
+LEX	=	flex
+LIBS	=	-lfl


Property changes on: trunk/usr.bin/migcom/POWERMAC/machdep.mk
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/alloc.h
===================================================================
--- trunk/usr.bin/migcom/alloc.h	                        (rev 0)
+++ trunk/usr.bin/migcom/alloc.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,78 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/02/05  17:54:07  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:53:36  mrt]
+ * 
+ * 90/06/02  15:04:21  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:09:59  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#ifndef	_ALLOC_H
+#define	_ALLOC_H
+
+#include <stdlib.h>
+
+extern const char *MessFreeRoutine;
+extern const char *MessAllocRoutine;
+extern const char * GenerationDate;
+extern const char * MigGenerationDate;
+extern const char * MigMoreData;
+
+#endif	/* _ALLOC_H */


Property changes on: trunk/usr.bin/migcom/alloc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/alpha/mig_machine.h
===================================================================
--- trunk/usr.bin/migcom/alpha/mig_machine.h	                        (rev 0)
+++ trunk/usr.bin/migcom/alpha/mig_machine.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc.  
+ *              All Rights Reserved  
+ *   
+ * Permission to use, copy, modify, and distribute this software and  
+ * its documentation for any purpose and without fee is hereby granted,  
+ * provided that the above copyright notice appears in all copies and  
+ * that both the copyright notice and this permission notice appear in  
+ * supporting documentation.  
+ *   
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE  
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  
+ * FOR A PARTICULAR PURPOSE.  
+ *   
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR  
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM  
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,  
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  
+ */
+/*
+ * cmk1.1
+ */
+
+#define	machine_alignment(SZ,ESZ) 					\
+ 	(((((ESZ) > 4) && ((SZ) & 7)) ?  				\
+	(SZ) = ((SZ) + 7) & ~7 : (((ESZ == 4) && ((SZ) & 3)) ?		\
+	(SZ) = ((SZ) + 3) & ~3 : 0)), (SZ) += (ESZ))
+
+#define	machine_padding(BYTES)						\
+	((bytes & 3) ? (4 - (bytes &  3)) : 0)
+
+#define PACK_MESSAGES FALSE


Property changes on: trunk/usr.bin/migcom/alpha/mig_machine.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/error.c
===================================================================
--- trunk/usr.bin/migcom/error.c	                        (rev 0)
+++ trunk/usr.bin/migcom/error.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,127 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/02/05  17:54:11  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:53:53  mrt]
+ * 
+ * 90/06/02  15:04:25  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:10:17  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "global.h"
+#include "error.h"
+
+extern int lineno;
+extern const char *yyinname;
+
+static const char *program;
+int errors = 0;
+
+/*ARGSUSED*/
+/*VARARGS1*/
+void
+fatal(const char *format, ...)
+{
+    va_list pvar;
+    va_start(pvar, format);
+    fprintf(stderr, "%s: fatal: \"%s\", line %d: ", program, yyinname, lineno-1);
+    (void) vfprintf(stderr, format, pvar);
+    fprintf(stderr, "\n");
+    va_end(pvar);
+    exit(1);
+}
+
+/*ARGSUSED*/
+/*VARARGS1*/
+void
+warn(const char *format, ...)
+{
+    va_list pvar;
+    va_start(pvar, format);
+    if (!BeQuiet && (errors == 0))
+    {
+	fprintf(stderr, "\"%s\", line %d: warning: ", yyinname, lineno-1);
+	(void) vfprintf(stderr, format, pvar);
+	fprintf(stderr, "\n");
+    }
+    va_end(pvar);
+}
+
+/*ARGSUSED*/
+/*VARARGS1*/
+void
+error(const char *format, ...)
+{
+    va_list pvar;
+    va_start(pvar, format);
+    fprintf(stderr, "\"%s\", line %d: ", yyinname, lineno-1);
+    (void) vfprintf(stderr, format, pvar);
+    fprintf(stderr, "\n");
+    va_end(pvar);
+    errors++;
+}
+
+void
+set_program_name(const char *name)
+{
+    program = name;
+}


Property changes on: trunk/usr.bin/migcom/error.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/error.h
===================================================================
--- trunk/usr.bin/migcom/error.h	                        (rev 0)
+++ trunk/usr.bin/migcom/error.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,87 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 92/03/03  16:24:58  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:31:12  jeffreyh]
+ * 
+ * 92/01/14  16:46:17  rpd
+ * 	Removed <mach_error.h>.
+ * 	[92/01/06            rpd]
+ * 
+ * 91/02/05  17:54:14  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:00  mrt]
+ * 
+ * 90/06/02  15:04:33  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:10:30  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#ifndef	_ERROR_H
+#define	_ERROR_H
+
+#include <sys/errno.h>
+extern int lineno;
+extern void fatal(const char *format, ...);
+extern void warn(const char *format, ...);
+extern void error(const char *format, ...);
+
+extern int errors;
+extern void set_program_name(const char *name);
+
+#endif	/* _ERROR_H */


Property changes on: trunk/usr.bin/migcom/error.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/global.c
===================================================================
--- trunk/usr.bin/migcom/global.c	                        (rev 0)
+++ trunk/usr.bin/migcom/global.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,209 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ * 
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ * 
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/08/28  11:16:53  jsb
+ * 	Replaced ServerProcName with ServerDemux.
+ * 	[91/08/13            rpd]
+ * 
+ * 	Removed Camelot and TrapRoutine support.
+ * 	Changed MsgKind to MsgSeqno.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/06/26  14:39:24  rpd
+ * 	Removed InitRoutineName.
+ * 	[91/06/26            rpd]
+ * 
+ * 91/06/25  10:30:59  rpd
+ * 	Added ServerHeaderFileName.
+ * 	[91/05/22            rpd]
+ * 
+ * 91/02/05  17:54:23  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:07  mrt]
+ * 
+ * 90/06/19  23:00:47  rpd
+ * 	Added UserFilePrefix.
+ * 	[90/06/03            rpd]
+ * 
+ * 90/06/02  15:04:38  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:10:43  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ *  8-Feb-89  David Golub (dbg) at Carnegie-Mellon University
+ *	Use default values for output file names only if they have not
+ *	yet been set.
+ *
+ * 17-Sep-87  Bennet Yee (bsy) at Carnegie-Mellon University
+ *	Added GenSymTab
+ *
+ * 25-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed CamelotPrefix to op_
+ *
+ * 12-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Initialized CamelotPrefix
+ *
+ * 10-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed UseRPC to TRUE
+ *
+ *  3-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Removed reference to UseThreads.
+ *
+ * 16-Jul-87  Robert Sansom (rds) at Carnegie Mellon University
+ *	Added MsgType.
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mach/message.h>
+#include "strdefs.h"
+#include "global.h"
+#include "error.h"
+#include "mig_machine.h"
+
+
+
+boolean_t BeQuiet = FALSE;
+boolean_t BeVerbose = FALSE;
+boolean_t UseMsgRPC = TRUE;
+boolean_t GenSymTab = FALSE;
+boolean_t UseEventLogger = FALSE;
+boolean_t BeAnsiC = TRUE;
+boolean_t CheckNDR = FALSE;
+boolean_t PackMsg = PACK_MESSAGES;
+boolean_t UseSplitHeaders = FALSE;
+boolean_t ShortCircuit = FALSE;
+boolean_t UseRPCTrap = FALSE;
+boolean_t TestRPCTrap= FALSE;
+boolean_t IsVoucherCodeAllowed = TRUE;
+
+boolean_t IsKernelUser = FALSE;
+boolean_t IsKernelServer = FALSE;
+
+string_t RCSId = strNULL;
+
+string_t SubsystemName = strNULL;
+u_int SubsystemBase = 0;
+
+string_t MsgOption = strNULL;
+string_t WaitTime = strNULL;
+string_t SendTime = strNULL;
+string_t ErrorProc = "MsgError";
+string_t ServerPrefix = "";
+string_t UserPrefix = "";
+string_t ServerDemux = strNULL;
+string_t ServerImpl = strNULL;
+string_t ServerSubsys = strNULL;
+int MaxMessSizeOnStack = -1;    /* by default, always on stack */
+int UserTypeLimit = -1;         /* by default, assume unlimited size. */
+
+string_t yyinname;
+
+char NewCDecl[] = "(defined(__STDC__) || defined(c_plusplus))";
+char LintLib[] = "defined(LINTLIBRARY)";
+
+void
+init_global(void)
+{
+    yyinname = strmake("<no name yet>");
+}
+
+string_t UserFilePrefix = strNULL;
+string_t UserHeaderFileName = strNULL;
+string_t ServerHeaderFileName = strNULL;
+string_t InternalHeaderFileName = strNULL;
+string_t DefinesHeaderFileName = strNULL;
+string_t UserFileName = strNULL;
+string_t ServerFileName = strNULL;
+string_t GenerationDate = strNULL;
+
+void
+more_global(void)
+{
+  if (SubsystemName == strNULL)
+    fatal("no SubSystem declaration");
+
+  if (UserHeaderFileName == strNULL)
+    UserHeaderFileName = strconcat(SubsystemName, ".h");
+  else if (streql(UserHeaderFileName, "/dev/null"))
+    UserHeaderFileName = strNULL;
+
+  if (UserFileName == strNULL)
+    UserFileName = strconcat(SubsystemName, "User.c");
+  else if (streql(UserFileName, "/dev/null"))
+    UserFileName = strNULL;
+
+  if (ServerFileName == strNULL)
+    ServerFileName = strconcat(SubsystemName, "Server.c");
+  else if (streql(ServerFileName, "/dev/null"))
+    ServerFileName = strNULL;
+
+  if (ServerDemux == strNULL)
+    ServerDemux = strconcat(SubsystemName, "_server");
+
+  if (ServerImpl == strNULL)
+    ServerImpl = strconcat(SubsystemName, "_impl");
+
+  if (ServerSubsys == strNULL) {
+    if (ServerPrefix != strNULL)
+      ServerSubsys = strconcat(ServerPrefix, SubsystemName);
+    else
+      ServerSubsys = SubsystemName;
+    ServerSubsys = strconcat(ServerSubsys, "_subsystem");
+  }
+}


Property changes on: trunk/usr.bin/migcom/global.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/global.h
===================================================================
--- trunk/usr.bin/migcom/global.h	                        (rev 0)
+++ trunk/usr.bin/migcom/global.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,159 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ * 
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ * 
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/08/28  11:16:56  jsb
+ * 	Replaced ServerProcName with ServerDemux.
+ * 	[91/08/13            rpd]
+ * 
+ * 	Removed Camelot and TrapRoutine support.
+ * 	Changed MsgKind to MsgSeqno.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/06/26  14:39:32  rpd
+ * 	Removed InitRoutineName.
+ * 	[91/06/26            rpd]
+ * 
+ * 91/06/25  10:31:12  rpd
+ * 	Added ServerHeaderFileName.
+ * 	[91/05/22            rpd]
+ * 
+ * 91/02/05  17:54:29  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:12  mrt]
+ * 
+ * 90/06/19  23:00:54  rpd
+ * 	Added UserFilePrefix.
+ * 	[90/06/03            rpd]
+ * 
+ * 90/06/02  15:04:42  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:10:53  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 17-Sep-87  Bennet Yee (bsy) at Carnegie-Mellon University
+ *	Added GenSymTab
+ *
+ * 16-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added CamelotPrefix
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#ifndef _GLOBAL_H
+#define _GLOBAL_H
+
+#include "type.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+extern boolean_t BeQuiet;   /* no warning messages */
+extern boolean_t BeVerbose; /* summarize types, routines */
+extern boolean_t BeDebug;   /* enters in the debug mode */
+extern boolean_t UseMsgRPC;
+extern boolean_t GenSymTab;
+extern boolean_t UseEventLogger;
+extern boolean_t BeAnsiC;
+extern boolean_t CheckNDR;
+extern boolean_t PackMsg;
+extern boolean_t UseSplitHeaders;
+extern boolean_t ShortCircuit;
+extern boolean_t UseRPCTrap;
+extern boolean_t TestRPCTrap;
+extern boolean_t IsVoucherCodeAllowed;
+
+extern boolean_t IsKernelUser;
+extern boolean_t IsKernelServer;
+
+extern string_t RCSId;
+
+extern string_t SubsystemName;
+extern u_int SubsystemBase;
+
+extern string_t MsgOption;
+extern string_t WaitTime;
+extern string_t SendTime;
+extern string_t ErrorProc;
+extern string_t ServerPrefix;
+extern string_t UserPrefix;
+extern string_t ServerDemux;
+extern string_t ServerImpl;
+extern string_t ServerSubsys;
+extern int MaxMessSizeOnStack;
+extern int UserTypeLimit;
+
+extern int yylineno;
+extern string_t yyinname;
+
+extern void init_global(void);
+
+extern string_t UserFilePrefix;
+extern string_t UserHeaderFileName;
+extern string_t ServerHeaderFileName;
+extern string_t InternalHeaderFileName;
+extern string_t DefinesHeaderFileName;
+extern string_t UserFileName;
+extern string_t ServerFileName;
+extern string_t GenerationDate;
+
+extern void more_global(void);
+
+extern char NewCDecl[];
+extern char LintLib[];
+
+#endif  /* _GLOBAL_H */


Property changes on: trunk/usr.bin/migcom/global.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/header.c
===================================================================
--- trunk/usr.bin/migcom/header.c	                        (rev 0)
+++ trunk/usr.bin/migcom/header.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,600 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/08/28  11:16:58  jsb
+ * 	Removed TrapRoutine support.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/06/26  14:39:37  rpd
+ * 	Removed the user initialization function and InitRoutineName.
+ * 	Fixed to use different symbolic constants to protect
+ * 	the user and server header files against multiple inclusion.
+ * 	[91/06/26            rpd]
+ * 
+ * 91/06/25  10:31:21  rpd
+ * 	Restored prototype generation.
+ * 	Changed WriteHeader to WriteUserHeader.
+ * 	Added WriteServerHeader.
+ * 	[91/05/23            rpd]
+ * 
+ * 91/02/05  17:54:33  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:19  mrt]
+ * 
+ * 90/12/20  17:04:47  jeffreyh
+ * 	Commented out code for prototype generation. This is a temporary solution
+ * 	to the longer term problem of the need 
+ * 	for the generation of both a client and a server header file 
+ * 	that have correct prototypes for strict ansi c and c++. The
+ * 	prototypes generated before anly were for the client and broke kernel
+ * 	files that included them if compiled under standard gcc
+ * 	[90/12/07            jeffreyh]
+ * 
+ * 90/06/02  15:04:46  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:11:06  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ *  8-Jul-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Conditionally defined mig_external to be extern and then defined
+ *	all functions  with the storage class mig_external.
+ *	Mig_external can be changed
+ *	when the generated code is compiled.
+ *
+ * 18-Jan-88  David Detlefs (dld) at Carnegie-Mellon University
+ *	Modified to produce C++ compatible code via #ifdefs.
+ *	All changes have to do with argument declarations.
+ *
+ *  3-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Revision to make multi-threaded use work. Removed definitions for
+ * 	alloc_reply_port and init_msg_type as these routines are 
+ * 	no longer generated.
+ *
+ * 30-Jul-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ * 	Made changes to generate conditional code for C++ parameter lists
+ *
+ * 29-Jul-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed WriteRoutine to produce conditional argument
+ *	lists for C++
+ *
+ *  8-Jun-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed the KERNEL include from ../h to sys/
+ *	Removed extern from WriteHeader to make hi-c happy
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include "write.h"
+#include "utils.h"
+#include "global.h"
+#include "strdefs.h"
+#include "error.h"
+#include <stdlib.h>
+
+void
+WriteIncludes(FILE *file, boolean_t isuser, boolean_t isdef)
+{
+	if (isdef) {
+		fprintf(file, "#include <mach/port.h>\n");
+		fprintf(file, "#include <machine/mach/kern_return.h>\n");
+		if (!isuser)
+			fprintf(file, "#include <mach/mig_errors.h>\n");
+	}
+	else {
+		fprintf(file, "#include <sys/cdefs.h>\n");
+		fprintf(file, "#include <sys/types.h>\n");
+		fprintf(file, "#ifdef _KERNEL\n");
+		fprintf(file, "#include <sys/mach/ndr.h>\n");
+		fprintf(file, "#include <sys/mach/kern_return.h>\n");
+		fprintf(file, "#include <sys/mach/notify.h>\n");
+		fprintf(file, "#include <sys/mach/mach_types.h>\n");
+		fprintf(file, "#include <sys/mach/message.h>\n");
+		fprintf(file, "#include <sys/mach/mig_errors.h>\n");
+		fprintf(file, "#else /* !_KERNEL */\n");
+		fprintf(file, "#include <string.h>\n");
+		fprintf(file, "#include <mach/ndr.h>\n");
+		fprintf(file, "#include <mach/boolean.h>\n");
+		fprintf(file, "#include <mach/kern_return.h>\n");
+		fprintf(file, "#include <mach/notify.h>\n");
+		fprintf(file, "#include <mach/mach_types.h>\n");
+		fprintf(file, "#include <mach/message.h>\n");
+		fprintf(file, "#include <mach/mig_errors.h>\n");
+		fprintf(file, "#endif /*_KERNEL */\n");
+		if (ShortCircuit)
+			fprintf(file, "#include <mach/rpc.h>\n");
+		if (isuser && IsKernelUser) {
+			fprintf(file, "#if\t(__MigKernelSpecificCode) || (_MIG_KERNEL_SPECIFIC_CODE_)\n");
+			fprintf(file, "#include <kern/ipc_mig.h>\n");
+			fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+		}
+	}
+	fprintf(file, "\n");
+}
+
+static void
+WriteETAPDefines(FILE *file)
+{
+	register statement_t *stat;
+	int fnum;
+    const char *fname;
+	int first = TRUE;
+
+	fprintf(file, "\n#ifndef subsystem_to_name_map_%s\n", SubsystemName);
+	fprintf(file, "#define subsystem_to_name_map_%s \\\n", SubsystemName);
+    for (stat = defs_stats; stat != stNULL; stat = stat->stNext)
+        if (stat->stKind == skRoutine)
+		{
+			fnum = SubsystemBase + stat->stRoutine->rtNumber;
+			fname = stat->stRoutine->rtName;
+			if (! first)
+				fprintf(file, ",\\\n");
+			fprintf(file, "    { \"%s\", %d }", fname, fnum);
+			first = FALSE;
+		}
+	fprintf(file, "\n#endif\n");
+}
+
+static void
+WriteProlog(FILE *file, const char *protect, boolean_t more, boolean_t isuser)
+{
+	if (protect != strNULL) {
+		fprintf(file, "#ifndef\t_%s\n", protect);
+		fprintf(file, "#define\t_%s\n", protect);
+		fprintf(file, "\n");
+	}
+
+	fprintf(file, "/* Module %s */\n", SubsystemName);
+	fprintf(file, "\n");
+
+	if (more) {
+		WriteIncludes(file, isuser, UseSplitHeaders);
+	}
+	fprintf(file, "#ifdef AUTOTEST\n");
+	fprintf(file, "#ifndef FUNCTION_PTR_T\n");
+	fprintf(file, "#define FUNCTION_PTR_T\n");
+	fprintf(file, "typedef void (*function_ptr_t)");
+	fprintf(file, "(mach_port_t, char *, mach_msg_type_number_t);\n");
+	fprintf(file, "typedef struct {\n");
+	fprintf(file, "        char            *name;\n");
+	fprintf(file, "        function_ptr_t  function;\n");
+	fprintf(file, "} function_table_entry;\n");
+	fprintf(file, "typedef function_table_entry   *function_table_t;\n");
+	fprintf(file, "#endif /* FUNCTION_PTR_T */\n");
+	fprintf(file, "#endif /* AUTOTEST */\n");
+	fprintf(file, "\n#ifndef\t%s_MSG_COUNT\n", SubsystemName);
+	fprintf(file, "#define\t%s_MSG_COUNT\t%d\n", SubsystemName, rtNumber);
+	fprintf(file, "#endif\t/* %s_MSG_COUNT */\n\n", SubsystemName);
+}
+
+static void
+WriteEpilog(FILE *file, const char *protect, boolean_t isuser)
+{
+    const char *defname = 
+        isuser ? "__AfterMigUserHeader" : "__AfterMigServerHeader";
+
+	WriteETAPDefines(file);
+    fprintf(file, "\n#ifdef %s\n%s\n#endif /* %s */\n",
+			defname, defname, defname);
+	if (protect != strNULL) {
+		fprintf(file, "\n");
+		fprintf(file, "#endif\t /* _%s */\n", protect);
+	}
+}
+
+static void
+WriteUserRoutine(FILE *file, routine_t *rt)
+{
+	fprintf(file, "\n");
+	fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
+	WriteMigExternal(file);
+	fprintf(file, "%s %s\n", ReturnTypeStr(rt), rt->rtUserName);
+    fprintf(file, "#if\t%s\n", LintLib);
+    fprintf(file, "    (");
+    WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", " , "");
+    fprintf(file, ")\n");
+    WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ";\n", ";\n");
+    fprintf(file, "{ ");
+    fprintf(file, "return ");
+    fprintf(file, "%s(", rt->rtUserName);
+    WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", ", "");
+    fprintf(file, "); }\n");
+    fprintf(file, "#else\n");
+	if (BeAnsiC) {
+		fprintf(file, "(\n");
+		WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
+		fprintf(file, ");\n");
+    } else {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "(\n");
+		WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
+		fprintf(file, ");\n");
+		fprintf(file, "#else\n");
+
+		fprintf(file, "    ();\n");
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+	}
+	fprintf(file, "#endif\t/* %s */\n",  LintLib);
+}
+
+void
+WriteUserRequestUnion(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	fprintf(file, "/* union of all requests */\n\n");
+	fprintf(file, "#ifndef __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
+	fprintf(file, "#define __RequestUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
+	fprintf(file, "union __RequestUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName);
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		if (stat->stKind == skRoutine) {
+			register routine_t *rt;
+
+			rt = stat->stRoutine;
+			fprintf(file, "\t__Request__%s_t Request_%s;\n", rt->rtName, rt->rtUserName);
+		}
+	}
+	fprintf(file, "};\n");
+	fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName);
+}
+
+void
+WriteUserReplyUnion(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	fprintf(file, "/* union of all replies */\n\n");
+	fprintf(file, "#ifndef __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
+	fprintf(file, "#define __ReplyUnion__%s%s_subsystem__defined\n", UserPrefix, SubsystemName);
+	fprintf(file, "union __ReplyUnion__%s%s_subsystem {\n", UserPrefix, SubsystemName);
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		if (stat->stKind == skRoutine) {
+			register routine_t *rt;
+
+			rt = stat->stRoutine;
+			fprintf(file, "\t__Reply__%s_t Reply_%s;\n", rt->rtName, rt->rtUserName);
+		}
+	}
+	fprintf(file, "};\n");
+	fprintf(file, "#endif /* !__RequestUnion__%s%s_subsystem__defined */\n", UserPrefix, SubsystemName);
+}
+
+void
+WriteUserHeader(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+    const char *protect = strconcat(SubsystemName, "_user_");
+
+	WriteProlog(file, protect, TRUE, TRUE);
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		switch (stat->stKind)
+		{
+		case skImport:
+		case skUImport:
+		case skDImport:
+			WriteImport(file, stat->stFileName);
+			break;
+		case skRoutine:
+		case skSImport:
+		case skIImport:
+			break;
+		default:
+			fatal("WriteHeader(): bad statement_kind_t (%d)",
+				  (int) stat->stKind);
+		}
+    fprintf(file, "\n#ifdef __BeforeMigUserHeader\n");
+	fprintf(file, "__BeforeMigUserHeader\n");
+	fprintf(file, "#endif /* __BeforeMigUserHeader */\n");
+	fprintf(file, "\n");
+	fprintf(file, "#include <sys/cdefs.h>\n");
+	fprintf(file, "__BEGIN_DECLS\n");
+	fprintf(file, "\n");
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		if (stat->stKind == skRoutine)
+			WriteUserRoutine(file, stat->stRoutine);
+	}
+	fprintf(file, "\n");
+	fprintf(file, "__END_DECLS\n");
+
+	fprintf(file, "\n");
+	fprintf(file, "/********************** Caution **************************/\n");
+	fprintf(file, "/* The following data types should be used to calculate  */\n");
+	fprintf(file, "/* maximum message sizes only. The actual message may be */\n");
+	fprintf(file, "/* smaller, and the position of the arguments within the */\n");
+	fprintf(file, "/* message layout may vary from what is presented here.  */\n");
+	fprintf(file, "/* For example, if any of the arguments are variable-    */\n");
+	fprintf(file, "/* sized, and less than the maximum is sent, the data    */\n");
+	fprintf(file, "/* will be packed tight in the actual message to reduce  */\n");
+	fprintf(file, "/* the presence of holes.                                */\n");
+	fprintf(file, "/********************** Caution **************************/\n");
+	fprintf(file, "\n");
+
+	WriteRequestTypes(file, stats);
+	WriteUserRequestUnion(file, stats);
+
+	WriteReplyTypes(file, stats);
+	WriteUserReplyUnion(file, stats);
+
+	WriteEpilog(file, protect, TRUE);
+}
+
+static void
+WriteDefinesRoutine(FILE *file, routine_t *rt)
+{
+    char *up = (char *)malloc(strlen(rt->rtName)+1);
+
+    up = toupperstr(strcpy(up, rt->rtName));
+    fprintf(file, "#define\tMACH_ID_%s\t\t%d\t/* %s() */\n", 
+			up, rt->rtNumber + SubsystemBase, rt->rtName);
+	if (rt->rtKind == rkRoutine)
+		fprintf(file, "#define\tMACH_ID_%s_REPLY\t\t%d\t/* %s() */\n", 
+				up, rt->rtNumber + SubsystemBase + 100, rt->rtName);
+	fprintf(file, "\n");
+}
+
+void
+WriteServerRoutine(FILE *file, routine_t *rt)
+{
+	fprintf(file, "\n");
+	fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
+	WriteMigExternal(file);
+	fprintf(file, "%s %s\n", ReturnTypeStr(rt), rt->rtServerName);
+    fprintf(file, "#if\t%s\n", LintLib);
+    fprintf(file, "    (");
+    WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", " , "");
+    fprintf(file, ")\n");
+    WriteList(file, rt->rtArgs, WriteServerVarDecl,
+			  akbServerArg, ";\n", ";\n");
+    fprintf(file, "{ ");
+    fprintf(file, "return ");
+    fprintf(file, "%s(", rt->rtServerName);
+    WriteList(file, rt->rtArgs, WriteNameDecl, akbServerArg, ", ", "");
+    fprintf(file, "); }\n");
+    fprintf(file, "#else\n");
+	if (BeAnsiC) {
+		fprintf(file, "(\n");
+        WriteList(file, rt->rtArgs, WriteServerVarDecl,
+				  akbServerArg, ",\n", "\n");
+		fprintf(file, ");\n");
+    } else {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "(\n");
+        WriteList(file, rt->rtArgs, WriteServerVarDecl,
+				  akbServerArg, ",\n", "\n");
+		fprintf(file, ");\n");
+		fprintf(file, "#else\n");
+
+		fprintf(file, "    ();\n");
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+	}
+    fprintf(file, "#endif\t/* %s */\n",  LintLib);
+}
+
+static void
+WriteDispatcher(FILE *file)
+{
+	register statement_t *stat;
+	int descr_count = 0;
+
+    for (stat = defs_stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine)
+		{
+			register routine_t *rt = stat->stRoutine;
+			descr_count += rtCountArgDescriptors(rt->rtArgs, (int *) 0);
+		}
+	fprintf(file, "\n");
+
+	WriteMigExternal(file);
+	fprintf(file, "boolean_t %s(\n", ServerDemux);
+	fprintf(file, "\t\tmach_msg_header_t *InHeadP,\n");
+	fprintf(file, "\t\tmach_msg_header_t *OutHeadP);\n\n");
+
+	WriteMigExternal(file);
+	fprintf(file, "mig_routine_t %s_routine(\n", ServerDemux);
+	fprintf(file, "\t\tmach_msg_header_t *InHeadP);\n\n");
+
+	fprintf(file, "\n/* Description of this subsystem, for use in direct RPC */\n");
+	fprintf(file, "extern const struct %s {\n", ServerSubsys);
+	if (UseRPCTrap) {
+		fprintf(file, "\tstruct subsystem *\tsubsystem;\t/* Reserved for system use */\n");
+	}
+	else {
+		fprintf(file, "\tmig_server_routine_t\tserver;\t/* Server routine */\n");
+	}
+	fprintf(file, "\tmach_msg_id_t\tstart;\t/* Min routine number */\n");
+	fprintf(file, "\tmach_msg_id_t\tend;\t/* Max routine number + 1 */\n");
+	fprintf(file, "\tunsigned int\tmaxsize;\t/* Max msg size */\n");
+	if (UseRPCTrap) {
+		fprintf(file, "\tvm_address_t\tbase_addr;\t/* Base address */\n");
+		fprintf(file, "\tstruct rpc_routine_descriptor\t/*Array of routine descriptors */\n");
+	}
+	else {
+		fprintf(file, "\tvm_address_t\treserved;\t/* Reserved */\n");
+		fprintf(file, "\tstruct routine_descriptor\t/*Array of routine descriptors */\n");
+	}
+	fprintf(file, "\t\troutine[%d];\n", rtNumber);
+	if (UseRPCTrap) {
+		fprintf(file, "\tstruct rpc_routine_arg_descriptor\t/*Array of arg descriptors */\n");
+		fprintf(file, "\t\targ_descriptor[%d];\n", descr_count);
+	}
+	fprintf(file, "} %s;\n", ServerSubsys);
+	fprintf(file, "\n");
+}
+
+void
+WriteServerHeader(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+    const char *protect = strconcat(SubsystemName, "_server_");
+
+	WriteProlog(file, protect, TRUE, FALSE);
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		switch (stat->stKind)
+		{
+		case skImport:
+		case skSImport:
+		case skDImport:
+			WriteImport(file, stat->stFileName);
+			break;
+		case skRoutine:
+		case skUImport:
+		case skIImport:
+			break;
+		default:
+			fatal("WriteServerHeader(): bad statement_kind_t (%d)",
+				  (int) stat->stKind);
+		}
+	fprintf(file, "\n#ifdef __BeforeMigServerHeader\n");
+	fprintf(file, "__BeforeMigServerHeader\n");
+	fprintf(file, "#endif /* __BeforeMigServerHeader */\n\n");
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		if (stat->stKind == skRoutine)
+			WriteServerRoutine(file, stat->stRoutine);
+	}
+
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		if (stat->stKind == skRoutine)
+			WriteServerRoutine(file, stat->stRoutine);
+	}
+	WriteDispatcher(file);
+
+	WriteRequestTypes(file, stats);
+	WriteServerRequestUnion(file, stats);
+
+	WriteReplyTypes(file, stats);
+	WriteServerReplyUnion(file, stats);
+
+	WriteEpilog(file, protect, FALSE);
+}
+
+static void
+WriteInternalRedefine(FILE *file, register routine_t *rt)
+{
+    fprintf(file, "#define %s %s_external\n",
+			rt->rtUserName, rt->rtUserName);
+}
+
+void
+WriteInternalHeader(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		switch (stat->stKind)
+		{
+		case skRoutine:
+			WriteInternalRedefine(file, stat->stRoutine);
+			break;
+		case skImport:
+		case skUImport:
+		case skSImport:
+		case skDImport:
+		case skIImport:
+			break;
+		default:
+			fatal("WriteInternalHeader(): bad statement_kind_t (%d)",
+				  (int) stat->stKind);
+		}
+}
+
+void
+WriteDefinesHeader(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+    const char *protect = strconcat(SubsystemName, "_defines");
+
+	WriteProlog(file, protect, FALSE, FALSE);
+	fprintf(file, "\n/*\tDefines related to the Subsystem %s\t*/\n\n", SubsystemName);
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		switch (stat->stKind)
+		{
+		case skRoutine:
+			WriteDefinesRoutine(file, stat->stRoutine);
+			break;
+		case skImport:
+		case skSImport:
+		case skUImport:
+			break;
+		default:
+			fatal("WriteDefinesHeader(): bad statement_kind_t (%d)",
+				  (int) stat->stKind);
+		}
+	}
+	WriteEpilog(file, protect, FALSE);
+}


Property changes on: trunk/usr.bin/migcom/header.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/hp_pa/mig_machine.h
===================================================================
--- trunk/usr.bin/migcom/hp_pa/mig_machine.h	                        (rev 0)
+++ trunk/usr.bin/migcom/hp_pa/mig_machine.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc.  
+ *              All Rights Reserved  
+ *   
+ * Permission to use, copy, modify, and distribute this software and  
+ * its documentation for any purpose and without fee is hereby granted,  
+ * provided that the above copyright notice appears in all copies and  
+ * that both the copyright notice and this permission notice appear in  
+ * supporting documentation.  
+ *   
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE  
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  
+ * FOR A PARTICULAR PURPOSE.  
+ *   
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR  
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM  
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,  
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  
+ */
+/*
+ * cmk1.1
+ */
+
+#define	machine_alignment(SZ,ESZ) 					\
+	(((SZ) = ((SZ) + 3) & ~3), (SZ) += (ESZ))
+
+#define	machine_padding(BYTES)						\
+	((BYTES & 3) ? (4 - (BYTES & 3)) : 0)
+
+#ifndef	NBBY
+#define NBBY	8
+#endif
+
+#define PACK_MESSAGES TRUE


Property changes on: trunk/usr.bin/migcom/hp_pa/mig_machine.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/i386/mig_machine.h
===================================================================
--- trunk/usr.bin/migcom/i386/mig_machine.h	                        (rev 0)
+++ trunk/usr.bin/migcom/i386/mig_machine.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc.  
+ *              All Rights Reserved  
+ *   
+ * Permission to use, copy, modify, and distribute this software and  
+ * its documentation for any purpose and without fee is hereby granted,  
+ * provided that the above copyright notice appears in all copies and  
+ * that both the copyright notice and this permission notice appear in  
+ * supporting documentation.  
+ *   
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE  
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  
+ * FOR A PARTICULAR PURPOSE.  
+ *   
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR  
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM  
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,  
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  
+ */
+/*
+ * cmk1.1
+ */
+
+#define	machine_alignment(SZ,ESZ) 					\
+	(((SZ) = ((SZ) + 3) & ~3), (SZ) += (ESZ))
+
+#define	machine_padding(BYTES)						\
+	((BYTES & 3) ? (4 - (BYTES & 3)) : 0)
+
+#ifndef	NBBY
+#define NBBY	8
+#endif
+
+#define PACK_MESSAGES TRUE


Property changes on: trunk/usr.bin/migcom/i386/mig_machine.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/lexxer.h
===================================================================
--- trunk/usr.bin/migcom/lexxer.h	                        (rev 0)
+++ trunk/usr.bin/migcom/lexxer.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/02/05  17:54:38  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:28  mrt]
+ * 
+ * 90/06/02  15:04:50  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:11:15  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+extern void LookFileName(void);
+extern void LookString(void);
+extern void LookQString(void);
+extern void LookNormal(void);


Property changes on: trunk/usr.bin/migcom/lexxer.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/lexxer.l
===================================================================
--- trunk/usr.bin/migcom/lexxer.l	                        (rev 0)
+++ trunk/usr.bin/migcom/lexxer.l	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,353 @@
+/* $MidnightBSD$ */
+%k 10000
+%n 5000
+%a 20000
+%e 10000
+%p 25000
+
+Ident		([A-Za-z_][A-Za-z_0-9]*)
+Number		([0-9]+)
+String		([-/._$A-Za-z0-9]+)
+QString		(\"[^"\n]*\")
+AString		(\<[^>\n]*\>)
+FileName	({QString}|{AString})
+
+%{
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 at 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.
+ */
+/*
+ * 92/03/03  16:25:00  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:31:19  jeffreyh]
+ * 
+ * 92/01/23  15:21:24  rpd
+ * 	Fixed macros for STDC.
+ * 	[92/01/16            rpd]
+ * 
+ * 92/01/03  20:29:25  dbg
+ * 	Add 'CountInOut' flag.
+ * 	[91/11/11            dbg]
+ * 
+ * 91/08/28  11:17:01  jsb
+ * 	Added syServerDemux.
+ * 	[91/08/13            rpd]
+ * 
+ * 	Removed syMsgKind, syCamelot, syCamelotRoutine, syTrapRoutine,
+ * 	syTrapSimpleRoutine.  Added syMsgSeqno.
+ * 	[91/08/11            rpd]
+ * 
+ * 91/07/31  18:09:31  dbg
+ * 	Add 'serverCopy' keyword.
+ * 	[91/06/05            dbg]
+ * 
+ * 	Add 'c_string' keyword.
+ * 	[91/04/03            dbg]
+ * 
+ * 91/02/05  17:54:51  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:35  mrt]
+ * 
+ * 90/06/02  15:04:54  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:11:34  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include <sys/types.h>
+#include <mach/message.h>
+#include <mach/std_types.h>
+#include "strdefs.h"
+#include "type.h"
+#include "error.h"
+#include "statement.h"
+#include "global.h"
+#include "parser.h"
+#include "lexxer.h"
+#include "mig_machine.h"
+
+
+#undef yywrap
+#define yywrap() 1
+#define	PortSize	(sizeof (mach_port_t) * NBBY)
+#ifdef	__STDC__
+#define stringize(x)	#x
+#else	/* __STDC__ */
+#define	stringize(x)	"x"
+#endif	/* __STDC__ */
+
+#ifdef	LDEBUG
+#define RETURN(sym)							\
+{									\
+    printf("yylex: returning '%s' (%d)\n", stringize(sym), (sym));	\
+    return (sym);							\
+}
+#else	/* LDEBUG */
+#define RETURN(sym)	return (sym)
+#endif	/* LDEBUG */
+
+#define	TPRETURN(intype, outtype, tsize)				\
+{									\
+    yylval.symtype.innumber = (intype);					\
+    yylval.symtype.instr = stringize(intype);				\
+    yylval.symtype.outnumber = (outtype);				\
+    yylval.symtype.outstr = stringize(outtype);				\
+    yylval.symtype.size = (tsize);					\
+    RETURN(sySymbolicType);						\
+}
+
+#define	TRETURN(type, tsize)	TPRETURN(type,type,tsize)
+
+#define SAVE(s)		do {oldYYBegin = s; BEGIN s; } while (0)
+
+#define RESTORE		BEGIN oldYYBegin
+
+#define	FRETURN(val)							\
+{									\
+    yylval.flag = (val);						\
+    RETURN(syIPCFlag);							\
+}
+
+static int	oldYYBegin = 0;
+
+int lineno = 0;			/* Replaces lex yylineno */
+
+static void doSharp(); /* process body of # directives */
+extern void yyerror(const char *);
+%}
+
+%option noyywrap 
+
+%Start	Normal String FileName QString SkipToEOL
+
+%%
+
+<Normal>[Rr][Oo][Uu][Tt][Ii][Nn][Ee]		RETURN(syRoutine);
+<Normal>[Ss][Ii][Mm][Pp][Ll][Ee][Rr][Oo][Uu][Tt][Ii][Nn][Ee] RETURN(sySimpleRoutine);
+<Normal>[Ss][Uu][Bb][Ss][Yy][Ss][Tt][Ee][Mm]	RETURN(sySubsystem);
+<Normal>[Mm][Ss][Gg][Oo][Pp][Tt][Ii][Oo][Nn]	RETURN(syMsgOption);
+<Normal>[Mm][Ss][Gg][Ss][Ee][Qq][Nn][Oo]	RETURN(syMsgSeqno);
+<Normal>[Ww][Aa][Ii][Tt][Tt][Ii][Mm][Ee]	RETURN(syWaitTime);
+<Normal>[Nn][Oo][Ww][Aa][Ii][Tt][Tt][Ii][Mm][Ee]	RETURN(syNoWaitTime);
+<Normal>[Ss][Ee][Nn][Dd][Tt][Ii][Mm][Ee]	RETURN(sySendTime);
+<Normal>[Nn][Oo][Ss][Ee][Nn][Dd][Tt][Ii][Mm][Ee]	RETURN(syNoSendTime);
+<Normal>[Ii][Nn]				RETURN(syIn);
+<Normal>[Oo][Uu][Tt]				RETURN(syOut);
+<Normal>[Uu][Ss][Ee][Rr][Ii][Mm][Pp][Ll]		RETURN(syUserImpl);
+<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Ii][Mm][Pp][Ll]	RETURN(syServerImpl);
+<Normal>[Ss][Ee][Cc][Tt][Oo][Kk][Ee][Nn]	RETURN(sySecToken);
+<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Ss][Ee][Cc][Tt][Oo][Kk][Ee][Nn] RETURN(syServerSecToken);
+<Normal>[Uu][Ss][Ee][Rr][Ss][Ee][Cc][Tt][Oo][Kk][Ee][Nn]	RETURN(syUserSecToken);
+<Normal>[Aa][Uu][Dd][Ii][Tt][Tt][Oo][Kk][Ee][Nn]	RETURN(syAuditToken);
+<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Aa][Uu][Dd][Ii][Tt][Tt][Oo][Kk][Ee][Nn] RETURN(syServerAuditToken);
+<Normal>[Uu][Ss][Ee][Rr][Aa][Uu][Dd][Ii][Tt][Tt][Oo][Kk][Ee][Nn]	RETURN(syUserAuditToken);
+<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Cc][Oo][Nn][Tt][Ee][Xx][Tt][Tt][Oo][Kk][Ee][Nn]	RETURN(syServerContextToken);
+<Normal>[Ii][Nn][Oo][Uu][Tt]			RETURN(syInOut);
+<Normal>[Rr][Ee][Qq][Uu][Ee][Ss][Tt][Pp][Oo][Rr][Tt]	RETURN(syRequestPort);
+<Normal>[Rr][Ee][Pp][Ll][Yy][Pp][Oo][Rr][Tt]		RETURN(syReplyPort);
+<Normal>[Uu][Rr][Ee][Pp][Ll][Yy][Pp][Oo][Rr][Tt]	RETURN(syUReplyPort);
+<Normal>[Ss][Rr][Ee][Pp][Ll][Yy][Pp][Oo][Rr][Tt]	RETURN(sySReplyPort);
+<Normal>[Aa][Rr][Rr][Aa][Yy]			RETURN(syArray);
+<Normal>[Oo][Ff]				RETURN(syOf);
+<Normal>[Ee][Rr][Rr][Oo][Rr]			RETURN(syErrorProc);
+<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Pp][Rr][Ee][Ff][Ii][Xx] RETURN(syServerPrefix);
+<Normal>[Uu][Ss][Ee][Rr][Pp][Rr][Ee][Ff][Ii][Xx]	RETURN(syUserPrefix);
+<Normal>[Ss][Ee][Rr][Vv][Ee][Rr][Dd][Ee][Mm][Uu][Xx]	RETURN(syServerDemux);
+<Normal>[Rr][Cc][Ss][Ii][Dd]			RETURN(syRCSId);
+<Normal>[Ii][Mm][Pp][Oo][Rr][Tt]		RETURN(syImport);
+<Normal>[Uu][Ii][Mm][Pp][Oo][Rr][Tt]		RETURN(syUImport);
+<Normal>[Ss][Ii][Mm][Pp][Oo][Rr][Tt]		RETURN(sySImport);
+<Normal>[Dd][Ii][Mm][Pp][Oo][Rr][Tt]		RETURN(syDImport);
+<Normal>[Ii][Ii][Mm][Pp][Oo][Rr][Tt]		RETURN(syIImport);
+<Normal>[Tt][Yy][Pp][Ee]			RETURN(syType);
+<Normal>[Kk][Ee][Rr][Nn][Ee][Ll][Ss][Ee][Rr][Vv][Ee][Rr] RETURN(syKernelServer);
+<Normal>[Kk][Ee][Rr][Nn][Ee][Ll][Uu][Ss][Ee][Rr]	RETURN(syKernelUser);
+<Normal>[Ss][Kk][Ii][Pp]			RETURN(sySkip);
+<Normal>[Ss][Tt][Rr][Uu][Cc][Tt]		RETURN(syStruct);
+<Normal>[Ii][Nn][Tt][Rr][Aa][Nn]		RETURN(syInTran);
+<Normal>[Oo][Uu][Tt][Tt][Rr][Aa][Nn]		RETURN(syOutTran);
+<Normal>[Dd][Ee][Ss][Tt][Rr][Uu][Cc][Tt][Oo][Rr]	RETURN(syDestructor);
+<Normal>[Cc][Tt][Yy][Pp][Ee]				RETURN(syCType);
+<Normal>[Cc][Uu][Ss][Ee][Rr][Tt][Yy][Pp][Ee]		RETURN(syCUserType);
+<Normal>[Cc][Ss][Ee][Rr][Vv][Ee][Rr][Tt][Yy][Pp][Ee]	RETURN(syCServerType);
+<Normal>[Cc]_[Ss][Tt][Rr][Ii][Nn][Gg]			RETURN(syCString);
+
+<Normal>[Ss][Aa][Mm][Ee][Cc][Oo][Uu][Nn][Tt] 		FRETURN(flSameCount);
+<Normal>[Rr][Ee][Tt][Cc][Oo][Dd][Ee] 			FRETURN(flRetCode);
+<Normal>[Pp][Hh][Yy][Ss][Ii][Cc][Aa][Ll][Cc][Oo][Pp][Yy] FRETURN(flPhysicalCopy);
+<Normal>[Oo][Vv][Ee][Rr][Ww][Rr][Ii][Tt][Ee]	FRETURN(flOverwrite);
+<Normal>[Dd][Ee][Aa][Ll][Ll][Oo][Cc]		FRETURN(flDealloc);
+<Normal>[Nn][Oo][Tt][Dd][Ee][Aa][Ll][Ll][Oo][Cc] FRETURN(flNotDealloc);
+<Normal>[Cc][Oo][Uu][Nn][Tt][Ii][Nn][Oo][Uu][Tt] FRETURN(flCountInOut);
+<Normal>[Pp][Oo][Ll][Yy][Mm][Oo][Rr][Pp][Hh][Ii][Cc]	TPRETURN(MACH_MSG_TYPE_POLYMORPHIC, MACH_MSG_TYPE_POLYMORPHIC, PortSize);
+<Normal>[Aa][Uu][Tt][Oo]			FRETURN(flAuto);
+<Normal>[Cc][Oo][Nn][Ss][Tt]			FRETURN(flConst);
+<Normal>"PointerTo"				RETURN(syPointerTo);
+<Normal>"PointerToIfNot"		      	RETURN(syPointerToIfNot);
+<Normal>"ValueOf"				RETURN(syValueOf);
+<Normal>"UserTypeLimit"				RETURN(syUserTypeLimit);
+<Normal>"OnStackLimit"                          RETURN(syOnStackLimit);
+
+
+<Normal>"MACH_MSG_TYPE_UNSTRUCTURED"	TRETURN(MACH_MSG_TYPE_UNSTRUCTURED,0);
+<Normal>"MACH_MSG_TYPE_BIT"		TRETURN(MACH_MSG_TYPE_BIT,1);
+<Normal>"MACH_MSG_TYPE_BOOLEAN"		TRETURN(MACH_MSG_TYPE_BOOLEAN,32);
+<Normal>"MACH_MSG_TYPE_INTEGER_8"	TRETURN(MACH_MSG_TYPE_INTEGER_8,8);
+<Normal>"MACH_MSG_TYPE_INTEGER_16"	TRETURN(MACH_MSG_TYPE_INTEGER_16,16);
+<Normal>"MACH_MSG_TYPE_INTEGER_32"	TRETURN(MACH_MSG_TYPE_INTEGER_32,32);
+<Normal>"MACH_MSG_TYPE_INTEGER_64"	TRETURN(MACH_MSG_TYPE_INTEGER_64,64);
+<Normal>"MACH_MSG_TYPE_REAL_32"		TRETURN(MACH_MSG_TYPE_REAL_32,32);
+<Normal>"MACH_MSG_TYPE_REAL_64"		TRETURN(MACH_MSG_TYPE_REAL_64,64);
+<Normal>"MACH_MSG_TYPE_CHAR"		TRETURN(MACH_MSG_TYPE_CHAR,8);
+<Normal>"MACH_MSG_TYPE_BYTE"		TRETURN(MACH_MSG_TYPE_BYTE,8);
+
+<Normal>"MACH_MSG_TYPE_MOVE_RECEIVE"	TPRETURN(MACH_MSG_TYPE_MOVE_RECEIVE,MACH_MSG_TYPE_PORT_RECEIVE,PortSize);
+<Normal>"MACH_MSG_TYPE_COPY_SEND"	TPRETURN(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_PORT_SEND,PortSize);
+<Normal>"MACH_MSG_TYPE_MAKE_SEND"	TPRETURN(MACH_MSG_TYPE_MAKE_SEND,MACH_MSG_TYPE_PORT_SEND,PortSize);
+<Normal>"MACH_MSG_TYPE_MOVE_SEND"	TPRETURN(MACH_MSG_TYPE_MOVE_SEND,MACH_MSG_TYPE_PORT_SEND,PortSize);
+<Normal>"MACH_MSG_TYPE_MAKE_SEND_ONCE"	TPRETURN(MACH_MSG_TYPE_MAKE_SEND_ONCE,MACH_MSG_TYPE_PORT_SEND_ONCE,PortSize);
+<Normal>"MACH_MSG_TYPE_MOVE_SEND_ONCE"	TPRETURN(MACH_MSG_TYPE_MOVE_SEND_ONCE,MACH_MSG_TYPE_PORT_SEND_ONCE,PortSize);
+
+<Normal>"MACH_MSG_TYPE_PORT_NAME"	TRETURN(MACH_MSG_TYPE_PORT_NAME,PortSize);
+<Normal>"MACH_MSG_TYPE_PORT_RECEIVE"	TPRETURN(MACH_MSG_TYPE_POLYMORPHIC,MACH_MSG_TYPE_PORT_RECEIVE,PortSize);
+<Normal>"MACH_MSG_TYPE_PORT_SEND"	TPRETURN(MACH_MSG_TYPE_POLYMORPHIC,MACH_MSG_TYPE_PORT_SEND,PortSize);
+<Normal>"MACH_MSG_TYPE_PORT_SEND_ONCE"	TPRETURN(MACH_MSG_TYPE_POLYMORPHIC,MACH_MSG_TYPE_PORT_SEND_ONCE,PortSize);
+<Normal>"MACH_MSG_TYPE_POLYMORPHIC"	TPRETURN(MACH_MSG_TYPE_POLYMORPHIC, MACH_MSG_TYPE_POLYMORPHIC, PortSize);
+
+<Normal>":"		RETURN(syColon);
+<Normal>";"		RETURN(sySemi);
+<Normal>","		RETURN(syComma);
+<Normal>"+"		RETURN(syPlus);
+<Normal>"-"		RETURN(syMinus);
+<Normal>"*"		RETURN(syStar);
+<Normal>"/"		RETURN(syDiv);
+<Normal>"("		RETURN(syLParen);
+<Normal>")"		RETURN(syRParen);
+<Normal>"="		RETURN(syEqual);
+<Normal>"^"		RETURN(syCaret);
+<Normal>"~"		RETURN(syTilde);
+<Normal>"<"		RETURN(syLAngle);
+<Normal>">"		RETURN(syRAngle);
+<Normal>"["		RETURN(syLBrack);
+<Normal>"]"		RETURN(syRBrack);
+<Normal>"|"		RETURN(syBar);
+
+<Normal>{Ident}		{ yylval.identifier = strmake(yytext);
+			  RETURN(syIdentifier); }
+<Normal>{Number}	{ yylval.number = atoi(yytext); RETURN(syNumber); }
+
+<String>{String}	{ yylval.string = strmake(yytext);
+			  SAVE(Normal); RETURN(syString); }
+<FileName>{FileName}	{ yylval.string = strmake(yytext);
+			  SAVE(Normal); RETURN(syFileName); }
+<QString>{QString}	{ yylval.string = strmake(yytext);
+			  SAVE(Normal); RETURN(syQString); }
+
+^\#[ \t]*{Number}[ \t]*\"[^"]*\"	{ doSharp(yytext+1);
+					  BEGIN SkipToEOL; }
+^\#\ *{Number}				{ doSharp(yytext+1);
+					  BEGIN SkipToEOL; }
+^\#					{ yyerror("illegal # directive");
+					  BEGIN SkipToEOL; }
+^\#pragma			{ BEGIN SkipToEOL; }
+<SkipToEOL>\n		{ RESTORE; lineno++; }
+<SkipToEOL>.		;
+
+[ \t]			;
+\n			lineno++;
+.			{ SAVE(Normal); RETURN(syError); }
+
+%%
+
+extern void
+LookNormal(void)
+{
+    SAVE(Normal);
+}
+
+extern void
+LookString(void)
+{
+    SAVE(String);
+}
+
+extern void
+LookQString()
+{
+    SAVE(QString);
+}
+
+extern void
+LookFileName()
+{
+    SAVE(FileName);
+}
+
+static void
+doSharp(body)
+    char *body;
+{
+    register char *startName, *endName;
+
+    lineno = atoi(body);
+    startName = strchr(body, '"');
+    if (startName != NULL)
+    {
+	endName = strrchr(body, '"');
+	*endName = '\0';
+	strfree(__DECONST(char *,yyinname));
+	yyinname = strmake(startName+1);
+    }
+}
+

Added: trunk/usr.bin/migcom/mig.c
===================================================================
--- trunk/usr.bin/migcom/mig.c	                        (rev 0)
+++ trunk/usr.bin/migcom/mig.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,463 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/08/28  11:17:04  jsb
+ * 	Removed TrapRoutine support.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/06/25  10:31:32  rpd
+ * 	Added ServerHeaderFileName and -sheader.
+ * 	[91/05/22            rpd]
+ * 
+ * 91/02/05  17:55:02  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:42  mrt]
+ * 
+ * 90/06/19  23:01:01  rpd
+ * 	Added prefix argument to -i option.
+ * 	Replaced GenIndividualUser with UserFilePrefix.
+ * 	[90/06/03            rpd]
+ * 
+ * 90/06/02  15:04:59  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:11:47  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ *  8-Feb-89  David Golub (dbg) at Carnegie-Mellon University
+ *	Added -user, -server, and -header switches to name output files.
+ *	Added -i switch to write individual files for user routines.
+ *
+ * 17-Aug-87  Bennet Yee (bsy) at Carnegie-Mellon University
+ *	Added -s,-S switches for generating a SymTab
+ *
+ *  3-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Removed -t,-T switch as code is now the same for
+ *	multi and single threaded use.
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+/*
+ *  Switches are;
+ *    -[v,Q]  verbose or not quiet:  prints out type
+ *      and routine information as mig runs.
+ *    -[V,q]  not verbose or quiet : don't print
+ *      information during compilation
+ *      (this is the default)
+ *    -[r,R]  do or don't use rpc calls instead of
+ *      send/receive pairs. Default is -r.
+ *    -[s,S]  generate symbol table or not:  generate a
+ *      table of rpc-name, number, routine triplets
+ *      as an external data structure -- main use is
+ *      for protection system's specification of rights
+ *      and for protection dispatch code.  Default is -s.
+ *    -[l,L]  -L generate code that insert code for logging
+ *      the most important events that happen at the
+ *      stub level (message conception, target routine
+ *      calls). Default is -l.
+ *    -[k,K]  -K enforces MIG to generate K&R C language, with the
+ *      addition of ANSI C syntax under #ifdef __STDC__.
+ *      Default is -k.
+ *    -[n,N]  -n enforces NDR checking and conversion logic generation.
+ *      Default is -N (no checking).
+ *    -i <prefix>
+ *      Put each user routine in its own file.  The
+ *      file is named <prefix><routine-name>.c.
+ *    -user <name>
+ *      Name the user-side file <name>
+ *    -server <name>
+ *      Name the server-side file <name>
+ *    -header <name>
+ *      Name the user-side header file <name>
+ *    -iheader <name>
+ *      Name the user-side internal header file <name>
+ *    -sheader <name>
+ *      Name the server-side header file <name>
+ *    -dheader <name>
+ *      Name the defines (msgh_ids) header file <name>
+ *
+ *  DESIGN:
+ *  Mig uses a lexxer module created by lex from lexxer.l and
+ *  a parser module created by yacc from parser.y to parse an
+ *  interface definitions module for a mach server.
+ *  The parser module calls routines in statement.c
+ *  and routines.c to build a list of statement structures.
+ *  The most interesting statements are the routine definitions
+ *  which contain information about the name, type, characteristics
+ *  of the routine, an argument list containing information for
+ *  each argument type, and a list of special arguments. The
+ *  argument type structures are build by routines in type.c
+ *  Once parsing is completed, the three code generation modules:
+ *  header.c user.c and server.c are called sequentially. These
+ *  do some code generation directly and also call the routines
+ *  in utils.c for common (parameterized) code generation.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "error.h"
+#include "lexxer.h"
+#include "global.h"
+#include "write.h"
+
+extern int yyparse();
+static FILE *myfopen();
+
+static void
+parseArgs(int argc,char *argv[])
+{
+	while (--argc > 0)
+		if ((++argv)[0][0] == '-') 
+		{
+			switch (argv[0][1]) 
+			{
+			case 'q':
+				BeQuiet = TRUE;
+				break;
+			case 'Q':
+				BeQuiet = FALSE;
+				break;
+			case 'v':
+				BeVerbose = TRUE;
+				break;
+			case 'V':
+				BeVerbose = FALSE;
+				break;
+			case 'r':
+				UseMsgRPC = TRUE;
+				break;
+			case 'R':
+				UseMsgRPC = FALSE;
+				break;
+			case 'l':
+				UseEventLogger = FALSE;
+				break;
+			case 'L':
+				UseEventLogger = TRUE;
+				break;
+			case 'k':
+				BeAnsiC = TRUE;
+				break;
+			case 'K':
+				BeAnsiC = FALSE;
+				break;
+
+			case 'n':
+				if (streql(argv[0], "-novouchers")) {
+					IsVoucherCodeAllowed = FALSE;
+				} else {
+					CheckNDR = TRUE;
+				}
+				break;
+
+			case 'N':
+				CheckNDR = FALSE;
+				break;
+
+			case 's':
+				if (streql(argv[0], "-server"))
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal("missing name for -server option");
+					ServerFileName = strmake(argv[0]);
+				}
+				else if (streql(argv[0], "-sheader"))
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal ("missing name for -sheader option");
+					ServerHeaderFileName = strmake(argv[0]);
+				}
+				else if (streql(argv[0], "-split"))
+					UseSplitHeaders = TRUE;
+				else
+					GenSymTab = TRUE;
+				break;
+			case 'S':
+				GenSymTab = FALSE;
+				break;
+			case 't':
+				TestRPCTrap = TRUE;
+				UseRPCTrap = TRUE;
+				break;
+			case 'T':
+				UseRPCTrap = FALSE;
+				break;
+			case 'i':
+				if (streql(argv[0], "-iheader"))
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal("missing name for -iheader option");
+					InternalHeaderFileName = strmake(argv[0]);
+				}
+				else
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal("missing prefix for -i option");
+					UserFilePrefix = strmake(argv[0]);
+				}
+				break;
+			case 'u':
+				if (streql(argv[0], "-user"))
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal("missing name for -user option");
+					UserFileName = strmake(argv[0]);
+				}
+				else
+					fatal("unknown flag: '%s'", argv[0]);
+				break;
+			case 'h':
+				if (streql(argv[0], "-header"))
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal("missing name for -header option");
+					UserHeaderFileName = strmake(argv[0]);
+				}
+				else
+					fatal("unknown flag: '%s'", argv[0]);
+				break;
+			case 'd':
+				if (streql(argv[0], "-dheader"))
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal("missing name for -dheader option");
+					DefinesHeaderFileName = strmake(argv[0]);
+				}
+				else
+					fatal("unknown flag: '%s'", argv[0]);
+				break;
+			case 'm':
+				if (streql(argv[0], "-maxonstack"))
+				{
+					--argc; ++argv;
+					if (argc == 0)
+						fatal("missing size for -maxonstack option");
+					MaxMessSizeOnStack = atoi(argv[0]);
+				}
+				else
+					fatal("unknown flag: '%s'", argv[0]);
+				break;
+			case 'x':
+				ShortCircuit = TRUE;
+				break;
+			case 'X':
+				ShortCircuit = FALSE;
+				break;
+			default:
+				fatal("unknown flag: '%s'", argv[0]);
+				/*NOTREACHED*/
+			}
+		}
+		else
+			fatal("bad argument: '%s'", *argv);
+}
+
+static FILE *uheader, *server, *user;
+
+int
+main(int argc, char *argv[])
+{
+    FILE *iheader, *sheader, *dheader;
+	time_t loc;
+	extern time_t time();
+	extern string_t ctime();
+	extern string_t GenerationDate;
+
+	set_program_name("mig");
+	parseArgs(argc, argv);
+	init_global();
+	init_type();
+	loc = time((time_t *)0);
+
+	GenerationDate = ctime(&loc);
+
+	LookNormal();
+	(void) yyparse();
+
+    if (errors > 0)
+        fatal("%d errors found. Abort.\n", errors);
+
+	more_global();
+
+	uheader = myfopen(UserHeaderFileName, "w");
+	if (!UserFilePrefix)
+		user = myfopen(UserFileName, "w");
+	server = myfopen(ServerFileName, "w");
+	if (ServerHeaderFileName)
+		sheader = myfopen(ServerHeaderFileName, "w");
+    if (IsKernelServer)
+    {
+		iheader = myfopen(InternalHeaderFileName, "w");
+	}
+	if (DefinesHeaderFileName)
+		dheader = myfopen(DefinesHeaderFileName, "w");
+    if (BeVerbose)
+    {
+		printf("Writing %s ... ", UserHeaderFileName);
+		fflush(stdout);
+	}
+    WriteUserHeader(uheader, defs_stats);
+	fclose(uheader);
+    if (ServerHeaderFileName)
+    {
+		if (BeVerbose)
+		{
+			printf ("done.\nWriting %s ...", ServerHeaderFileName);
+			fflush (stdout);
+		}
+		WriteServerHeader(sheader, defs_stats);
+		fclose(sheader);
+	}
+    if (IsKernelServer)
+    {
+		if (BeVerbose)
+		{
+			printf("done.\nWriting %s ... ", InternalHeaderFileName);
+			fflush(stdout);
+		}
+		WriteInternalHeader(iheader, defs_stats);
+		fclose(iheader);
+	}
+    if (DefinesHeaderFileName)
+    {
+		if (BeVerbose)
+		{
+			printf ("done.\nWriting %s ...", DefinesHeaderFileName);
+			fflush (stdout);
+		}
+		WriteDefinesHeader(dheader, defs_stats);
+		fclose(dheader);
+	}
+    if (UserFilePrefix)
+    {
+		if (BeVerbose)
+		{
+			printf("done.\nWriting individual user files ... ");
+			fflush(stdout);
+		}
+		WriteUserIndividual(defs_stats);
+	}
+    else
+    {
+		if (BeVerbose)
+		{
+			printf("done.\nWriting %s ... ", UserFileName);
+			fflush(stdout);
+		}
+		WriteUser(user, defs_stats);
+		fclose(user);
+	}
+    if (BeVerbose)
+    {
+		printf("done.\nWriting %s ... ", ServerFileName);
+		fflush(stdout);
+	}
+    WriteServer(server, defs_stats);
+	fclose(server);
+	if (BeVerbose)
+		printf("done.\n");
+
+	return (0);
+}
+
+static FILE *
+myfopen(char *name, char *mode)
+{
+    const char *realname;
+	FILE *file;
+
+	if (name == strNULL)
+		realname = "/dev/null";
+	else
+		realname = name;
+
+	file = fopen(realname, mode);
+	if (file == NULL)
+		fatal("fopen(%s): %s", realname, strerror(errno));
+	return file;
+}


Property changes on: trunk/usr.bin/migcom/mig.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/mig.sh
===================================================================
--- trunk/usr.bin/migcom/mig.sh	                        (rev 0)
+++ trunk/usr.bin/migcom/mig.sh	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,88 @@
+#!/bin/sh
+# Front-end to migcom.
+# Since migcom only deals with stdin, we need to
+# run things through the pre-processor.
+#
+# This is based on the Mac OS man page for mig.
+# Which is annoying, because the options aren't
+# parsable using getopts
+PROG="$0"
+
+QUIET="-Q"	# -q or -Q
+VERBOSE=""	# -v or -V
+EVLOG="-l"	# -l or -L
+ANSI="-k"	# -k or -K
+SERVSYM="-S"	# -S or -s
+USERPREFIX=""	# -i <prefix>
+USERRPC=""	# -user <path>
+SRVRPC=""	# -server <path>
+USRHDR=""	# -header <path>
+SYSHDR=""	# -sheader <path>
+IHDR=""		# -iheader <path>
+GHDR=""		# -dheader <path>
+STACKMAX=""	# -maxonstack <value>
+SPLIT=""	# -split
+ARCH=""		# -arch <arch>, ignored
+MD=""		# -MD, passed to cc
+CPP=""		# -cpp <path>, ignored
+CC="/usr/bin/cc"	# -cc <path>
+MIGCOM="/usr/bin/migcom"	# -migcom <path>
+# This is a hack, and I'm not entirely sure it's
+# valid.
+SYSROOT=$(expr $(dirname $0) : "\(.*\)/usr/bin") || SYSROOT=""
+
+while [ $# -gt 1 ]
+do
+    case "$1" in
+	-q)	QUIET="-q" ; shift ;;
+	-Q)	QUIET="-Q" ; shift ;;
+	-l)	EVLOG="-l" ; shift ;;
+	-L)	EVLOG="-L" ; shift ;;
+	-k)	ANSI="-k" ; shift ;;
+	-K)	ANSI="-K" ; shift ;;
+	-s)	SERVSYM="-s" ; shift ;;
+	-S)	SERVSYM="-S" ; shift ;;
+	-V)	VERBOSE="-V" ; shift ;;
+	-v)	VERBOSE="-v" ; shift ;;
+	-split)	SPLIT="-split" ; shift ;;
+	-MD)	MD="-MD" ; shift ;;
+	-i)	if [ $# -le 2 ] ; then usage ; fi ; USERPREFIX="-i $2" ; shift 2 ;;
+	-user)	if [ $# -le 2 ] ; then usage ; fi ; USERRPC="-user $2" ; shift 2 ;;
+	-server)	if [ $# -le 2 ]; then usage ; fi ; SRVRPC="-server $2" ; shift 2 ;;
+	-header)	if [ $# -le 2 ]; then usage ; fi ; USRHDR="-header $2" ; shift 2 ;;
+	-sheader)	if [ $# -le 2 ]; then usage ; fi ; SYSHDR="-sheader $2" ; shift 2 ;;
+	-iheader)	if [ $# -le 2 ]; then usage ; fi ; IHDR="-iheader $2" ; shift 2 ;;
+	-dheader)	if [ $# -le 2 ]; then usage ; fi ; GHDR="-dheader $2" ; shift 2 ;;
+	-maxonstack)	if [ $# -le 2 ]; then usage ; fi ; STACKMAX="-maxonstack $2" ; shift 2 ;;
+	-cpp)	if [ $# -le 2 ]; then usage ; fi ; shift 2 ;;
+	-cc)	if [ $# -le 2 ]; then usage ; fi ; CC="$2" ; shift 2 ;;
+	-migcom)	if [ $# -le 2 ]; then usage ; fi ; MIGCOM="$2" ; shift 2 ;;
+	-isysroot)	if [ $# -le 2 ]; then usage ; fi ; SYSROOT="$2" ; shift 2 ;;
+	-*)	CFLAGS="${CFLAGS} $1" ; shift ;;
+    esac
+done
+
+CC="${CC}"
+MIGCOM="${SYSROOT}${MIGCOM}"
+
+if [ $# -ne 1 ]; then
+    usage
+fi
+
+input_file="$1"
+
+tmpfile=${TMPDIR:-/tmp}/migcom-$$.c
+
+( echo "#line 1 \"${input_file}\"" ; cat ${input_file} ) > ${tmpfile}
+if ! ${CC} ${MD} ${CFLAGS} -E ${tmpfile} |
+	${MIGCOM} ${QUIET} ${EVLOG} ${ANSI} ${SERVSYM} \
+	    ${SPLIT} ${USERPREFIX} ${VERBOSE} \
+	    ${USERRPC} ${SRVRPC} \
+	    ${USRHDR} ${SYSHDR} \
+	    ${IHDR} ${GHDR} \
+	    ${STACKMAX}
+then
+    rm -f ${tmpfile}
+    exit 1
+fi
+exit 0


Property changes on: trunk/usr.bin/migcom/mig.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/migcom.1
===================================================================
--- trunk/usr.bin/migcom/migcom.1	                        (rev 0)
+++ trunk/usr.bin/migcom/migcom.1	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,91 @@
+.TH MIG 1 
+.SH NAME
+mig \- Mach Interface Generator
+.SH SYNOPSIS
+.B mig
+[ 
+.I "option \&..."
+] 
+.I "file"
+ 
+.SH DESCRIPTION
+The
+.I mig
+command invokes the Mach Interface Generator to generate Remote Procedure Call (RPC)
+code for client-server style Mach IPC from specification files.
+.SH OPTIONS
+.TP
+.B \-q/-Q
+Omit /
+.I emit
+warning messages.
+.TP
+.B \-v/-V
+Verbose mode ( on /
+.I off
+) will summarize types and routines as they are processed.
+.TP
+.B \-l/-L
+Controls (
+.I off
+/ on ) whether or not generated code logs RPC events to system logs.
+.TP
+.B \-k/-K
+Controls (
+.I on
+/ off ) whether generated code complies with ANSI C standards.
+.TP
+.B \-s/-S
+Controls ( on /
+.I off
+) whether generated server-side code includes a generated symbol table.
+.TP
+.BI \-i " prefix"
+Specify User file prefix.
+.TP
+.BI \-user " path"
+Specify name of user-side RPC generated source file.
+.TP
+.BI \-server " path"
+Specify name of server-side RPC generated source file.
+.TP
+.BI \-header " path"
+Specify name of user-side generated header file.
+.TP
+.BI \-sheader " path"
+Specify name of server-side generated header file.
+.TP
+.BI \-iheader " path"
+Specify internal header file name.
+.TP
+.BI \-dheader " path"
+Specify defines generated header file.
+.TP
+.BI \-maxonstack " value"
+Specify maximum size of message on stack.
+.TP
+.B \-split
+Use split headers.
+.TP
+.BI \-arch " arch"
+Specify machine architecture for target code.
+.TP
+.B \-MD
+Option is passed to the C compiler for dependency generation.
+.TP
+.B \-cpp
+This option is ignored.
+.TP
+.BI \-cc " path"
+Specify pathname to specific C compiler to use as the preprocessor.
+.TP
+.BI \-migcom " path"
+Specify pathname to specific migcom compiler to use for source code generation.
+.TP
+.BI \-isysroot " path"
+Specify SDK root directory.
+.TP
+Additional options provided are passed along to the C compiler unchanged.
+.SH NOTES
+This man page is courtesy of Apple Computer, Inc. migcom(1) is from the
+original osfmk sources.


Property changes on: trunk/usr.bin/migcom/migcom.1
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/parser.y
===================================================================
--- trunk/usr.bin/migcom/parser.y	                        (rev 0)
+++ trunk/usr.bin/migcom/parser.y	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,833 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ * 
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ * 
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/08/28  11:17:06  jsb
+ * 	Added ServerDemux.
+ * 	[91/08/13            rpd]
+ * 
+ * 	Removed Camelot, TrapRoutine support.
+ * 	Removed obsolete translation and destructor specs.
+ * 	Replaced MsgKind with MsgSeqno.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/07/31  18:10:00  dbg
+ * 	Allow 'dealloc[]' to mean user-specified deallocate flag.
+ * 
+ * 	Added c_string.
+ * 	[91/04/03            dbg]
+ * 
+ * 91/02/05  17:55:12  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:54:54  mrt]
+ * 
+ * 90/06/02  15:05:11  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:12:20  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 17-Feb-87  Mary Thompson (mrt) at Carnegie Mellon
+ *	Simplied syntax for translation and destructor functions.
+ *	Also allowed any combination of these functions.
+ *
+ * 16-Nov-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Added maximum-size notation for arrays.  Added destructor
+ *	for server-side.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+%token	sySkip
+%token	syRoutine
+%token	sySimpleRoutine
+
+%token	sySubsystem
+%token	syKernelUser
+%token	syKernelServer
+
+%token	syMsgOption
+%token	syMsgSeqno
+%token	syWaitTime
+%token	sySendTime
+%token	syNoWaitTime
+%token	syNoSendTime
+%token	syErrorProc
+%token	syServerPrefix
+%token	syUserPrefix
+%token	syServerDemux
+%token	syRCSId
+
+%token	syImport
+%token	syUImport
+%token	sySImport
+%token  syIImport
+%token  syDImport
+
+%token	syIn
+%token	syOut
+%token	syInOut
+%token	syUserImpl
+%token	syServerImpl
+%token	syRequestPort
+%token	syReplyPort
+%token	sySReplyPort
+%token	syUReplyPort
+
+%token	syType
+%token	syArray
+%token	syStruct
+%token	syOf
+
+%token	syInTran
+%token	syOutTran
+%token	syDestructor
+%token	syCType
+%token	syCUserType
+%token	syUserTypeLimit
+%token	syOnStackLimit
+%token	syCServerType
+%token  syPointerTo
+%token  syPointerToIfNot
+%token  syValueOf
+
+%token	syCString
+%token	sySecToken
+%token	syUserSecToken
+%token	syServerSecToken
+%token	syAuditToken
+%token	syUserAuditToken
+%token	syServerAuditToken
+%token	syServerContextToken
+
+%token	syColon
+%token	sySemi
+%token	syComma
+%token	syPlus
+%token	syMinus
+%token	syStar
+%token	syDiv
+%token	syLParen
+%token	syRParen
+%token	syEqual
+%token	syCaret
+%token	syTilde
+%token	syLAngle
+%token	syRAngle
+%token	syLBrack
+%token	syRBrack
+%token	syBar
+
+%token	syError			/* lex error */
+
+%token	<number>	syNumber
+%token	<symtype>	sySymbolicType
+%token	<identifier>	syIdentifier
+%token	<string>	syString syQString
+%token	<string>	syFileName
+%token	<flag>		syIPCFlag
+
+%left	syPlus syMinus
+%left	syStar syDiv
+
+
+%type	<statement_kind> ImportIndicant
+%type	<number> VarArrayHead ArrayHead StructHead IntExp
+%type	<type> NamedTypeSpec TransTypeSpec NativeTypeSpec TypeSpec
+%type	<type> CStringSpec
+%type	<type> BasicTypeSpec PrevTypeSpec ArgumentType
+%type   <identifier> TypePhrase
+%type	<symtype> PrimIPCType IPCType
+%type	<routine> RoutineDecl Routine SimpleRoutine
+%type	<direction> Direction TrImplKeyword
+%type	<argument> Argument Trailer Arguments ArgumentList
+%type	<flag> IPCFlags
+
+%{
+
+#include <stdio.h>
+#include "lexxer.h"
+#include "strdefs.h"
+#include "type.h"
+#include "routine.h"
+#include "statement.h"
+#include "global.h"
+#include "error.h"
+
+static const char *import_name(statement_kind_t);
+int yylex(void);
+extern int yydebug;
+extern int yynerrs;
+extern int yyerrflag;
+extern int yychar;
+union migyys;
+extern union migyys yyval;
+extern union migyys yylval;
+%}
+
+%union migyys
+{
+    u_int number;
+    identifier_t identifier;
+    string_t string;
+    statement_kind_t statement_kind;
+    ipc_type_t *type;
+    struct
+    {
+      u_int innumber;		/* msgt_name value, when sending */
+      string_t instr;
+      u_int outnumber;	/* msgt_name value, when receiving */
+      string_t outstr;
+      u_int size;		/* 0 means there is no default size */
+    } symtype;
+    routine_t *routine;
+    arg_kind_t direction;
+    argument_t *argument;
+    ipc_flags_t flag;
+}
+
+%%
+
+Statements		:	/* empty */
+			|	Statements Statement
+			;
+
+Statement		:	Subsystem sySemi
+			|	WaitTime sySemi
+			|	SendTime sySemi
+			|	MsgOption sySemi
+                        |       UserTypeLimit sySemi
+                        |       OnStackLimit sySemi
+			|	Error sySemi
+			|	ServerPrefix sySemi
+			|	UserPrefix sySemi
+			|	ServerDemux sySemi
+			|	TypeDecl sySemi
+			|	RoutineDecl sySemi
+{
+    register statement_t *st = stAlloc();
+
+    st->stKind = skRoutine;
+    st->stRoutine = $1;
+    rtCheckRoutine($1);
+    if (BeVerbose)
+      rtPrintRoutine($1);
+}
+			|	sySkip sySemi
+				{ rtSkip(); }
+			|	Import sySemi
+			|	RCSDecl sySemi
+			|	sySemi
+			|	error sySemi
+				{ yyerrok; }
+			;
+
+Subsystem		:	SubsystemStart SubsystemMods
+				SubsystemName SubsystemBase
+{
+    if (BeVerbose)
+    {
+    printf("Subsystem %s: base = %u%s%s\n\n",
+    SubsystemName, SubsystemBase,
+    IsKernelUser ? ", KernelUser" : "",
+    IsKernelServer ? ", KernelServer" : "");
+  }
+}
+			;
+
+SubsystemStart		:	sySubsystem
+{
+    if (SubsystemName != strNULL)
+    {
+      warn("previous Subsystem decl (of %s) will be ignored", SubsystemName);
+      IsKernelUser = FALSE;
+      IsKernelServer = FALSE;
+	  strfree(__DECONST(char *, SubsystemName));
+    }
+}
+			;
+
+SubsystemMods		:	/* empty */
+			|	SubsystemMods SubsystemMod
+			;
+
+SubsystemMod		:	syKernelUser
+{
+    if (IsKernelUser)
+      warn("duplicate KernelUser keyword");
+    if (!UseMsgRPC) 
+    {
+      warn("with KernelUser the -R option is meaningless");
+      UseMsgRPC = TRUE;
+    }
+    IsKernelUser = TRUE;
+}
+			|	syKernelServer
+{
+    if (IsKernelServer)
+      warn("duplicate KernelServer keyword");
+    IsKernelServer = TRUE;
+}
+			;
+
+SubsystemName		:	syIdentifier	{ SubsystemName = $1; }
+			;
+
+SubsystemBase		:	syNumber	{ SubsystemBase = $1; }
+			;
+
+MsgOption		:	LookString syMsgOption syString
+{
+    if (streql($3, "MACH_MSG_OPTION_NONE"))
+    {
+      MsgOption = strNULL;
+      if (BeVerbose)
+          printf("MsgOption: canceled\n\n");
+    }
+    else
+    {
+      MsgOption = $3;
+      if (BeVerbose)
+          printf("MsgOption %s\n\n",$3);
+    }
+}
+			;
+
+UserTypeLimit           :       syUserTypeLimit syNumber
+				{UserTypeLimit = $2; }
+                        ;
+OnStackLimit            :       syOnStackLimit syNumber
+				{MaxMessSizeOnStack = $2; }
+                        ;
+
+WaitTime		:	LookString syWaitTime syString
+{
+    WaitTime = $3;
+    if (BeVerbose)
+      printf("WaitTime %s\n\n", WaitTime);
+}
+			|	syNoWaitTime
+{
+    WaitTime = strNULL;
+    if (BeVerbose)
+      printf("NoWaitTime\n\n");
+}
+			;
+
+SendTime		:	LookString sySendTime syString
+{
+    SendTime = $3;
+    if (BeVerbose)
+      printf("SendTime %s\n\n", SendTime);
+}
+			|	syNoSendTime
+{
+    SendTime = strNULL;
+    if (BeVerbose)
+      printf("NoSendTime\n\n");
+}
+			;
+
+Error			:	syErrorProc syIdentifier
+{
+    ErrorProc = $2;
+    if (BeVerbose)
+      printf("ErrorProc %s\n\n", ErrorProc);
+}
+			;
+
+ServerPrefix		:	syServerPrefix syIdentifier
+{
+    ServerPrefix = $2;
+    if (BeVerbose)
+      printf("ServerPrefix %s\n\n", ServerPrefix);
+}
+			;
+
+UserPrefix		:	syUserPrefix syIdentifier
+{
+    UserPrefix = $2;
+    if (BeVerbose)
+      printf("UserPrefix %s\n\n", UserPrefix);
+}
+			;
+
+ServerDemux		:	syServerDemux syIdentifier
+{
+    ServerDemux = $2;
+    if (BeVerbose)
+      printf("ServerDemux %s\n\n", ServerDemux);
+}
+			;
+
+Import			:	LookFileName ImportIndicant syFileName
+{
+    register statement_t *st = stAlloc();
+    st->stKind = $2;
+    st->stFileName = $3;
+
+    if (BeVerbose)
+      printf("%s %s\n\n", import_name($2), $3);
+}
+			;
+
+ImportIndicant		:	syImport	{ $$ = skImport; }
+			|	syUImport	{ $$ = skUImport; }
+			|	sySImport	{ $$ = skSImport; }
+			|	syIImport	{ $$ = skIImport; }
+			|	syDImport	{ $$ = skDImport; }
+			;
+
+RCSDecl			:	LookQString syRCSId syQString
+{
+    if (RCSId != strNULL)
+      warn("previous RCS decl will be ignored");
+    if (BeVerbose)
+      printf("RCSId %s\n\n", $3);
+    RCSId = $3;
+}
+			;
+
+TypeDecl		:	syType NamedTypeSpec
+{
+    register identifier_t name = $2->itName;
+
+    if (itLookUp(name) != itNULL)
+      warn("overriding previous definition of %s", name);
+    itInsert(name, $2);
+}
+			;
+
+NamedTypeSpec		:	syIdentifier syEqual TransTypeSpec
+				{ itTypeDecl($1, $$ = $3); }
+			;
+
+TransTypeSpec		:	TypeSpec
+				{ $$ = itResetType($1); }
+			|	TransTypeSpec syInTran syColon syIdentifier
+				syIdentifier syLParen syIdentifier syRParen
+{
+    $$ = $1;
+
+    if (($$->itTransType != strNULL) && !streql($$->itTransType, $4))
+	warn("conflicting translation types (%s, %s)",
+	     $$->itTransType, $4);
+    $$->itTransType = $4;
+
+    if (($$->itInTrans != strNULL) && !streql($$->itInTrans, $5))
+	warn("conflicting in-translation functions (%s, %s)",
+	     $$->itInTrans, $5);
+    $$->itInTrans = $5;
+
+    if (($$->itServerType != strNULL) && !streql($$->itServerType, $7))
+	warn("conflicting server types (%s, %s)",
+	     $$->itServerType, $7);
+    $$->itServerType = $7;
+}
+			|	TransTypeSpec syOutTran syColon syIdentifier
+				syIdentifier syLParen syIdentifier syRParen
+{
+    $$ = $1;
+
+    if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
+	warn("conflicting server types (%s, %s)",
+	     $$->itServerType, $4);
+    $$->itServerType = $4;
+
+    if (($$->itOutTrans != strNULL) && !streql($$->itOutTrans, $5))
+	warn("conflicting out-translation functions (%s, %s)",
+	     $$->itOutTrans, $5);
+    $$->itOutTrans = $5;
+
+    if (($$->itTransType != strNULL) && !streql($$->itTransType, $7))
+	warn("conflicting translation types (%s, %s)",
+	     $$->itTransType, $7);
+    $$->itTransType = $7;
+}
+			|	TransTypeSpec syDestructor syColon syIdentifier
+				syLParen syIdentifier syRParen
+{
+    $$ = $1;
+
+    if (($$->itDestructor != strNULL) && !streql($$->itDestructor, $4))
+	warn("conflicting destructor functions (%s, %s)",
+	     $$->itDestructor, $4);
+    $$->itDestructor = $4;
+
+    if (($$->itTransType != strNULL) && !streql($$->itTransType, $6))
+	warn("conflicting translation types (%s, %s)",
+	     $$->itTransType, $6);
+    $$->itTransType = $6;
+}
+			|	TransTypeSpec syCType syColon syIdentifier
+{
+    $$ = $1;
+
+    if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
+	warn("conflicting user types (%s, %s)",
+	     $$->itUserType, $4);
+    $$->itUserType = $4;
+
+    if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
+	warn("conflicting server types (%s, %s)",
+	     $$->itServerType, $4);
+    $$->itServerType = $4;
+}
+			|	TransTypeSpec syCUserType syColon syIdentifier
+{
+    $$ = $1;
+
+    if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
+	warn("conflicting user types (%s, %s)",
+	     $$->itUserType, $4);
+    $$->itUserType = $4;
+}
+			|	TransTypeSpec syCServerType
+				syColon syIdentifier
+{
+    $$ = $1;
+
+    if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
+	warn("conflicting server types (%s, %s)",
+	     $$->itServerType, $4);
+    $$->itServerType = $4;
+}
+			;
+
+TypeSpec		:	BasicTypeSpec
+				{ $$ = $1; }
+			|	PrevTypeSpec
+				{ $$ = $1; }
+			|	VarArrayHead TypeSpec
+				{ $$ = itVarArrayDecl($1, $2); }
+			|	ArrayHead TypeSpec
+				{ $$ = itArrayDecl($1, $2); }
+			|	syCaret TypeSpec
+				{ $$ = itPtrDecl($2); }
+			|	StructHead TypeSpec
+				{ $$ = itStructDecl($1, $2); }
+			|	CStringSpec
+				{ $$ = $1; }
+                        |       NativeTypeSpec
+				{ $$ = $1; }
+			;
+
+NativeTypeSpec          :       syPointerTo syLParen TypePhrase syRParen
+                                { $$ = itNativeType($3, TRUE, 0); }
+                        |       syPointerToIfNot syLParen TypePhrase syComma
+                                TypePhrase syRParen
+                                { $$ = itNativeType($3, TRUE, $5); }
+                        |       syValueOf syLParen TypePhrase syRParen
+                                { $$ = itNativeType($3, FALSE, 0); }
+			;
+
+BasicTypeSpec		:	IPCType
+{
+    $$ = itShortDecl($1.innumber, $1.instr,
+		     $1.outnumber, $1.outstr,
+		     $1.size);
+}
+			|	syLParen IPCType syComma IntExp
+				IPCFlags syRParen
+{
+    error("Long form type declarations aren't allowed anylonger\n");
+}
+			;
+
+PrimIPCType		:	syNumber
+{
+    $$.innumber = $$.outnumber = $1;
+    $$.instr = $$.outstr = strNULL;
+    $$.size = 0;
+}
+			|	sySymbolicType
+				{ $$ = $1; }
+			;
+
+IPCType			:	PrimIPCType
+				{ $$ = $1; }
+			|	PrimIPCType syBar PrimIPCType
+{
+    if ($1.size != $3.size)
+    {
+    if ($1.size == 0)
+      $$.size = $3.size;
+    else if ($3.size == 0)
+      $$.size = $1.size;
+	else
+	{
+      error("sizes in IPCTypes (%d, %d) aren't equal",
+      $1.size, $3.size);
+      $$.size = 0;
+    }
+  }
+  else
+    $$.size = $1.size;
+  $$.innumber = $1.innumber;
+  $$.instr = $1.instr;
+  $$.outnumber = $3.outnumber;
+  $$.outstr = $3.outstr;
+}
+			;
+
+PrevTypeSpec		:	syIdentifier
+				{ $$ = itPrevDecl($1); }
+			;
+
+VarArrayHead		:	syArray syLBrack syRBrack syOf
+				{ $$ = 0; }
+			|	syArray syLBrack syStar syRBrack syOf
+				{ $$ = 0; }
+			|	syArray syLBrack syStar syColon IntExp
+				syRBrack syOf
+				{ $$ = $5; }
+			;
+
+ArrayHead		:	syArray syLBrack IntExp syRBrack syOf
+				{ $$ = $3; }
+			;
+
+StructHead		:	syStruct syLBrack IntExp syRBrack syOf
+				{ $$ = $3; }
+			;
+
+CStringSpec		:	syCString syLBrack IntExp syRBrack
+				{ $$ = itCStringDecl($3, FALSE); }
+			|	syCString syLBrack syStar syColon
+				IntExp syRBrack
+				{ $$ = itCStringDecl($5, TRUE); }
+			;
+
+TypePhrase              :       syIdentifier
+                                { $$ = $1; }
+                        |       TypePhrase syIdentifier
+                                { $$ = strphrase($1, $2); strfree($2); }
+			;
+
+IntExp			: 	IntExp	syPlus	IntExp
+				{ $$ = $1 + $3;	}
+			| 	IntExp	syMinus	IntExp
+				{ $$ = $1 - $3;	}
+			|	IntExp	syStar	IntExp
+				{ $$ = $1 * $3;	}
+			| 	IntExp	syDiv	IntExp
+				{ $$ = $1 / $3;	}
+			|	syNumber
+				{ $$ = $1;	}
+			|	syLParen IntExp syRParen
+				{ $$ = $2;	}
+			;
+
+
+RoutineDecl		:	Routine			{ $$ = $1; }
+			|	SimpleRoutine		{ $$ = $1; }
+			;
+
+Routine			:	syRoutine syIdentifier Arguments
+				{ $$ = rtMakeRoutine($2, $3); }
+			;
+
+SimpleRoutine		:	sySimpleRoutine syIdentifier Arguments
+				{ $$ = rtMakeSimpleRoutine($2, $3); }
+			;
+
+Arguments		:	syLParen syRParen
+				{ $$ = argNULL; }
+			|	syLParen ArgumentList syRParen
+				{ $$ = $2; }
+
+			;
+
+ArgumentList		:	Argument
+				{ $$ = $1; }
+			|       Trailer
+				{ $$ = $1; }
+			|	Argument sySemi ArgumentList
+{
+  $$ = $1;
+  $$->argNext = $3;
+}
+			|       Trailer sySemi ArgumentList
+{
+  $$ = $1;
+  $$->argNext = $3;
+}
+			;
+
+Argument		:	Direction syIdentifier ArgumentType IPCFlags
+{
+  $$ = argAlloc();
+  $$->argKind = $1;
+  $$->argName = $2;
+  $$->argType = $3;
+  $$->argFlags = $4;
+  if ($3 && $3->itNative) {
+      if ($1 != akIn && $1 != akOut && $1 != akInOut)
+        error("Illegal direction specified");
+
+      if (!($3->itNativePointer) && $1 != akIn)
+        error("ValueOf only valid for in");
+
+      if (($3->itBadValue) != NULL && $1 != akIn)
+        error("PointerToIfNot only valid for in");
+  }
+}
+			;
+
+Trailer			:	TrImplKeyword syIdentifier ArgumentType
+{
+    $$ = argAlloc();
+    $$->argKind = $1;
+    $$->argName = $2;
+    $$->argType = $3;
+}
+			;
+
+
+Direction		:	/* empty */	{ $$ = akNone; }
+			|	syIn		{ $$ = akIn; }
+			|	syOut		{ $$ = akOut; }
+			|	syInOut		{ $$ = akInOut; }
+			|	syRequestPort	{ $$ = akRequestPort; }
+			|	syReplyPort	{ $$ = akReplyPort; }
+			|	sySReplyPort	{ $$ = akSReplyPort; }
+			|	syUReplyPort	{ $$ = akUReplyPort; }
+			|	syWaitTime	{ $$ = akWaitTime; }
+			|	sySendTime 	{ $$ = akSendTime; }
+			|	syMsgOption	{ $$ = akMsgOption; }
+			|	sySecToken		{ $$ = akSecToken; }
+			|	syServerSecToken	{ $$ = akServerSecToken; }
+			|	syUserSecToken		{ $$ = akUserSecToken; }
+			|	syAuditToken		{ $$ = akAuditToken; }
+			|	syServerAuditToken	{ $$ = akServerAuditToken; }
+			|	syUserAuditToken	{ $$ = akUserAuditToken; }
+			|	syServerContextToken	{ $$ = akServerContextToken; }
+			|	syMsgSeqno	{ $$ = akMsgSeqno; }
+			;
+
+TrImplKeyword		:	syServerImpl	{ $$ = akServerImpl; }
+			|	syUserImpl	{ $$ = akUserImpl; }
+			;
+
+
+ArgumentType		:	syColon syIdentifier
+{
+  $$ = itLookUp($2);
+  if ($$ == itNULL)
+    error("type '%s' not defined", $2);
+}
+			|	syColon NamedTypeSpec
+				{ $$ = $2; }
+                        |       syColon NativeTypeSpec
+				{ $$ = $2; }
+			;
+
+IPCFlags		:	/* empty */
+				{ $$ = flNone; }
+			|	IPCFlags syComma syIPCFlag
+{
+  if ($1 & $3)
+    warn("redundant IPC flag ignored");
+  else
+    $$ = $1 | $3;
+}
+			|	IPCFlags syComma syIPCFlag syLBrack syRBrack
+{
+  if ($3 != flDealloc)
+    warn("only Dealloc is variable");
+  else
+    $$ = $1 | flMaybeDealloc;
+}
+
+LookString		:	/* empty */
+				{ LookString(); }
+			;
+
+LookFileName		:	/* empty */
+				{ LookFileName(); }
+			;
+
+LookQString		:	/* empty */
+				{ LookQString(); }
+			;
+
+%%
+
+void yyerror(const char *s);
+
+void
+yyerror(const char *s)
+{
+  error(s);
+}
+
+static const char *
+import_name(statement_kind_t sk)
+{
+    switch (sk)
+    {
+    case skImport:
+      return "Import";
+    case skSImport:
+      return "SImport";
+    case skUImport:
+      return "UImport";
+    case skIImport:
+      return "IImport";
+    case skDImport:
+      return "DImport";
+    default:
+      fatal("import_name(%d): not import statement", (int) sk);
+      /*NOTREACHED*/
+      return strNULL;
+  }
+}

Added: trunk/usr.bin/migcom/ppc/mig_machine.h
===================================================================
--- trunk/usr.bin/migcom/ppc/mig_machine.h	                        (rev 0)
+++ trunk/usr.bin/migcom/ppc/mig_machine.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc.  
+ *              All Rights Reserved  
+ *   
+ * Permission to use, copy, modify, and distribute this software and  
+ * its documentation for any purpose and without fee is hereby granted,  
+ * provided that the above copyright notice appears in all copies and  
+ * that both the copyright notice and this permission notice appear in  
+ * supporting documentation.  
+ *   
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE  
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  
+ * FOR A PARTICULAR PURPOSE.  
+ *   
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR  
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM  
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,  
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  
+ */
+/*
+ * cmk1.1
+ */
+
+#define	machine_alignment(SZ,ESZ) 					\
+	(((SZ) = ((SZ) + 3) & ~3), (SZ) += (ESZ))
+
+#define	machine_padding(BYTES)						\
+	((BYTES & 3) ? (4 - (BYTES & 3)) : 0)
+
+#ifndef	NBBY
+#define NBBY	8
+#endif
+
+#ifndef PACK_MESSAGES
+#define PACK_MESSAGES TRUE
+#endif


Property changes on: trunk/usr.bin/migcom/ppc/mig_machine.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/routine.c
===================================================================
--- trunk/usr.bin/migcom/routine.c	                        (rev 0)
+++ trunk/usr.bin/migcom/routine.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,1861 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 at 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.
+ */
+
+/*
+ *  ABSTRACT:
+ *   Provides the routine used by parser.c to generate
+ *   routine structures for each routine statement.
+ *   The parser generates a threaded list of statements
+ *   of which the most interesting are the various kinds
+ *   routine statments. The routine structure is defined
+ *   in routine.h which includes it name, kind of routine
+ *   and other information,
+ *   a pointer to an argument list which contains the name
+ *   and type information for each argument, and a list
+ *   of distinguished arguments, eg.  Request and Reply
+ *   ports, waittime, retcode etc.
+ */
+#include <stdio.h>
+
+#include "type.h"
+#include <mach/message.h>
+#include <mach/kern_return.h>
+#include "mig_machine.h"
+#include "error.h"
+#include "alloc.h"
+#include "global.h"
+#include "routine.h"
+#include "write.h"
+#include "utils.h"
+
+u_int rtNumber = 0;
+
+static void rtSizeDelta();
+
+routine_t *
+rtAlloc(void)
+{
+	register routine_t *new;
+
+	new = (routine_t *) calloc(1, sizeof *new);
+	if (new == rtNULL)
+		fatal("rtAlloc(): %s", strerror(errno));
+	new->rtNumber = rtNumber++;
+	new->rtName = strNULL;
+	new->rtErrorName = strNULL;
+	new->rtUserName = strNULL;
+	new->rtServerName = strNULL;
+
+	return new;
+}
+
+void
+rtSkip(void)
+{
+	rtNumber++;
+}
+
+argument_t *
+argAlloc(void)
+{
+	static argument_t prototype =
+		{
+			strNULL,      /* identifier_t argName */
+			argNULL,      /* argument_t *argNext */
+			akNone,       /* arg_kind_t argKind */
+			itNULL,       /* ipc_type_t *argType */
+			argKPD_NULL,  /* mach_msg_descriptor_type_t argKPD_Type */
+			KPD_error,    /* KPD discipline for templates */
+			KPD_error,    /* KPD discipline for initializing */
+			KPD_error,    /* KPD discipline for packing */
+			KPD_error,    /* KPD discipline for extracting */
+			KPD_error,    /* KPD discipline for type checking */
+			strNULL,      /* string_t argVarName */
+			strNULL,      /* string_t argMsgField */
+			strNULL,      /* string_t argTTName */
+			strNULL,      /* string_t argPadName */
+			strNULL,      /* string_t argSuffix */
+			flNone,       /* ipc_flags_t argFlags */
+			d_NO,         /* dealloc_t argDeallocate */
+			FALSE,        /* boolean_t argCountInOut */
+			rtNULL,       /* routine_t *argRoutine */
+			argNULL,      /* argument_t *argCount */
+			argNULL,      /* argument_t *argSubCount */
+			argNULL,      /* argument_t *argCInOut */
+			argNULL,      /* argument_t *argPoly */
+			argNULL,      /* argument_t *argDealloc */
+			argNULL,      /* argument_t *argSameCount */
+			argNULL,      /* argument_t *argParent */
+			1,            /* int argMultiplier */
+			0,            /* int argRequestPos */
+			0,            /* int argReplyPos */
+			FALSE,        /* boolean_t argByReferenceUser */
+			FALSE,			/* boolean_t argByReferenceServer */
+			FALSE        	/* boolean_t argTempOnStack */
+		};
+	register argument_t *new;
+
+	new = (argument_t *) malloc(sizeof *new);
+	if (new == argNULL)
+		fatal("argAlloc(): %s", strerror(errno));
+	*new = prototype;
+	return new;
+}
+
+routine_t *
+rtMakeRoutine(identifier_t name, argument_t *args)
+{
+	register routine_t *rt = rtAlloc();
+
+	rt->rtName = name;
+	rt->rtKind = rkRoutine;
+	rt->rtArgs = args;
+
+	return rt;
+}
+
+routine_t *
+rtMakeSimpleRoutine(identifier_t name, argument_t *args)
+{
+	register routine_t *rt = rtAlloc();
+
+	rt->rtName = name;
+	rt->rtKind = rkSimpleRoutine;
+	rt->rtArgs = args;
+
+	return rt;
+}
+
+const char *
+rtRoutineKindToStr(routine_kind_t rk)
+{
+    switch (rk)
+    {
+    case rkRoutine:
+		return "Routine";
+    case rkSimpleRoutine:
+		return "SimpleRoutine";
+    default:
+		fatal("rtRoutineKindToStr(%d): not a routine_kind_t", rk);
+		/*NOTREACHED*/
+		return strNULL;
+	}
+
+}
+
+static void
+rtPrintArg(register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	if (!akCheck(arg->argKind, akbUserArg|akbServerArg) ||
+		(akIdent(arg->argKind) == akeCount) ||
+		(akIdent(arg->argKind) == akeDealloc) ||
+		(akIdent(arg->argKind) == akeNdrCode) ||
+		(akIdent(arg->argKind) == akePoly))
+		return;
+
+	printf("\n\t");
+
+    switch (akIdent(arg->argKind))
+    {
+    case akeRequestPort:
+		printf("RequestPort");
+		break;
+    case akeReplyPort:
+		printf("ReplyPort");
+		break;
+    case akeWaitTime:
+		printf("WaitTime");
+		break;
+
+    case akeSendTime:
+		printf("SendTime");
+		break;
+
+    case akeMsgOption:
+		printf("MsgOption");
+		break;
+    case akeMsgSeqno:
+		printf("MsgSeqno\t");
+		break;
+    case akeSecToken:
+		printf("SecToken\t");
+		break;
+
+    case akeAuditToken:
+		printf("AuditToken\t");
+		break;
+
+    case akeContextToken:
+		printf("ContextToken\t");
+		break;
+
+    case akeImplicit:
+		printf("Implicit\t");
+		break;
+    default:
+		if (akCheck(arg->argKind, akbRequest)) {
+			if (akCheck(arg->argKind, akbSend))
+				printf("In");
+			else
+				printf("(In)");
+		}
+		if (akCheck(arg->argKind, akbReply)) {
+			if (akCheck(arg->argKind, akbReturn))
+				printf("Out");
+			else
+				printf("(Out)");
+		}
+		printf("\t");
+	}
+
+	printf("\t%s: %s", arg->argName, it->itName);
+
+	if (arg->argDeallocate == d_YES)
+		printf(", Dealloc");
+	else if (arg->argDeallocate == d_MAYBE)
+		printf(", Dealloc[]");
+
+	if (arg->argCountInOut)
+		printf(", CountInOut");
+
+	if (arg->argFlags & flSameCount)
+		printf(", SameCount");
+
+	if (arg->argFlags & flPhysicalCopy)
+		printf(", PhysicalCopy");
+
+	if (arg->argFlags & flRetCode)
+		printf(", PhysicalCopy");
+
+	if (arg->argFlags & flOverwrite)
+		printf(", Overwrite");
+
+	if (arg->argFlags & flAuto)
+		printf(", Auto");
+
+	if (arg->argFlags & flConst)
+		printf(", Const");
+}
+
+void
+rtPrintRoutine(register routine_t *rt)
+{
+	register argument_t *arg;
+
+    printf("%s (%d) %s(", rtRoutineKindToStr(rt->rtKind),
+		   rt->rtNumber, rt->rtName);
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+		rtPrintArg(arg);
+
+	printf(")\n");
+	printf("\n");
+}
+
+/*
+ * Determines appropriate value of msg-simple for the message.
+ * One version for both In & Out.
+ */
+
+static void
+rtCheckSimple(argument_t *args, u_int mask, boolean_t *simple)
+{
+	register argument_t *arg;
+	boolean_t MustBeComplex = FALSE;
+
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheck(arg->argKind, mask)) {
+			ipc_type_t *it = arg->argType;
+
+			if (IS_KERN_PROC_DATA(it))
+				MustBeComplex = TRUE;
+		}
+
+	*simple = !MustBeComplex;
+}
+
+static void
+rtCheckFit(routine_t *rt, u_int mask, boolean_t *fitp, boolean_t *uselimp, u_int *knownp)
+{
+	boolean_t uselim = FALSE;
+	argument_t *arg;
+    int size = sizeof(mach_msg_header_t);
+
+	if (!rt->rtSimpleRequest)
+		machine_alignment(size,sizeof(mach_msg_body_t));
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+		if (akCheck(arg->argKind, mask)) {
+			register ipc_type_t *it = arg->argType;
+
+			machine_alignment(size, it->itMinTypeSize);
+			if (it->itNative)
+				uselim = TRUE;
+			else if (IS_VARIABLE_SIZED_UNTYPED(it)) {
+				machine_alignment(size, it->itTypeSize);
+				size += it->itPadSize;
+			}
+		}
+	*knownp = size;
+	if (MaxMessSizeOnStack == -1) {
+		*fitp = TRUE;
+		*uselimp = FALSE;
+    } else if (size > MaxMessSizeOnStack) {
+		*fitp = FALSE;
+		*uselimp = FALSE;
+    } else if (!uselim) {
+		*fitp = TRUE;
+		*uselimp = FALSE;
+    } else if (UserTypeLimit == -1) {
+		*fitp = FALSE;
+		*uselimp = FALSE;
+    } else if (size + UserTypeLimit > MaxMessSizeOnStack) {
+		*fitp = FALSE;
+		*uselimp = TRUE;
+    } else {
+		*fitp = TRUE;
+		*uselimp = TRUE;
+	}
+}
+
+static void
+rtFindHowMany(routine_t *rt)
+{
+	register argument_t *arg;
+	int multiplier = 1;
+	boolean_t test;
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		register ipc_type_t *it = arg->argType;
+
+		if (IS_MULTIPLE_KPD(it)) {
+			if (!it->itVarArray)
+				multiplier = it->itKPD_Number;
+			test = !it->itVarArray && !it->itElement->itVarArray;
+			it = it->itElement;
+		} else
+			test = !it->itVarArray;
+
+		if (akCheck(arg->argKind, akbSendKPD)) {
+
+			if (it->itInLine)
+				rt->rtCountPortsIn += it->itNumber * multiplier;
+			else if (it->itPortType) {
+				if (test)
+					rt->rtCountOolPortsIn += it->itNumber * multiplier;
+            } else {
+				if (test)
+					rt->rtCountOolIn += (it->itNumber * it->itSize + 7)/8 * multiplier;
+			}
+		}
+		if (akCheckAll(arg->argKind, akbReturnKPD)) {
+			if (it->itInLine)
+				rt->rtCountPortsOut += it->itNumber * multiplier;
+			else if (it->itPortType) {
+				if (test)
+					rt->rtCountOolPortsOut += it->itNumber * multiplier;
+            } else {
+				if (test)
+					rt->rtCountOolOut += ((it->itNumber * it->itSize + 7)/8) * multiplier;
+			}
+		}
+	}
+}
+
+boolean_t
+rtCheckMask(argument_t *args, u_int mask)
+{
+	register argument_t *arg;
+
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheckAll(arg->argKind, mask))
+			return TRUE;
+	return FALSE;
+}
+
+boolean_t
+rtCheckMaskFunction(argument_t *args, u_int mask, boolean_t (*func)(/* argument_t *arg */))
+{
+	register argument_t *arg;
+
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheckAll(arg->argKind, mask))
+			if ((*func)(arg))
+				return TRUE;
+	return FALSE;
+}
+
+
+static int
+rtCountKPDs(argument_t *args, u_int mask)
+{
+	register argument_t *arg;
+	int count = 0;
+
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheckAll(arg->argKind, mask))
+			count += arg->argType->itKPD_Number;
+	return count;
+}
+
+static int
+rtCountFlags(args, flag)
+    argument_t *args;
+    u_int flag;
+{
+	register argument_t *arg;
+	int count = 0;
+
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (arg->argFlags & flag)
+			count++;
+	return count;
+}
+
+int
+rtCountArgDescriptors(argument_t *args, int *argcount)
+{
+	register argument_t *arg;
+	int count = 0;
+
+	if (argcount)
+		*argcount = 0;
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheck(arg->argKind, akbServerArg)) {
+			if (RPCFixedArray(arg) ||
+				RPCPort(arg) ||
+				RPCVariableArray(arg) ||
+				RPCPortArray(arg)) {
+				count++;
+				if (argcount)
+					(*argcount)++;
+			}
+			else {
+				if (argcount) {
+					if (arg->argType->itStruct && arg->argType->itNumber &&
+						(arg->argType->itSize >= 32))
+						*argcount += arg->argType->itNumber * (arg->argType->itSize / 32);
+					else
+						(*argcount)++;
+				}
+			}
+		}
+	return count;
+}
+
+static int
+rtCountMask(argument_t *args, u_int mask)
+{
+	register argument_t *arg;
+	int count = 0;
+
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheckAll(arg->argKind, mask))
+			count++;
+	return count;
+}
+
+/* arg->argType may be NULL in this function */
+
+static void
+rtDefaultArgKind(routine_t *rt, argument_t *arg)
+{
+    if ((arg->argKind == akNone) && (rt->rtRequestPort == argNULL))
+		arg->argKind = akRequestPort;
+
+	if (arg->argKind == akNone)
+		arg->argKind = akIn;
+}
+
+/*
+ * Initializes arg->argDeallocate,
+ * arg->argCountInOut from arg->argFlags
+ * and perform consistency check over the
+ * flags.
+ */
+
+static ipc_flags_t
+rtProcessDeallocFlag(register ipc_type_t *it, register ipc_flags_t flags, register arg_kind_t kind, dealloc_t *what, string_t name)
+{
+
+	/* only one of flDealloc, flNotDealloc, flMaybeDealloc */
+
+	if (flags & flMaybeDealloc) {
+		if (flags & (flDealloc|flNotDealloc)) {
+			warn("%s: Dealloc and NotDealloc ignored with Dealloc[]", name);
+			flags &= ~(flDealloc|flNotDealloc);
+		}
+	}
+
+	if ((flags&(flDealloc|flNotDealloc)) == (flDealloc|flNotDealloc)) {
+		warn("%s: Dealloc and NotDealloc cancel out", name);
+		flags &= ~(flDealloc|flNotDealloc);
+	}
+
+	if (((IsKernelServer && akCheck(kind, akbReturn)) ||
+		 (IsKernelUser && akCheck(kind, akbSend))) &&
+		(flags & flDealloc)) {
+		/*
+		 *  For a KernelServer interface and an Out argument,
+		 *  or a KernelUser interface and an In argument,
+		 *  we avoid a possible spurious warning about the deallocate bit.
+		 *  For compatibility with Mach 2.5, the deallocate bit
+		 *  may need to be enabled on some inline arguments.
+		 */
+
+		*what= d_YES;
+    } else if (flags & (flMaybeDealloc|flDealloc)) {
+		/* only give semantic warnings if the user specified something */
+		if (it->itInLine && !it->itPortType) {
+			warn("%s: Dealloc is ignored: it is meaningless  for that type of argument", name);
+			flags &= ~(flMaybeDealloc|flDealloc);
+		} else
+			*what = (flags & flMaybeDealloc) ? d_MAYBE : d_YES;
+	}
+	return flags;
+}
+
+static void
+rtProcessSameCountFlag(register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	register ipc_flags_t flags = arg->argFlags;
+	string_t name = arg->argVarName;
+	static argument_t *old_arg;
+
+	if (flags & flSameCount)  {
+		if (!it->itVarArray) {
+			warn("%s: SameCount is ignored - the argument is not variable", name);
+			flags &= ~flSameCount;
+		}
+		if (old_arg) {
+			if (old_arg->argParent)
+				old_arg = old_arg->argParent;
+			if (old_arg->argSameCount)
+				old_arg = old_arg->argSameCount;
+
+			if (!old_arg->argType->itVarArray) {
+				warn("%s: SameCount is ignored - adjacent argument is not variable", name);
+				flags &= ~flSameCount;
+			}
+
+#define SAMECOUNT_MASK akeBITS|akbSend|akbReturn|akbRequest|akbReply|akbUserArg|akbServerArg
+			if (akCheck(old_arg->argKind, SAMECOUNT_MASK) !=
+				akCheck(arg->argKind, SAMECOUNT_MASK) ||
+				old_arg->argCountInOut != arg->argCountInOut) {
+				warn("%s: SameCount is ignored - inconsistencies with the adjacent argument\n", name);
+				flags &= ~flSameCount;
+			}
+			arg->argSameCount = old_arg;
+		}
+		arg->argFlags = flags;
+	}
+	old_arg = arg;
+}
+
+static ipc_flags_t
+rtProcessCountInOutFlag(ipc_type_t *it, ipc_flags_t flags, arg_kind_t kind, boolean_t *what, string_t name)
+{
+	if (flags & flCountInOut) {
+		if (!akCheck(kind, akbReply)) {
+			warn("%s: CountInOut is ignored: argument must be Out\n", name);
+			flags &= ~flCountInOut;
+		} else if (!it->itVarArray || !it->itInLine) {
+			warn("%s: CountInOut is ignored: argument isn't variable or in-line\n", name);
+			flags &= ~flCountInOut;
+		} else
+			*what = TRUE;
+	}
+	return flags;
+}
+
+static ipc_flags_t
+rtProcessPhysicalCopyFlag(register ipc_type_t *it, register ipc_flags_t flags, register arg_kind_t kind __unused, string_t name)
+{
+	if (flags & flPhysicalCopy) {
+		if (it->itInLine) {
+			warn("%s: PhysicalCopy is ignored, argument copied inline anyway", name);
+			flags &= ~flPhysicalCopy;
+		}
+		if (it->itPortType) {
+			warn("%s: PhysicalCopy is ignored, it does not apply to ports and array of ports", name);
+			flags &= ~flPhysicalCopy;
+		}
+	}
+	return flags;
+}
+
+static void
+rtProcessRetCodeFlag(register argument_t *thisarg)
+{
+	register ipc_type_t *it = thisarg->argType;
+	register ipc_flags_t flags = thisarg->argFlags;
+	string_t name = thisarg->argVarName;
+	routine_t *thisrout = thisarg->argRoutine;
+
+	if (flags & flRetCode) {
+		if (!it->itInLine || !it->itStruct ||
+			it->itSize != 32 || it->itNumber != 1) {
+			warn("%s: RetCode is ignored - the type doesn't match a MIG RetCode", name);
+			flags &= ~flRetCode;
+		} else if (thisrout->rtKind != rkSimpleRoutine) {
+			fatal("%s: RetCode is allowed only for SimpleRoutines", name);
+		} else if (thisrout->rtRetCArg != argNULL) {
+			warn("%s: RetCode is ignored - only one argument can be flagged as RetCode", name);
+			flags &= ~flRetCode;
+		} else {
+			thisrout->rtRetCArg = thisarg;
+		}
+		thisarg->argFlags = flags;
+	}
+}
+
+static ipc_flags_t
+rtProcessOverwriteFlag(register ipc_type_t *it, register ipc_flags_t flags, register arg_kind_t kind, string_t name)
+{
+	if (flags & flOverwrite)
+		if (it->itInLine || it->itMigInLine ||
+			/* among In, Out, InOut, we want only the Out! */
+			!akCheck(kind, akbReturn) || akCheck(kind, akbSend)) {
+			warn("%s: Overwrite is ignored - it must be Out AND Ool!", name);
+			flags &= ~flOverwrite;
+		}
+	return flags;
+}
+
+static void
+rtDetectKPDArg(argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *string;
+
+	if  (IS_KERN_PROC_DATA(it)) {
+		if (akCheck(arg->argKind, akbSendBody)) {
+			arg->argKind = akRemFeature(arg->argKind, akbSendBody);
+			arg->argKind = akAddFeature(arg->argKind, akbSendKPD);
+		}
+		if (akCheck(arg->argKind, akbReturnBody)) {
+			arg->argKind = akRemFeature(arg->argKind, akbReturnBody);
+			arg->argKind = akAddFeature(arg->argKind, akbReturnKPD);
+		}
+		if (it->itInLine) {
+			string = "mach_msg_port_descriptor_t";
+			arg->argKPD_Type = MACH_MSG_PORT_DESCRIPTOR;
+        } else if (it->itPortType) {
+			string = "mach_msg_ool_ports_descriptor_t";
+			arg->argKPD_Type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
+        } else {
+			string = "mach_msg_ool_descriptor_t";
+			arg->argKPD_Type = MACH_MSG_OOL_DESCRIPTOR;
+		}
+		it->itKPDType = string;
+	}
+}
+
+static void
+rtAugmentArgKind(argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	/* akbVariable means variable-sized inline */
+
+	if (IS_VARIABLE_SIZED_UNTYPED(it)) {
+		if (akCheckAll(arg->argKind, akbRequest|akbReply))
+			error("%s: Inline variable-sized arguments can't be InOut",
+				  arg->argName);
+		arg->argKind = akAddFeature(arg->argKind, akbVariable);
+	}
+	if (IS_OPTIONAL_NATIVE(it))
+		arg->argKind = akAddFeature(arg->argKind, akbVariable);
+
+	/*
+	 * Need to use a local variable in the following cases:
+	 *  1) There is a translate-out function & the argument is being
+	 *     returned.  We need to translate it before it hits the message.
+	 *  2) There is a translate-in function & the argument is
+	 *     sent and returned.  We need a local variable for its address.
+	 *  3) There is a destructor function, which will be used
+	 *     (SendRcv and not ReturnSnd), and there is a translate-in
+	 *     function whose value must be saved for the destructor.
+	 *  4) This is Complex KPD (array of KPD), and as such it has to
+	 *     be copied to a local array in input and output
+	 *  5) Both poly and dealloc generate warnings compile time, because
+	 *     we attempt to take address of bit-field structure member
+	 */
+
+    if (((it->itOutTrans != strNULL) &&
+		 akCheck(arg->argKind, akbReturnSnd)) ||
+		((it->itInTrans != strNULL) &&
+		 akCheckAll(arg->argKind, akbSendRcv|akbReturnSnd)) ||
+		((it->itDestructor != strNULL) &&
+		 akCheck(arg->argKind, akbSendRcv) &&
+		 !akCheck(arg->argKind, akbReturnSnd) &&
+		 (it->itInTrans != strNULL)) ||
+		(IS_MULTIPLE_KPD(it)) ||
+		((akIdent(arg->argKind) == akePoly) &&
+		 akCheck(arg->argKind, akbReturnSnd))  ||
+		((akIdent(arg->argKind) == akeDealloc) &&
+		 akCheck(arg->argKind, akbReturnSnd))
+		)
+    {
+		arg->argKind = akRemFeature(arg->argKind, akbReplyCopy);
+		arg->argKind = akAddFeature(arg->argKind, akbVarNeeded);
+	}
+}
+
+/*
+ * The Suffix allows to handle KPDs as normal data.
+ * it is used in InArgMsgField.
+ */
+static void
+rtSuffixExtArg(register argument_t *args)
+{
+	register argument_t *arg;
+    register const char *subindex;
+	char string[MAX_STR_LEN];
+
+	for (arg = args; arg != argNULL; arg = arg->argNext)  {
+		if (akCheck(arg->argKind, akbSendKPD | akbReturnKPD)) {
+			if (IS_MULTIPLE_KPD(arg->argType))
+				subindex = "[0]";
+			else
+				subindex = "";
+			switch (arg->argKPD_Type) {
+
+			case MACH_MSG_PORT_DESCRIPTOR:
+				(void)sprintf(string, "%s.name", subindex);
+				break;
+
+			case MACH_MSG_OOL_DESCRIPTOR:
+			case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+				(void)sprintf(string, "%s.address", subindex);
+				break;
+
+			default:
+				error("Type of kernel processed data unknown\n");
+			}
+			arg->argSuffix = strconcat(arg->argMsgField, string);
+			/* see above the list of VarNeeded cases */
+			/*
+			 * argCount has been removed from the VarNeeded list,
+			 * because VarSize arrays have their Count in the untyped
+			 * section of the message, and because it is not possible
+			 * to move anything in-line/out-of-line
+			 */
+		} else if (akIdent(arg->argKind) == akePoly &&
+				   akCheck(arg->argParent->argKind, akbSendKPD | akbReturnKPD)) {
+			register argument_t *par_arg = arg->argParent;
+
+			if (IS_MULTIPLE_KPD(par_arg->argType))
+				subindex = "[0]";
+			else
+				subindex = "";
+			switch (par_arg->argKPD_Type) {
+
+			case MACH_MSG_PORT_DESCRIPTOR:
+			case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+				(void)sprintf(string, "%s.disposition", subindex);
+				arg->argSuffix = strconcat(par_arg->argMsgField, string);
+				break;
+			default:
+				error("Type of kernel processed data inconsistent\n");
+			}
+		} else if (akIdent(arg->argKind) == akeDealloc &&
+				   akCheck(arg->argParent->argKind, akbSendKPD | akbReturnKPD)) {
+			register argument_t *par_arg = arg->argParent;
+
+			if (IS_MULTIPLE_KPD(par_arg->argType))
+				subindex = "[0]";
+			else
+				subindex = "";
+			switch (par_arg->argKPD_Type) {
+
+			case MACH_MSG_OOL_DESCRIPTOR:
+			case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+				(void)sprintf(string, "%s.deallocate", subindex);
+				arg->argSuffix = strconcat(par_arg->argMsgField, string);
+				break;
+
+			default:
+				error("Type of kernel processed data inconsistent\n");
+			}
+		}
+	}
+}
+
+/* arg->argType may be NULL in this function */
+
+static void
+rtCheckRoutineArg(routine_t *rt, argument_t *arg)
+{
+    switch (akIdent(arg->argKind))
+    {
+    case akeRequestPort:
+		if (rt->rtRequestPort != argNULL)
+			warn("multiple RequestPort args in %s; %s won't be used",
+				 rt->rtName, rt->rtRequestPort->argName);
+		rt->rtRequestPort = arg;
+		break;
+
+    case akeReplyPort:
+		if (rt->rtReplyPort != argNULL)
+			warn("multiple ReplyPort args in %s; %s won't be used",
+				 rt->rtName, rt->rtReplyPort->argName);
+		rt->rtReplyPort = arg;
+		break;
+
+    case akeWaitTime:
+		if (rt->rtWaitTime != argNULL)
+			warn("multiple WaitTime/SendTime type args in %s; %s won't be used", rt->rtName, rt->rtWaitTime->argName);
+		rt->rtWaitTime = arg;
+		break;
+
+    case akeSendTime:
+		if (rt->rtWaitTime != argNULL) {
+			if (akIdent(rt->rtWaitTime->argKind) == akeWaitTime) {
+				warn("SendTime type argument after a WaitTime in %s; SendTime %s won't be used", rt->rtName, arg->argName);
+				break;
+			} else 
+				warn("multiple SendTime type args in %s; %s won't be used", rt->rtName, rt->rtWaitTime->argName);
+		}
+		rt->rtWaitTime = arg;
+		break;
+
+    case akeMsgOption:
+		if (rt->rtMsgOption != argNULL)
+			warn("multiple MsgOption args in %s; %s won't be used",
+				 rt->rtName, rt->rtMsgOption->argName);
+		rt->rtMsgOption = arg;
+		break;
+
+    default:
+		break;
+	}
+}
+
+/* arg->argType may be NULL in this function */
+
+static void
+rtSetArgDefaults(routine_t *rt, register argument_t *arg)
+{
+	arg->argRoutine = rt;
+	if (arg->argVarName == strNULL)
+		arg->argVarName = arg->argName;
+	if (arg->argMsgField == strNULL)
+		switch(akIdent(arg->argKind)) {
+		case akeRequestPort:
+			arg->argMsgField = "Head.msgh_request_port";
+			break;
+		case akeReplyPort:
+			arg->argMsgField = "Head.msgh_reply_port";
+			break;
+		case akeNdrCode:
+			arg->argMsgField = "NDR";
+			break;
+		case akeSecToken:
+			arg->argMsgField = "msgh_sender";
+			break;
+
+		case akeAuditToken:
+			arg->argMsgField = "msgh_audit";
+			break;
+
+		case akeContextToken:
+			arg->argMsgField = "msgh_context";
+			break;
+
+		case akeMsgSeqno:
+			arg->argMsgField = "msgh_seqno";
+			break;
+		case akeImplicit:
+			/* the field is set directly by Yacc */
+			break;
+		default:
+			arg->argMsgField = arg->argName;
+			break;
+		}
+
+	if (arg->argTTName == strNULL)
+		arg->argTTName = strconcat(arg->argName, "Template");
+	if (arg->argPadName == strNULL)
+		arg->argPadName = strconcat(arg->argName, "Pad");
+
+	/*
+	 *  The poly args for the request and reply ports have special defaults,
+	 *  because their msg-type-name values aren't stored in normal fields.
+	 */
+
+	if ((rt->rtRequestPort != argNULL) &&
+		(rt->rtRequestPort->argPoly == arg) &&
+		(arg->argType != itNULL)) {
+		arg->argMsgField = "Head.msgh_bits";
+		arg->argType->itInTrans = "MACH_MSGH_BITS_REQUEST";
+	}
+
+	if ((rt->rtReplyPort != argNULL) &&
+		(rt->rtReplyPort->argPoly == arg) &&
+		(arg->argType != itNULL)) {
+		arg->argMsgField = "Head.msgh_bits";
+		arg->argType->itInTrans = "MACH_MSGH_BITS_REPLY";
+	}
+}
+
+static void
+rtAddCountArg(register argument_t *arg)
+{
+	register argument_t *count, *master;
+	register ipc_type_t *it = arg->argType;
+
+	count = argAlloc();
+
+	if (IS_MULTIPLE_KPD(it) && it->itElement->itVarArray) {
+		count->argName = strconcat(arg->argName, "Subs");
+		count->argType = itMakeSubCountType(it->itKPD_Number, it->itVarArray, arg->argVarName);
+		count->argKind = akeSubCount;
+		arg->argSubCount = count;
+    } else {
+		count->argName = strconcat(arg->argName, "Cnt");
+		count->argType = itMakeCountType();
+		count->argKind = akeCount;
+		arg->argCount = count;
+		if (arg->argParent != argNULL)  {
+			/* this is the case where we are at the second level of recursion:
+			   we want the Parent to access it through argCount */
+			arg->argParent->argCount = count;
+		}
+	}
+	master = (arg->argParent != argNULL) ? arg->argParent : arg;
+	if (IS_MULTIPLE_KPD(master->argType))
+		count->argMultiplier = 1;
+	else
+		count->argMultiplier = it->itElement->itNumber;
+	count->argParent = arg;
+	count->argNext = arg->argNext;
+	arg->argNext = count;
+
+	if (arg->argType->itString) {
+	    /* C String gets no Count argument on either side. */
+		count->argKind = akAddFeature(count->argKind, akCheck(arg->argKind, akbSend) ? akbSendRcv : akbReturnRcv);
+		count->argVarName = (char *)0;
+    } else {
+		/*
+		 * Count arguments have to be present on the message body (NDR encoded)
+		 * akbVariable has to be turned down, has it foul the algorithm
+		 * for detecting the in-line variable sized arrays
+		 */
+		count->argKind |= akAddFeature(akbUserArg|akbServerArg, (arg->argKind) & ~akeBITS);
+		count->argKind = akRemFeature(count->argKind, akbVariable|akbVarNeeded);
+		if (IS_VARIABLE_SIZED_UNTYPED(arg->argType))
+			/*
+			 * Count arguments for the above types are explicitly declared
+			 * BEFORE the variable (with those bits, they would come afterwards)
+			 */
+			count->argKind = akRemFeature(count->argKind, akbRequest|akbReply);
+	}
+}
+
+static void
+rtAddCountInOutArg(register argument_t *arg)
+{
+	register argument_t *count;
+
+	/*
+	 *  The user sees a single count variable.  However, to get the
+	 *  count passed from user to server for variable-sized inline OUT
+	 *  arrays, we need two count arguments internally.  This is
+	 *  because the count value lives in different message fields (and
+	 *  is scaled differently) in the request and reply messages.
+	 *
+	 *  The two variables have the same name to simplify code generation.
+	 *
+	 *  This variable has a null argParent field because it has akbRequest.
+	 *  For example, see rtCheckVariable.
+	 */
+
+	count = argAlloc();
+	count->argName = strconcat(arg->argName, "Cnt");
+	count->argType = itMakeCountType();
+	count->argParent = argNULL;
+	count->argNext = arg->argNext;
+	arg->argNext = count;
+	(count->argCInOut = arg->argCount)->argCInOut = count;
+	count->argKind = akCountInOut;
+}
+
+static void
+rtAddPolyArg(register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	register argument_t *poly;
+	arg_kind_t akbsend, akbreturn;
+
+	poly = argAlloc();
+	poly->argName = strconcat(arg->argName, "Poly");
+	poly->argType = itMakePolyType();
+	poly->argParent = arg;
+	poly->argNext = arg->argNext;
+	arg->argNext = poly;
+	arg->argPoly = poly;
+
+	/*
+	 * akbsend is bits added if the arg is In;
+	 * akbreturn is bits added if the arg is Out.
+	 * The mysterious business with KernelServer subsystems:
+	 * when packing Out arguments, they use OutNames instead
+	 * of InNames, and the OutName determines if they are poly-in
+	 * as well as poly-out.
+	 */
+
+	akbsend = akbSend;
+	akbreturn = akbReturn;
+
+    if (it->itInName == MACH_MSG_TYPE_POLYMORPHIC)
+    {
+		akbsend |= akbUserArg|akbSendSnd;
+		if (!IsKernelServer)
+			akbreturn |= akbServerArg|akbReturnSnd;
+	}
+    if (it->itOutName == MACH_MSG_TYPE_POLYMORPHIC)
+    {
+		akbsend |= akbServerArg|akbSendRcv;
+		akbreturn |= akbUserArg|akbReturnRcv;
+		if (IsKernelServer)
+			akbreturn |= akbServerArg|akbReturnSnd;
+	}
+
+	poly->argKind = akPoly;
+	if (akCheck(arg->argKind, akbSend))
+		poly->argKind = akAddFeature(poly->argKind,
+									 akCheck(arg->argKind, akbsend));
+	if (akCheck(arg->argKind, akbReturn))
+		poly->argKind = akAddFeature(poly->argKind,
+									 akCheck(arg->argKind, akbreturn));
+}
+
+static void
+rtAddDeallocArg(register argument_t *arg)
+{
+	register argument_t *dealloc;
+
+	dealloc = argAlloc();
+	dealloc->argName = strconcat(arg->argName, "Dealloc");
+	dealloc->argType = itMakeDeallocType();
+	dealloc->argParent = arg;
+	dealloc->argNext = arg->argNext;
+	arg->argNext = dealloc;
+	arg->argDealloc = dealloc;
+
+	/*
+	 * Dealloc flag can only be associated to KPDs.
+	 */
+
+	dealloc->argKind = akeDealloc;
+	if (akCheck(arg->argKind, akbSend))
+		dealloc->argKind = akAddFeature(dealloc->argKind,
+										akCheck(arg->argKind, akbUserArg|akbSend|akbSendSnd));
+	if (akCheck(arg->argKind, akbReturn)) {
+		dealloc->argKind = akAddFeature(dealloc->argKind,
+										akCheck(arg->argKind, akbServerArg|akbReturn|akbReturnSnd));
+
+		dealloc->argByReferenceServer = TRUE;
+	}
+}
+
+static void
+rtCheckRoutineArgs(routine_t *rt)
+{
+	register argument_t *arg;
+
+    for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+    {
+		register ipc_type_t *it = arg->argType;
+
+		rtDefaultArgKind(rt, arg);
+		rtCheckRoutineArg(rt, arg);
+
+		/* need to set argTTName before adding implicit args */
+		rtSetArgDefaults(rt, arg);
+
+		/* the arg may not have a type (if there was some error in parsing it),
+		   in which case we don't want to do these steps. */
+
+		if (it != itNULL) {
+			arg->argFlags = rtProcessDeallocFlag(it, arg->argFlags, arg->argKind, &arg->argDeallocate, arg->argVarName);
+			arg->argFlags = rtProcessCountInOutFlag(it, arg->argFlags, arg->argKind, &arg->argCountInOut, arg->argVarName);
+			rtProcessSameCountFlag(arg);
+			arg->argFlags = rtProcessPhysicalCopyFlag(it, arg->argFlags, arg->argKind, arg->argVarName);
+			rtProcessRetCodeFlag(arg);
+			arg->argFlags = rtProcessOverwriteFlag(it, arg->argFlags, arg->argKind, arg->argVarName);
+			rtAugmentArgKind(arg);
+
+			/* args added here will get processed in later iterations */
+			/* order of args is 'arg poly countinout count dealloc' */
+
+			if (arg->argDeallocate == d_MAYBE)
+				rtAddDeallocArg(arg);
+			if (it->itVarArray || (IS_MULTIPLE_KPD(it) && it->itElement->itVarArray))
+				rtAddCountArg(arg);
+			if (arg->argCountInOut)
+				rtAddCountInOutArg(arg);
+			if ((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) ||
+				(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC))
+				rtAddPolyArg(arg);
+			/*
+			 * Detects whether the arg has to become part of the
+			 * Kernel Processed Data section; if yes, define the proper
+			 * itUserKPDType, itServerKPDType
+			 */
+			rtDetectKPDArg(arg);
+		}
+	}
+}
+
+static boolean_t
+rtCheckTrailerType(register argument_t *arg)
+{
+    if (akIdent(arg->argKind) == akeSecToken ||
+		akIdent(arg->argKind) == akeAuditToken ||
+		akIdent(arg->argKind) == akeContextToken)
+		itCheckTokenType(arg->argVarName, arg->argType);
+
+	if (akIdent(arg->argKind) == akeMsgSeqno)
+		itCheckIntType(arg->argVarName, arg->argType);
+	/*
+	 * if the built-in are not used, we cannot match
+	 * the type/size of the desciption provided by the user
+	 * with the one defined in message.h.
+	 */
+	return (TRUE);
+}
+
+static void
+rtCheckArgTypes(routine_t *rt)
+{
+	if (rt->rtRequestPort == argNULL)
+		error("%s %s doesn't have a server port argument",
+			  rtRoutineKindToStr(rt->rtKind), rt->rtName);
+
+	if ((rt->rtRequestPort != argNULL) &&
+		(rt->rtRequestPort->argType != itNULL))
+		itCheckRequestPortType(rt->rtRequestPort->argName,
+							   rt->rtRequestPort->argType);
+
+	if ((rt->rtReplyPort != argNULL) &&
+		(rt->rtReplyPort->argType != itNULL))
+		itCheckReplyPortType(rt->rtReplyPort->argName,
+							 rt->rtReplyPort->argType);
+
+	if ((rt->rtWaitTime != argNULL) &&
+		(rt->rtWaitTime->argType != itNULL))
+		itCheckIntType(rt->rtWaitTime->argName,
+					   rt->rtWaitTime->argType);
+
+	if ((rt->rtMsgOption != argNULL) &&
+		(rt->rtMsgOption->argType != itNULL))
+		itCheckIntType(rt->rtMsgOption->argName,
+					   rt->rtMsgOption->argType);
+
+	if ((IsKernelServer && rt->rtServerImpl) ||
+		(IsKernelUser   && rt->rtUserImpl))
+		fatal("Implicit data is not supported in the KernelUser and KernelServer modes");
+	/* rtCheckTrailerType will hit a fatal() if something goes wrong */
+	if (rt->rtServerImpl)
+		rtCheckMaskFunction(rt->rtArgs, akbServerImplicit, rtCheckTrailerType);
+	if (rt->rtUserImpl)
+		rtCheckMaskFunction(rt->rtArgs, akbUserImplicit, rtCheckTrailerType);
+}
+
+/*
+ * Check for arguments which are missing seemingly needed functions.
+ * We make this check here instead of in itCheckDecl, because here
+ * we can take into account what kind of argument the type is
+ * being used with.
+ *
+ * These are warnings, not hard errors, because mig will generate
+ * reasonable code in any case.  The generated code will work fine
+ * if the ServerType and TransType are really the same, even though
+ * they have different names.
+ */
+
+static void
+rtCheckArgTrans(routine_t *rt)
+{
+	argument_t *arg;
+
+	/* the arg may not have a type (if there was some error in parsing it) */
+
+    for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		ipc_type_t *it = arg->argType;
+
+		if ((it != itNULL) && !streql(it->itServerType, it->itTransType)) {
+			if (akCheck(arg->argKind, akbSendRcv) && (it->itInTrans == strNULL))
+				warn("%s: argument has no in-translation function", arg->argName);
+
+			if (akCheck(arg->argKind, akbReturnSnd) && (it->itOutTrans == strNULL))
+				warn("%s: argument has no out-translation function", arg->argName);
+		}
+	}
+}
+
+/*
+ * Adds an implicit return-code argument.  It exists in the reply message,
+ * where it is the first piece of data (After the NDR format label)..
+ */
+
+static void
+rtAddRetCode(routine_t *rt)
+{
+	register argument_t *arg = argAlloc();
+
+	arg->argName = "RetCode";
+	arg->argType = itRetCodeType;
+	arg->argKind = akRetCode;
+	rt->rtRetCode = arg;
+
+	arg->argNext = rt->rtArgs;
+	rt->rtArgs = arg;
+}
+
+/*
+ * Process the Return Code.
+ * The MIG protocol says that RetCode != 0 are only sent through
+ * mig_reply_error_t structures. Therefore, there is no need
+ * for reserving a RetCode in a complex Reply message.
+ */
+static void
+rtProcessRetCode(routine_t *rt)
+{
+
+	if (!rt->rtOneWay && !rt->rtSimpleReply) {
+		register argument_t *arg = rt->rtRetCode;
+
+		arg->argKind = akRemFeature(arg->argKind, akbReply);
+		/* we want the RetCode to be a local variable instead */
+		arg->argKind = akAddFeature(arg->argKind, akbVarNeeded);
+	}
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest) {
+		register argument_t *arg = rt->rtRetCArg;
+
+		arg->argKind = akeRetCode|akbUserArg|akbServerArg|akbSendRcv;
+	}
+}
+
+/*
+ * Adds an implicit NDR argument.  It exists in the reply message,
+ * where it is the first piece of data.
+ */
+
+static void
+rtAddNdrCode(routine_t *rt)
+{
+	register argument_t *arg = argAlloc();
+
+	arg->argName = "NDR_record";
+	arg->argType = itNdrCodeType;
+	arg->argKind = akeNdrCode;
+	rt->rtNdrCode = arg;
+
+	/* add at beginning, so ndr-code is first in the reply message  */
+	arg->argNext = rt->rtArgs;
+	rt->rtArgs = arg;
+}
+
+/*
+ * Process the NDR Code.
+ * We stick a NDR format label iff there is untyped data
+ */
+static void
+rtProcessNdrCode(routine_t *rt)
+{
+	register argument_t *ndr = rt->rtNdrCode;
+	argument_t *arg;
+	boolean_t found;
+
+	/* akbSendSnd|akbSendBody initialize the NDR format label */
+#define ndr_send akbRequest|akbSend|akbSendSnd|akbSendBody
+	/* akbReplyInit initializes the NDR format label */
+#define ndr_rcv  akbReply|akbReplyInit|akbReturn|akbReturnBody
+
+	ndr->argKind = akAddFeature(ndr->argKind, ndr_send|ndr_rcv);
+
+	for (found = FALSE, arg = ndr->argNext; arg != argNULL; arg = arg->argNext)
+		if (akCheck(arg->argKind, akbSendRcv|akbSendBody) &&
+			!akCheck(arg->argKind, akbServerImplicit) && !arg->argType->itPortType &&
+			(!arg->argParent || akIdent(arg->argKind) == akeCount ||
+			 akIdent(arg->argKind) == akeCountInOut)) {
+			arg->argKind = akAddFeature(arg->argKind, akbSendNdr);
+			found = TRUE;
+		}
+	if (!found)
+		ndr->argKind = akRemFeature(ndr->argKind, ndr_send);
+
+	found = FALSE;
+	if (!rt->rtOneWay)
+		for (arg = ndr->argNext; arg != argNULL; arg = arg->argNext)
+			if ((arg == rt->rtRetCode && akCheck(arg->argKind, akbReply)) ||
+				(arg != rt->rtRetCode &&
+				 akCheck(arg->argKind, akbReturnRcv|akbReturnBody) &&
+				 !akCheck(arg->argKind, akbUserImplicit) && !arg->argType->itPortType &&
+				 (!arg->argParent || akIdent(arg->argKind) == akeCount ||
+				  akIdent(arg->argKind) == akeCountInOut))) {
+				arg->argKind = akAddFeature(arg->argKind, akbReturnNdr);
+				found = TRUE;
+			}
+	if (!found && !akCheck(rt->rtRetCode->argKind, akbReply))
+		ndr->argKind = akRemFeature(ndr->argKind, ndr_rcv);
+}
+
+/*
+ *  Adds a dummy WaitTime argument to the function.
+ *  This argument doesn't show up in any C argument lists;
+ *  it implements the global WaitTime statement.
+ */
+
+static void
+rtAddWaitTime(routine_t *rt, identifier_t name, arg_kind_t kind)
+{
+	register argument_t *arg = argAlloc();
+	argument_t **loc;
+
+	arg->argName = "dummy WaitTime arg";
+	arg->argVarName = name;
+	arg->argType = itWaitTimeType;
+	arg->argKind = kind;
+	rt->rtWaitTime = arg;
+
+	/* add wait-time after msg-option, if possible */
+
+	if (rt->rtMsgOption != argNULL)
+		loc = &rt->rtMsgOption->argNext;
+	else
+		loc = &rt->rtArgs;
+
+	arg->argNext = *loc;
+	*loc = arg;
+
+	rtSetArgDefaults(rt, arg);
+}
+
+/*
+ *  Adds a dummy MsgOption argument to the function.
+ *  This argument doesn't show up in any C argument lists;
+ *  it implements the global MsgOption statement.
+ */
+
+static void
+rtAddMsgOption(routine_t *rt, identifier_t name)
+{
+	register argument_t *arg = argAlloc();
+	argument_t **loc;
+
+	arg->argName = "dummy MsgOption arg";
+	arg->argVarName = name;
+	arg->argType = itMsgOptionType;
+	arg->argKind = akeMsgOption;
+	rt->rtMsgOption = arg;
+
+	/* add msg-option after msg-seqno */
+
+	loc = &rt->rtArgs;
+
+	arg->argNext = *loc;
+	*loc = arg;
+
+	rtSetArgDefaults(rt, arg);
+}
+
+/*
+ * Process the MsgOption Code.
+ * We must add the information to post a receive with the right
+ * Trailer options.
+ */
+static void
+rtProcessMsgOption(routine_t *rt)
+{
+	register argument_t *msgop = rt->rtMsgOption;
+	register argument_t *arg;
+	boolean_t sectoken = FALSE;
+	boolean_t audittoken = FALSE;
+	boolean_t contexttoken = FALSE;
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+		if (akCheckAll(arg->argKind, akbReturn|akbUserImplicit)) {
+			if (akIdent(arg->argKind) == akeSecToken)
+				sectoken = TRUE;
+			else if (akIdent(arg->argKind) == akeAuditToken)
+				audittoken = TRUE;
+			else if (akIdent(arg->argKind) == akeContextToken)
+				contexttoken = TRUE;
+		}
+
+	if (contexttoken == TRUE)
+		msgop->argVarName = strconcat(msgop->argVarName, "|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_CTX)");
+	else if (audittoken == TRUE)
+		msgop->argVarName = strconcat(msgop->argVarName, "|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT)");
+	else if (sectoken == TRUE)
+		msgop->argVarName = strconcat(msgop->argVarName, "|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER)");
+	/* other implicit data received by the user will be handled here */
+}
+
+
+/*
+ *  Adds a dummy reply port argument to the function.
+ */
+
+static void
+rtAddDummyReplyPort(routine_t *rt, ipc_type_t *type)
+{
+	register argument_t *arg = argAlloc();
+	argument_t **loc;
+
+	arg->argName = "dummy ReplyPort arg";
+	arg->argVarName = "dummy ReplyPort arg";
+	arg->argType = type;
+	arg->argKind = akeReplyPort;
+	rt->rtReplyPort = arg;
+
+	/* add the reply port after the request port */
+
+	if (rt->rtRequestPort != argNULL)
+		loc = &rt->rtRequestPort->argNext;
+	else
+		loc = &rt->rtArgs;
+
+	arg->argNext = *loc;
+	*loc = arg;
+
+	rtSetArgDefaults(rt, arg);
+}
+
+
+/*
+ * At least one overwrite keyword has been detected:
+ * we tag all the OOL entries (ports + data) with
+ * akbOverwrite which will tell us that we have to
+ * fill a KPD entry in the message-template
+ */
+static void
+rtCheckOverwrite(register routine_t *rt)
+{
+	register argument_t *arg;
+	register int howmany = rt->rtOverwrite;
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		register ipc_type_t *it = arg->argType;
+
+		if (akCheck(arg->argKind, akbReturnKPD) && !it->itInLine) {
+			/* among OUT args, we want OOL, OOL ports and MigInLine */
+			arg->argKind = akAddFeature(arg->argKind, akbOverwrite);
+			if (arg->argFlags & flOverwrite)
+				howmany--;
+			if (!howmany)
+				return;
+		}
+	}
+}
+
+/*
+ * Initializes argRequestPos, argReplyPos, rtMaxRequestPos, rtMaxReplyPos,
+ * rtNumRequestVar, rtNumReplyVar, and adds akbVarNeeded to those arguments
+ * that need it because of variable-sized inline considerations.
+ *
+ * argRequestPos and argReplyPos get -1 if the value shouldn't be used.
+ */
+static void
+rtCheckVariable(register routine_t *rt)
+{
+	register argument_t *arg;
+	int NumRequestVar = 0;
+	int NumReplyVar = 0;
+	int MaxRequestPos = 0;
+	int MaxReplyPos = 0;
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		register argument_t *parent = arg->argParent;
+
+		/*
+		 * We skip KPDs. We have to make sure that the KPDs count
+		 * present in the message body follow the RequestPos/ReplyPos logic
+		 * The rest of the parameters are defaulted to have
+		 * Arg{Request, Reply}Pos = 0
+		 */
+		if (parent == argNULL || akCheck(parent->argKind, akbSendKPD|akbReturnKPD)) {
+			if (akCheckAll(arg->argKind, akbSend|akbSendBody)) {
+				arg->argRequestPos = NumRequestVar;
+				MaxRequestPos = NumRequestVar;
+				if (akCheck(arg->argKind, akbVariable))
+					NumRequestVar++;
+			}
+			if (akCheckAll(arg->argKind, akbReturn|akbReturnBody)) {
+				arg->argReplyPos = NumReplyVar;
+				MaxReplyPos = NumReplyVar;
+				if (akCheck(arg->argKind, akbVariable))
+					NumReplyVar++;
+			}
+		} else {
+			arg->argRequestPos = parent->argRequestPos;
+			arg->argReplyPos = parent->argReplyPos;
+		}
+		/*
+		  printf("Var %s Kind %x RequestPos %d\n", arg->argVarName, arg->argKind, arg->argRequestPos);
+		  printf("* Var %s Kind %x ReplyPos %d\n", arg->argVarName, arg->argKind, arg->argReplyPos);
+		*/
+
+		/* Out variables that follow a variable-sized field
+		   need VarNeeded or ReplyCopy; they can't be stored
+		   directly into the reply message. */
+
+		if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnBody) &&
+			!akCheck(arg->argKind, akbReplyCopy|akbVarNeeded) &&
+			(arg->argReplyPos > 0))
+			arg->argKind = akAddFeature(arg->argKind, akbVarNeeded);
+	}
+
+	rt->rtNumRequestVar = NumRequestVar;
+	rt->rtNumReplyVar = NumReplyVar;
+	rt->rtMaxRequestPos = MaxRequestPos;
+	rt->rtMaxReplyPos = MaxReplyPos;
+}
+
+/*
+ * Adds akbDestroy where needed.
+ */
+
+static void
+rtCheckDestroy(register routine_t *rt)
+{
+	register argument_t *arg;
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		register ipc_type_t *it = arg->argType;
+
+		if(akCheck(arg->argKind, akbSendRcv) &&
+		   !akCheck(arg->argKind, akbReturnSnd) &&
+		   (it->itDestructor != strNULL || IS_MIG_INLINE_EMUL(it))) {
+			arg->argKind = akAddFeature(arg->argKind, akbDestroy);
+		}
+		if (argIsIn(arg) && akCheck(arg->argKind, akbSendKPD|akbReturnKPD) &&
+			arg->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR &&
+			(arg->argFlags & flAuto))
+			arg->argKind = akAddFeature(arg->argKind, akbDestroy);
+	}
+}
+
+/*
+ * Sets ByReferenceUser and ByReferenceServer.
+ */
+
+static void
+rtAddByReference(register routine_t *rt)
+{
+	register argument_t *arg;
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		register ipc_type_t *it = arg->argType;
+
+		if (akCheck(arg->argKind, akbReturnRcv) && it->itStruct) {
+			arg->argByReferenceUser = TRUE;
+
+			/*
+			 *  A CountInOut arg itself is not akbReturnRcv,
+			 *  so we need to set argByReferenceUser specially.
+			 */
+
+			if (arg->argCInOut != argNULL)
+				arg->argCInOut->argByReferenceUser = TRUE;
+		}
+
+		if ((akCheck(arg->argKind, akbReturnSnd) ||
+			(akCheck(arg->argKind, akbServerImplicit) &&
+			 akCheck(arg->argKind, akbReturnRcv) &&
+			 akCheck(arg->argKind, akbSendRcv)))
+			&& it->itStruct) {
+			arg->argByReferenceServer = TRUE;
+		}
+	}
+}
+
+/*
+ * This procedure can be executed only when all the akb* and ake* have
+ * been set properly (when rtAddCountArg is executed, akbVarNeeded
+ * might not be set yet - see rtCheckVariable)
+ */
+static void
+rtAddSameCount(register routine_t *rt)
+{
+	register argument_t *arg;
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+		if (arg->argFlags & flSameCount) {
+			register ipc_type_t *it = arg->argType;
+			register argument_t *tmp_count;
+			register argument_t *my_count = arg->argCount;
+			register argument_t *ref_count = arg->argSameCount->argCount;
+
+			tmp_count = argAlloc();
+			*tmp_count = *ref_count;
+			/*
+			 * if our count is a akbVarNeeded, we need to copy this
+			 * attribute to the master count!
+			 */
+			tmp_count->argKind = akeSameCount;
+			ref_count->argKind = akAddFeature(ref_count->argKind, akCheck(my_count->argKind, akbVarNeeded));
+			tmp_count->argKind = akAddFeature(tmp_count->argKind, akCheck(my_count->argKind, akbVarNeeded));
+			tmp_count->argNext = my_count->argNext;
+			tmp_count->argMultiplier = my_count->argMultiplier;
+			tmp_count->argType = my_count->argType;
+			tmp_count->argParent = arg;
+			/* we don't need more */
+			arg->argCount = tmp_count;
+			arg->argNext = tmp_count;
+			/* for these args, Cnt is not akbRequest, and therefore size is embedded */
+			if (IS_VARIABLE_SIZED_UNTYPED(it))
+				it->itMinTypeSize = 0;
+			tmp_count->argType->itMinTypeSize = 0;
+			tmp_count->argType->itTypeSize = 0;
+		}
+}
+
+void
+rtCheckRoutine(register routine_t *rt)
+{
+	/* Initialize random fields. */
+
+	rt->rtErrorName = ErrorProc;
+	rt->rtOneWay = (rt->rtKind == rkSimpleRoutine);
+	rt->rtServerName = strconcat(ServerPrefix, rt->rtName);
+	rt->rtUserName = strconcat(UserPrefix, rt->rtName);
+
+	/* Add implicit arguments. */
+
+	rtAddRetCode(rt);
+	rtAddNdrCode(rt);
+
+	/* Check out the arguments and their types.  Add count, poly
+	   implicit args.  Any arguments added after rtCheckRoutineArgs
+	   should have rtSetArgDefaults called on them. */
+
+	rtCheckRoutineArgs(rt);
+
+	/* Add dummy WaitTime and MsgOption arguments, if the routine
+	   doesn't have its own args and the user specified global values. */
+
+	if (rt->rtReplyPort == argNULL) {
+		if (rt->rtOneWay)
+			rtAddDummyReplyPort(rt, itZeroReplyPortType);
+		else
+			rtAddDummyReplyPort(rt, itRealReplyPortType);
+	}
+	if (rt->rtMsgOption == argNULL) {
+		if (MsgOption == strNULL)
+			rtAddMsgOption(rt, "MACH_MSG_OPTION_NONE");
+		else
+			rtAddMsgOption(rt, MsgOption);
+	}
+	if (rt->rtWaitTime == argNULL) {
+		if (WaitTime != strNULL)
+			rtAddWaitTime(rt, WaitTime, akeWaitTime);
+		else if (SendTime != strNULL)
+			rtAddWaitTime(rt, SendTime, akeSendTime);
+	}
+
+
+	/* Now that all the arguments are in place, do more checking. */
+
+	rtCheckArgTypes(rt);
+	rtCheckArgTrans(rt);
+
+    if (rt->rtOneWay && 
+    	(rtCheckMask(rt->rtArgs, akbReturn) || rt->rtUserImpl))
+		error("%s %s has OUT argument",
+			  rtRoutineKindToStr(rt->rtKind), rt->rtName);
+
+	/* If there were any errors, don't bother calculating more info
+	   that is only used in code generation anyway.  Therefore,
+	   the following functions don't have to worry about null types. */
+
+    if (errors > 0) 
+        fatal("%d errors found. Abort.\n", errors);
+
+	rt->rtServerImpl  = rtCountMask(rt->rtArgs, akbServerImplicit);
+	rt->rtUserImpl = rtCountMask(rt->rtArgs, akbUserImplicit);
+	/*
+	 * ASSUMPTION:
+	 * kernel cannot change a message from simple to complex,
+	 * therefore SimpleSendReply and SimpleRcvReply become SimpleReply
+	 */
+#ifdef notyet
+	/* Setting this to true causes MIG to generate incorrect code */
+	rtCheckSimple(rt->rtArgs, akbRequest, &rt->rtSimpleRequest);
+#endif
+	rtCheckSimple(rt->rtArgs, akbReply, &rt->rtSimpleReply);
+
+	rt->rtRequestKPDs = rtCountKPDs(rt->rtArgs, akbSendKPD);
+	rt->rtReplyKPDs = rtCountKPDs(rt->rtArgs, akbReturnKPD);
+	/*
+	 * Determine how many overwrite parameters we have:
+	 *  # of Overwrite args -> rt->rtOverwrite
+	 *  flOverwrite -> the arg has to be overwritten
+	 *  akbOverwrite -> the arg has to be declared in the message-template
+	 *  (only as a placeholder if !flOverwrite).
+	 */
+	if ((rt->rtOverwrite = rtCountFlags(rt->rtArgs, flOverwrite))) {
+		rtCheckOverwrite(rt);
+		rt->rtOverwriteKPDs = rtCountKPDs(rt->rtArgs, akbReturnKPD|akbOverwrite);
+		if (IsKernelUser)
+			fatal("Overwrite option(s) do not match with the KernelUser personality\n");
+	}
+
+    rtCheckFit(rt, akbRequest, &rt->rtRequestFits, &rt->rtRequestUsedLimit, &rt->rtRequestSizeKnown);
+    rtCheckFit(rt, akbReply, &rt->rtReplyFits, &rt->rtReplyUsedLimit, &rt->rtReplySizeKnown);
+
+	rtCheckVariable(rt);
+	rtCheckDestroy(rt);
+	rtAddByReference(rt);
+	rtSuffixExtArg(rt->rtArgs);
+	rtAddSameCount(rt);
+	rtProcessRetCode(rt);
+	rtProcessNdrCode(rt);
+	if (rt->rtUserImpl)
+		rtProcessMsgOption(rt);
+
+	rt->rtNoReplyArgs = !rtCheckMask(rt->rtArgs, akbReturnSnd);
+
+	if (UseEventLogger)
+		/* some more info's are needed for Event logging/Stats */
+		rtFindHowMany(rt);
+}
+
+void
+rtMinRequestSize(FILE *file, routine_t *rt, const char *str)
+{
+    fprintf(file, "(sizeof(%s)", str);
+	rtSizeDelta(file, akbRequest, rt);
+	fprintf(file, ")");
+}
+
+void
+rtMinReplySize(FILE *file, routine_t *rt, const char *str)
+{
+    fprintf(file, "(sizeof(%s)", str);
+	rtSizeDelta(file, akbReply, rt);
+	fprintf(file, ")");
+}
+
+static void
+rtSizeDelta(FILE *file, u_int mask, routine_t *rt)
+{
+	argument_t *arg;
+	u_int min_size = sizeof(mach_msg_header_t);
+	u_int max_size;
+	boolean_t output = FALSE;
+
+	if (!rt->rtSimpleRequest)
+		machine_alignment(min_size, sizeof(mach_msg_body_t));
+	max_size = min_size;
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+		if (akCheck(arg->argKind, mask)) {
+			register ipc_type_t *it = arg->argType;
+
+			machine_alignment(min_size, it->itMinTypeSize);
+			machine_alignment(max_size, it->itMinTypeSize);
+
+			if (IS_VARIABLE_SIZED_UNTYPED(it)) {
+				machine_alignment(max_size, it->itTypeSize);
+				max_size += it->itPadSize;
+			}
+			if (IS_OPTIONAL_NATIVE(it)) {
+				if (output)
+					fprintf(file, " + ");
+				else {
+					output = TRUE;
+					fprintf(file, " - (");
+				}
+				fprintf(file, "_WALIGNSZ_(%s)", it->itUserType);
+			}
+		}
+	if (min_size != max_size) {
+		if (output)
+			fprintf(file, " + ");
+		else
+			fprintf(file, " - ");
+		fprintf(file, "%d", max_size - min_size);
+	}
+	if (output)
+		fprintf(file, ")");
+}
+


Property changes on: trunk/usr.bin/migcom/routine.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/routine.h
===================================================================
--- trunk/usr.bin/migcom/routine.h	                        (rev 0)
+++ trunk/usr.bin/migcom/routine.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,615 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 at 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.
+ */
+/*
+ * 92/03/03  16:25:12  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:32:23  jeffreyh]
+ * 
+ * 92/01/14  16:46:34  rpd
+ * 	Removed akbWasInOut.  Added akeCountInOut, argCInOut.
+ * 	[92/01/08            rpd]
+ * 
+ * 92/01/03  20:29:52  dbg
+ * 	Add byReferenceUser and byReferenceServer to each argument, so
+ * 	they can be individually set.  Add akbPointer.
+ * 	[91/09/04            dbg]
+ * 
+ * 91/08/28  11:17:17  jsb
+ * 	Removed Camelot and TrapRoutine support.
+ * 	Changed MsgKind to MsgSeqno.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/07/31  18:10:37  dbg
+ * 	Add akbIndefinite, argServerCopy.
+ * 	[91/04/10            dbg]
+ * 
+ * 	Change argDeallocate to an enumerated type, to allow for
+ * 	user-specified deallocate flag.
+ * 
+ * 	Add rtCheckMaskFunction.  Add rtNoReplyArgs to routine
+ * 	structure.
+ * 	[91/04/03            dbg]
+ * 
+ * 91/02/05  17:55:28  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:55:21  mrt]
+ * 
+ * 90/06/02  15:05:23  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:12:57  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 20-Dec-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Added pointers to last Request and Reply arguments.
+ *	Added flag to show that (only) last argument is variable-sized.
+ *	Added argMultiplier field for count arguments, where parent
+ *	argument is itself a multiple of an IPC type.
+ *
+ * 16-Nov-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Don't add akbVarNeeded attribute here - server.c can
+ *	better determine whether it is needed.
+ *
+ * 21-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added argFlag field to argument_t
+ *
+ * 18-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed akTid to omit akServerArg
+ *	Changed arg_kind_t to u_int to make code more obvious and
+ *	to get rid of compiler warnings and to give hc a chance.
+ *	Changed flags on akTid, akDummy.
+ *
+ * 10-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added defines need to make MsgType a legitimate argument type
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#ifndef	_ROUTINE_H
+#define	_ROUTINE_H
+
+#include "type.h"
+#include <mach/message.h>
+#include <mach/boolean.h>
+#include <sys/types.h>
+
+/* base kind arg */
+#define akeNone		(0)
+#define akeNormal	(1)	/* a normal, user-defined argument */
+#define akeRequestPort	(2)	/* pointed at by rtRequestPort */
+#define akeWaitTime	(3)	/* pointed at by rtWaitTime */
+#define akeReplyPort	(4)	/* pointed at by rtReplyPort */
+#define akeMsgOption	(5)	/* pointed at by rtMsgOption */
+#define akeMsgSeqno	(6)	/* pointed at by rtMsgSeqno */
+#define akeRetCode	(7)	/* pointed at by rtRetCode */
+#define akeNdrCode	(8)	/* pointed at by rtNdrCode */
+#define akeCount	(9)	/* a count arg for argParent */
+#define akePoly		(10)	/* a poly arg for argParent */
+#define	akeDealloc	(11)	/* a deallocate arg for argParent */
+#define akeCountInOut   (12)  /* a count-in-out arg */
+#define akeSameCount    (13)  /* a samecount case: in fact, a no count! */
+#define akeSubCount     (14)  /* a array of array case: subordinate arrays count */
+#define akeImplicit     (15)  /* an implicit argument, from the trailer */
+#define akeSecToken     (16)  /* an argument from the trailer: the security token */
+#define akeAuditToken   (17)  /* an argument from the trailer: the audit token */
+#define akeContextToken (18)  /* an argument from the trailer: the context token */
+#define akeSendTime     (19)  /* pointed at by rtWaitTime */
+
+
+#define	akeBITS		(0x0000003f)
+#define	akbRequest	(0x00000040)	/* has a msg_type in request */
+#define	akbReply	(0x00000080)	/* has a msg_type in reply */
+#define	akbUserArg	(0x00000100)	/* an arg on user-side */
+#define	akbServerArg	(0x00000200)	/* an arg on server-side  */
+#define akbSend		(0x00000400)	/* value carried in request */
+#define akbSendBody	(0x00000800)	/* value carried in request body */
+#define akbSendSnd	(0x00001000)	/* value stuffed into request */
+#define akbSendRcv	(0x00002000)	/* value grabbed from request */
+#define akbReturn	(0x00004000)	/* value carried in reply */
+#define akbReturnBody	(0x00008000)	/* value carried in reply body */
+#define akbReturnSnd	(0x00010000)	/* value stuffed into reply */
+#define akbReturnRcv	(0x00020000)	/* value grabbed from reply */
+#define akbReturnNdr      (0x00040000)  /* needs NDR conversion in reply */
+#define akbReplyInit	(0x00080000)	/* reply value doesn't come from target routine */
+#define akbReplyCopy	(0x00200000)	/* copy reply value from request */
+#define akbVarNeeded	(0x00400000)	/* may need local var in server */
+#define akbDestroy	(0x00800000)	/* call destructor function */
+#define akbSendNdr        (0x04000000)  /* needs NDR conversion in request */
+#define akbVariable	(0x01000000)	/* variable size inline data */
+#define akbSendKPD 	(0x08000000)	/* the arg is sent in the Kernel Processed Data
+					   section of the Request message */
+#define akbReturnKPD 	(0x10000000)	/* the arg is sent in the Kernel Processed Data
+					   section of the Reply message */
+#define akbUserImplicit 	(0x20000000)	/* the arg is Impl */
+#define akbServerImplicit 	(0x40000000)	/* the arg is Impl */
+#define akbOverwrite 	(0x80000000)
+/* be careful, there aren't many bits left */
+
+typedef u_int  arg_kind_t;
+
+/*
+ * akbRequest means msg_type/data fields are allocated in the request
+ * msg.  akbReply means msg_type/data fields are allocated in the
+ * reply msg.  These bits * control msg structure declarations packing, 
+ * and checking of mach_msg_type_t fields.
+ *
+ * akbUserArg means this argument is an argument to the user-side stub.
+ * akbServerArg means this argument is an argument to
+ * the server procedure called by the server-side stub.
+ *
+ * The akbSend* and akbReturn* bits control packing/extracting values
+ * in the request and reply messages.
+ *
+ * akbSend means the argument's value is carried in the request msg.
+ * akbSendBody implies akbSend; the value is carried in the msg body.
+ * akbSendKPD is the equivalent of akbSendBody for Kernel Processed Data.
+ * akbSendSnd implies akbSend; the value is stuffed into the request.
+ * akbSendRcv implies akbSend; the value is pulled out of the request.
+ *
+ * akbReturn, akbReturnBody, akbReturnSnd, akbReturnRcv are defined
+ * similarly but apply to the reply message.
+ *
+ * User-side code generation (header.c, user.c) and associated code
+ * should use akbSendSnd and akbReturnRcv, but not akbSendRcv and
+ * akbReturnSnd.  Server-side code generation (server.c) is reversed.
+ * Code generation should use the more specific akb{Send,Return}{Snd,Rcv}
+ * bits when possible, instead of akb{Send,Return}.
+ *
+ * Note that akRetCode and akReturn lack any Return bits, although
+ * there is a value in the msg.  These guys are packed/unpacked
+ * with special code, unlike other arguments.
+ *
+ * akbReplyInit implies akbReply.  It means the server-side stub
+ * should initialize the field, because its value does not come
+ * from the execution of the target routine: the setting of the
+ * NDR record is the sole example (at the moment) of use of this flag.
+ *
+ * akbVariable means the argument has variable-sized inline data.
+ * It isn't currently used for code generation, but routine.c
+ * does use it internally.  It is added in rtAugmentArgKind.
+ *
+ * akbReplyCopy and akbVarNeeded help control code generation in the
+ * server-side stub.  The preferred method of handling data in the
+ * server-side stub avoids copying into/out-of local variables.  In
+ * arguments get passed directly to the server proc from the request msg.
+ * Out arguments get stuffed directly into the reply msg by the server proc.
+ * For InOut arguments, the server proc gets the address of the data in
+ * the request msg, and the resulting data gets copied to the reply msg.
+ * Some arguments need a local variable in the server-side stub.  The
+ * code extracts the data from the request msg into the variable, and
+ * stuff the reply msg from the variable.
+ *
+ * akbReplyCopy implies akbReply.  It means the data should get copied
+ * from the request msg to the reply msg after the server proc is called.
+ * It is only used by akInOut.  akTid doesn't need it because the tid
+ * data in the reply msg is initialized in the server demux function.
+ *
+ * akbVarNeeded means the argument needs a local variable in the
+ * server-side stub.  It is added in rtAugmentArgKind and
+ * rtCheckVariable.  An argument shouldn't have all three of
+ * akbReturnSnd, akbVarNeeded and akbReplyCopy, because this indicates
+ * the reply msg should be stuffed both ways.
+ *
+ * akbDestroy helps control code generation in the server-side stub.
+ * It means this argument has a destructor function which should be called.
+ *
+ * akbOverwrite is used to identify the arguments that have to put an entry in
+ * the scatter list (the message-template used by the User stub to specify 
+ * where the out-of-line data sent by server has to land).
+ *
+ * akbUserImplicit (akbServerImplicit) is used to mark the arguments that
+ * correspond to implicit data (data generated by the kernel and inserted in 
+ * the trailer).
+ *
+ * Header file generation (header.c) uses:
+ *	akbUserArg
+ *
+ * User stub generation (user.c) uses:
+ *	akbUserArg, akbRequest, akbReply, akbSendSnd,
+ *	akbSendBody, akbSendKPD, akbReturnRcv, akbOverwrite, akbUserImplicit 
+ *
+ * Server stub generation (server.c) uses:
+ *	akbServerArg, akbRequest, akbReply, akbSendRcv, akbReturnSnd,
+ *	akbReplyCopy, akbVarNeeded, akbSendBody, akbServerImplicit
+ *
+ *
+ * During code generation, the routine, argument, and type data structures
+ * are read-only.  The code generation functions' output is their only
+ * side-effect.
+ *
+ *
+ * Style note:
+ * Code can use logical operators (|, &, ~) on akb values.
+ * ak values should be manipulated with the ak functions.
+ */
+
+/* various useful combinations */
+
+#define akbNone		(0)
+#define akbAll		(~akbNone)
+#define akbAllBits	(~akeBITS)
+
+#define akbSendBits	(akbSend|akbSendBody|akbSendSnd|akbSendRcv)
+#define akbReturnBits	(akbReturn|akbReturnBody|akbReturnSnd|akbReturnRcv)
+#define akbSendReturnBits	(akbSendBits|akbReturnBits)
+
+#define akNone		akeNone
+
+#define akIn		akAddFeature(akeNormal,				\
+	akbUserArg|akbServerArg|akbRequest|akbSendBits)
+
+#define akOut		akAddFeature(akeNormal,				\
+	akbUserArg|akbServerArg|akbReply|akbReturnBits)
+
+#define akServerImpl	akAddFeature(akeImplicit, \
+	akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
+#define akUserImpl	akAddFeature(akeImplicit, \
+	akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
+
+#define akServerSecToken akAddFeature(akeSecToken, \
+	akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
+#define akUserSecToken akAddFeature(akeSecToken, \
+	akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
+
+#define akSecToken akAddFeature(akeSecToken, \
+        akbServerArg|akbServerImplicit|akbSend|akbSendRcv| \
+        akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
+
+#define akServerAuditToken akAddFeature(akeAuditToken, \
+  akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
+#define akUserAuditToken akAddFeature(akeAuditToken, \
+  akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
+#define akAuditToken akAddFeature(akeAuditToken, \
+        akbServerArg|akbServerImplicit|akbSend|akbSendRcv| \
+        akbUserArg|akbUserImplicit|akbReturn|akbReturnRcv)
+
+#define akServerContextToken akAddFeature(akeContextToken, \
+  akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
+	
+#define akMsgSeqno	akAddFeature(akeMsgSeqno,			\
+	akbServerArg|akbServerImplicit|akbSend|akbSendRcv)
+
+#define akInOut		akAddFeature(akeNormal,				\
+	akbUserArg|akbServerArg|akbRequest|akbReply|			\
+	akbSendBits|akbReturnBits|akbReplyCopy)
+
+#define akRequestPort	akAddFeature(akeRequestPort,			\
+	akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv)
+
+#define akWaitTime	akAddFeature(akeWaitTime, akbUserArg)
+
+#define akSendTime  akAddFeature(akeSendTime, akbUserArg)
+	
+#define akMsgOption	akAddFeature(akeMsgOption, akbUserArg)
+
+#define akReplyPort	akAddFeature(akeReplyPort,			\
+	akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv)
+
+#define akUReplyPort	akAddFeature(akeReplyPort,			\
+	akbUserArg|akbSend|akbSendSnd|akbSendRcv)
+
+#define akSReplyPort	akAddFeature(akeReplyPort,			\
+	akbServerArg|akbSend|akbSendSnd|akbSendRcv)
+
+#define akRetCode	akAddFeature(akeRetCode, akbReply|akbReturnBody)
+
+#define akCount		akAddFeature(akeCount,				\
+	akbUserArg|akbServerArg)
+
+#define akPoly		akePoly
+
+#define	akDealloc	akAddFeature(akeDealloc, akbUserArg)
+
+#define akCountInOut	akAddFeature(akeCountInOut, akbRequest|akbSendBits)
+
+#define	akCheck(ak, bits)	((ak) & (bits))
+#define akCheckAll(ak, bits)	(akCheck(ak, bits) == (bits))
+#define akAddFeature(ak, bits)	((ak)|(bits))
+#define akRemFeature(ak, bits)	((ak)&~(bits))
+#define akIdent(ak)		((ak) & akeBITS)
+
+#define argIsIn(arg)	(akIdent(arg->argKind) == akeNormal && \
+					akCheck(arg->argKind, akbRequest))
+#define argIsOut(arg)	(akIdent(arg->argKind) == akeNormal && \
+					akCheck(arg->argKind, akbReply))
+
+/*
+ * The arguments to a routine/function are linked in left-to-right order.
+ * argName is used for error messages and pretty-printing,
+ * not code generation.  Code generation shouldn't make any assumptions
+ * about the order of arguments, esp. count and poly arguments.
+ * (Unfortunately, code generation for inline variable-sized arguments
+ * does make such assumptions.)
+ *
+ * argVarName is the name used in generated code for function arguments
+ * and local variable names.  argMsgField is the name used in generated
+ * code for the field in msgs where the argument's value lives.
+ * argTTName is the name used in generated code for msg-type fields and
+ * static variables used to initialize those fields.  argPadName is the
+ * name used in generated code for a padding field in msgs.
+ *
+ * argFlags can be used to override the deallocate bits
+ * in the argument's type.  rtProcessArgFlags sets argDeallocate 
+ * from it and the type.  Code generation shouldn't use
+ * argFlags.
+ *
+ * argCount, argPoly, and argDealloc get to the implicit count, poly,
+ * and dealloc arguments associated with the argument; they should be
+ * used instead of argNext.  In these implicit arguments, argParent is
+ * a pointer to the "real" arg.
+ *
+ * In count arguments, argMultiplier is a scaling factor applied to
+ * the count arg's value to get msg-type-number.  It is equal to
+ *	argParent->argType->itElement->itNumber
+ * 
+ */
+
+typedef struct argument
+{
+    /* if argKind == akReturn, then argName is name of the function */
+    identifier_t argName;
+    struct argument *argNext;
+
+    arg_kind_t argKind;
+    ipc_type_t *argType;
+						/* Kernel Processed Data */
+    mach_msg_descriptor_type_t argKPD_Type; 	/* KPD type: port, ool, port+ool */
+    void  (* argKPD_Template)();		/* KPD discipline for static templates */
+    void  (* argKPD_Init)();			/* KPD discipline for initializing */
+    void  (* argKPD_Pack)();			/* KPD discipline for packing */
+    void  (* argKPD_Extract)();			/* KPD discipline for extracting */
+    void  (* argKPD_TypeCheck)();		/* KPD discipline for type checking */
+
+    string_t argVarName;	/* local variable and argument names */
+    string_t argMsgField;	/* message field's name */
+    string_t argTTName;		/* name for msg_type fields, static vars */
+    string_t argPadName;	/* name for pad field in msg */
+    string_t argSuffix;		/* name extension for KPDs */
+
+    ipc_flags_t argFlags;
+    dealloc_t argDeallocate;	/* overrides argType->itDeallocate */
+    boolean_t argCountInOut;
+
+    struct routine *argRoutine;	/* routine we are part of */
+
+    struct argument *argCount;	/* our count arg, if present */
+    struct argument *argSubCount;	/* our sub-count arg, if present (variable subordinate arrays) */
+    struct argument *argCInOut;	/* our CountInOut arg, if present */
+    struct argument *argPoly;	/* our poly arg, if present */
+    struct argument *argDealloc;/* our dealloc arg, if present */
+    struct argument *argSameCount;	/* the arg to take the count from, if present */
+    struct argument *argParent;	/* in a count or poly arg, the base arg */
+    u_int argMultiplier;	/* for Count argument: parent is a multiple
+				   of a basic IPC type.  Argument must be
+				   multiplied by Multiplier to get IPC
+				   number-of-elements. */
+
+    /* how variable/inline args precede this one, in request and reply */
+    u_int argRequestPos;
+    u_int argReplyPos;
+    /* whether argument is by reference, on user and server side */
+    boolean_t	argByReferenceUser;
+    boolean_t	argByReferenceServer;
+
+    boolean_t	argTempOnStack;	/* A temporary for the short-circuiting
+				 * code when -maxonstack is used.
+				 */
+} argument_t;
+
+/*
+ * The various routine kinds' peculiarities are abstracted by rtCheckRoutine
+ * into attributes like rtOneWay, etc.  These are what
+ * code generation should use.  It is Bad Form for code generation to
+ * test rtKind.
+ */
+
+typedef enum
+{
+    rkRoutine,
+    rkSimpleRoutine
+} routine_kind_t;
+
+typedef struct routine
+{
+    identifier_t rtName;
+    routine_kind_t rtKind;
+    argument_t *rtArgs;
+    u_int rtNumber;		/* used for making msg ids */
+
+    identifier_t rtUserName;	/* user-visible name (UserPrefix + Name) */
+    identifier_t rtServerName;	/* server-side name (ServerPrefix + Name) */
+
+    identifier_t rtErrorName;	/* error-handler name */
+
+    boolean_t rtOneWay;		/* SimpleRoutine */
+
+    boolean_t rtSimpleRequest;
+    boolean_t rtSimpleReply;	
+
+    u_int rtNumRequestVar;	/* number of variable/inline args in request */
+    u_int rtNumReplyVar;	/* number of variable/inline args in reply */
+
+    u_int rtMaxRequestPos;	/* maximum of argRequestPos */
+    u_int rtMaxReplyPos;	/* maximum of argReplyPos */
+
+    u_int rtRequestKPDs;	/* number of Kernel Processed Data entries */
+    u_int rtReplyKPDs;		/* number of Kernel Processed Data entries */
+    u_int rtOverwrite;		/* number of Overwrite entries */
+    u_int rtOverwriteKPDs;	/* number of entries in the Overwrite template */
+
+    boolean_t rtNoReplyArgs;	/* if so, no reply message arguments beyond
+				   what the server dispatch routine inserts */
+
+    boolean_t rtRequestFits;	/* Request fits within onstack limit */
+    boolean_t rtReplyFits;	/* Reply fits within onstack limit */
+    boolean_t rtRequestUsedLimit;/* User type limit used in deciding whether 
+                                    request fits within onstack limit */
+    boolean_t rtReplyUsedLimit; /* User type limit used in deciding whether 
+                                   reply fits within onstack limit */
+    u_int rtRequestSizeKnown;   /* Max size of known portion of request */
+    u_int rtReplySizeKnown;     /* Max size of known portion of request */
+
+    u_int rtServerImpl;		/* Implicit data requested */
+    u_int rtUserImpl;		/* Implicit data requested */
+
+    /* distinguished arguments */
+    argument_t *rtRetCArg;	/* the Routine has this argument tagged as RetCode */
+    argument_t *rtRequestPort;	/* always non-NULL, defaults to first arg */
+    argument_t *rtReplyPort;	/* always non-NULL, defaults to Mig-supplied */
+    argument_t *rtRetCode;	/* always non-NULL */
+    argument_t *rtNdrCode;	/* always non-NULL */
+    argument_t *rtWaitTime;	/* if non-NULL, will use MACH_RCV_TIMEOUT */
+    argument_t *rtMsgOption;	/* always non-NULL, defaults to NONE */
+
+    /* more info's used only when UseEventLogger is turned on */
+    u_int	rtCountPortsIn;    /* how many in-line Ports are sent */
+    u_int	rtCountOolPortsIn; /* how many out_of-line Ports are sent */
+    u_int	rtCountOolIn; 	   /* how many bytes out_of-line are sent */
+
+    u_int	rtCountPortsOut;    /* how many in-line Ports are rcv'd */
+    u_int	rtCountOolPortsOut; /* how many out_of-line Ports are rcv'd */
+    u_int	rtCountOolOut; 	    /* how many bytes out_of-line are rcv'd */
+
+    u_int	rtTempBytesOnStack; /* A temporary for the short-circuiting
+				     * code when -maxonstack is used.
+				     */
+
+} routine_t;
+
+#define rtNULL		((routine_t *) 0)
+#define argNULL		((argument_t *) 0)
+#define argKPD_NULL	((mach_msg_descriptor_type_t) -1)
+
+#define rtMessOnStack(rt) ((rt)->rtRequestFits && (rt)->rtReplyFits)
+
+/*
+ * These are the ways MiG organizes stub parameters
+ */
+#define IS_VARIABLE_SIZED_UNTYPED(x)  ((x)->itVarArray && \
+                                       (x)->itInLine  && \
+                                      !(x)->itPortType)
+#define IS_KERN_PROC_DATA(x)	     (!(x)->itInLine || (x)->itPortType)
+#define IS_OPTIONAL_NATIVE(x)        ((x)->itNative && \
+                                      (x)->itNativePointer && \
+                                      (x)->itBadValue != NULL)
+
+/*
+ * I consider the case of fixed/variable bounded arrays of ports or ool or oolport
+ */
+#define IS_MULTIPLE_KPD(x) 	((x)->itKPD_Number > 1)
+/*
+ * I consider the case of MiG presenting data as it is inLine, even
+ * if it is sent/rcvd as out-of-line
+ */
+#define IS_MIG_INLINE_EMUL(x) 		((x)->itMigInLine)
+
+extern u_int rtNumber;
+/* rt->rtNumber will be initialized */
+extern routine_t *rtAlloc(void);
+/* skip a number */
+extern void rtSkip(void);
+
+extern argument_t *argAlloc(void);
+
+extern boolean_t
+rtCheckMask(argument_t *args, u_int mask);
+
+extern boolean_t
+rtCheckMaskFunction(argument_t *args, u_int mask,
+					boolean_t (*func)(argument_t *arg));
+
+extern routine_t *
+rtMakeRoutine( identifier_t name, argument_t *args);
+extern routine_t *
+rtMakeSimpleRoutine(identifier_t name, argument_t *args);
+
+extern void rtPrintRoutine(routine_t *rt);
+extern void rtCheckRoutine(routine_t *rt);
+
+extern const char *rtRoutineKindToStr(routine_kind_t rk);
+
+extern int rtCountArgDescriptors(argument_t *args, int *argcount);
+
+extern void rtMinRequestSize(FILE *file, routine_t *rt, const char *str);
+extern void rtMinReplySize(FILE *file, routine_t *rt, const char *str);
+
+#define RPCUserStruct(arg)    (arg->argType->itStruct && arg->argType->itInLine)
+
+#define RPCString(arg)        (arg->argType->itString && arg->argType->itInLine)
+
+#define RPCOutStruct(arg)     (arg->argType->itStruct &&\
+			       argIsOut(arg) && (! arg->argType->itVarArray))
+#define RPCOutWord(arg)       (RPCUserStruct(arg) &&\
+			       (arg->argType->itSize <= 32) &&\
+			       (arg->argType->itNumber == 1) && argIsOut(arg))
+
+#define RPCPort(arg)          (arg->argKPD_Type == MACH_MSG_PORT_DESCRIPTOR)
+
+#define RPCPortArray(arg)     (arg->argKPD_Type == MACH_MSG_OOL_PORTS_DESCRIPTOR)
+
+#define RPCVariableArray(arg) ((arg->argType->itVarArray) &&\
+			       !RPCPort(arg) && !RPCPortArray(arg))
+
+#define RPCFixedArray(arg)    (((! arg->argType->itVarArray) &&\
+			       !RPCPort(arg) && !RPCPortArray(arg) &&\
+			       (arg->argType->itNumber > 1) &&\
+				!RPCUserStruct(arg)) ||\
+			       RPCString(arg) ||\
+			       RPCOutWord(arg) ||\
+			       RPCOutStruct(arg))
+
+
+#endif	/* _ROUTINE_H */
+
+
+


Property changes on: trunk/usr.bin/migcom/routine.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/server.c
===================================================================
--- trunk/usr.bin/migcom/server.c	                        (rev 0)
+++ trunk/usr.bin/migcom/server.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,2843 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 at 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.
+ */
+/*
+ * 92/03/03  16:25:17  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:32:30  jeffreyh]
+ * 
+ * 92/01/14  16:46:39  rpd
+ * 	Modified WriteInitializeCount, WriteExtractArg
+ * 	for the revised CountInOut implementation.
+ * 	Fixed Indefinite code generation, to allow short type descriptors.
+ * 	Added deallocate bit handling to Indefinite code generation.
+ * 	[92/01/08            rpd]
+ * 
+ * 92/01/03  20:30:09  dbg
+ * 	Generate <subsystem>_server_routine to return unpacking function
+ * 	pointer.
+ * 	[91/11/11            dbg]
+ * 
+ * 	For inline variable-length arrays that are Out parameters, allow
+ * 	passing the user's count argument to the server as an InOut
+ * 	parameter.
+ * 	[91/11/11            dbg]
+ * 
+ * 	Redo handling of OUT arrays that are passed in-line or
+ * 	out-of-line.  Treat more like out-of-line arrays:
+ * 	user allocates buffer and pointer
+ * 	fills in pointer with buffer address
+ * 	passes pointer to stub
+ * 	stub copies data to *pointer, or changes pointer
+ * 	User can always use *pointer.
+ * 
+ * 	Change argByReferenceUser to a field in argument_t.
+ * 	[91/09/04            dbg]
+ * 
+ * 91/08/28  11:17:21  jsb
+ * 	Replaced ServerProcName with ServerDemux.
+ * 	[91/08/13            rpd]
+ * 
+ * 	Removed Camelot and TrapRoutine support.
+ * 	Changed MsgKind to MsgSeqno.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/07/31  18:10:51  dbg
+ * 	Allow indefinite-length variable arrays.  They may be copied
+ * 	either in-line or out-of-line, depending on size.
+ * 
+ * 	Copy variable-length C Strings with mig_strncpy, to combine
+ * 	'strcpy' and 'strlen' operations.
+ * 
+ * 	New method for advancing request message pointer past
+ * 	variable-length arguments.  We no longer have to know the order
+ * 	of variable-length arguments and their count arguments.
+ * 
+ * 	Remove redundant assignments (to msgh_simple, msgh_size) in
+ * 	generated code.
+ * 	[91/07/17            dbg]
+ * 
+ * 91/06/25  10:31:51  rpd
+ * 	Cast request and reply ports to ipc_port_t in KernelServer stubs.
+ * 	[91/05/27            rpd]
+ * 
+ * 91/02/05  17:55:37  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:55:30  mrt]
+ * 
+ * 90/06/02  15:05:29  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:13:12  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 18-Oct-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Set the local port in the server reply message to
+ *	MACH_PORT_NULL for greater efficiency and to make Camelot
+ *	happy.
+ *
+ * 18-Apr-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed call to WriteLocalVarDecl in WriteMsgVarDecl
+ *	to write out the parameters for the C++ code to a call
+ *	a new routine WriteServerVarDecl which includes the *
+ *	for reference variable, but uses the transType if it
+ *	exists.
+ *
+ * 27-Feb-88  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Changed reply message initialization for camelot interfaces.
+ *	Now we assume camelot interfaces are all camelotroutines and
+ *	always initialize the dummy field & tid field.  This fixes
+ *	the wrapper-server-call bug in distributed transactions.
+ *
+ * 23-Feb-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed the include of camelot_types.h to cam/camelot_types.h
+ *
+ * 19-Feb-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Fixed WriteDestroyArg to not call the destructor
+ *	function on any in/out args.
+ *
+ *  4-Feb-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Fixed dld's code to write out parameter list to
+ *	use WriteLocalVarDecl to get transType or ServType if
+ *	they exist.
+ *
+ * 19-Jan-88  David Golub (dbg) at Carnegie-Mellon University
+ *	Change variable-length inline array declarations to use
+ *	maximum size specified to Mig.  Make message variable
+ *	length if the last item in the message is variable-length
+ *	and inline.  Use argMultipler field to convert between
+ *	argument and IPC element counts.
+ *
+ * 18-Jan-88  David Detlefs (dld) at Carnegie-Mellon University
+ *	Modified to produce C++ compatible code via #ifdefs.
+ *	All changes have to do with argument declarations.
+ *
+ *  2-Dec-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Added destructor function for IN arguments to server.
+ *
+ * 18-Nov-87  Jeffrey Eppinger (jle) at Carnegie-Mellon University
+ *	Changed to typedef "novalue" as "void" if we're using hc.
+ *
+ * 17-Sep-87  Bennet Yee (bsy) at Carnegie-Mellon University
+ *	Added _<system>SymTab{Base|End} for use with security
+ *	dispatch routine.  It is neccessary for the authorization
+ *	system to know the operations by symbolic names.
+ *	It is harmless to user code as it only means an extra
+ *	array if it is accidentally turned on.
+ *
+ * 24-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Corrected the setting of retcode for CamelotRoutines.
+ *
+ * 21-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added deallocflag to call to WritePackArgType.
+ *
+ * 14-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Moved type declarations and assignments for DummyType 
+ *	and tidType to server demux routine. Automatically
+ *	include camelot_types.h and msg_types.h for interfaces 
+ *	containing camelotRoutines.
+ *
+ *  8-Jun-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Removed #include of sys/types.h and strings.h from WriteIncludes.
+ *	Changed the KERNEL include from ../h to sys/
+ *	Removed extern from WriteServer to make hi-c happy
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <mach/message.h>
+#include "write.h"
+#include "utils.h"
+#include "global.h"
+#include "error.h"
+
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif  /* max */
+
+void WriteLogDefines();
+void WriteIdentificationString();
+static void WriteFieldDecl();
+
+static void
+WriteKPD_Iterator(FILE *file, boolean_t in, boolean_t varying, argument_t *arg, boolean_t bracket)
+{
+	register ipc_type_t *it = arg->argType;
+	char string[MAX_STR_LEN];
+
+	fprintf(file, "\t{\n");
+	fprintf(file, "\t    register\t%s\t*ptr;\n", it->itKPDType);
+	fprintf(file, "\t    register int\ti");
+	if (varying && !in)
+		fprintf(file, ", j");
+	fprintf(file, ";\n\n");
+
+	if (in)
+		sprintf(string, "In%dP", arg->argRequestPos);
+	else
+		sprintf(string, "OutP");
+
+	fprintf(file, "\t    ptr = &%s->%s[0];\n", string, arg->argMsgField);
+
+	if (varying) {
+		register argument_t *count = arg->argCount;
+
+		if (in)
+            fprintf(file, "\t    for (i = 0; i < In%dP->%s; ptr++, i++) %s\n",
+					count->argRequestPos, count->argMsgField,
+					(bracket) ? "{" : "");
+		else {
+			fprintf(file, "\t    j = min(%d, ", it->itKPD_Number);
+			if (akCheck(count->argKind, akbVarNeeded))
+				fprintf(file, "%s);\n", count->argName);
+			else
+				fprintf(file, "%s->%s);\n", string, count->argMsgField);
+            fprintf(file, "\t    for (i = 0; i < j; ptr++, i++) %s\n",
+					(bracket) ? "{" : "");
+		}
+    } else
+        fprintf(file, "\t    for (i = 0; i < %d; ptr++, i++) %s\n", it->itKPD_Number,
+				(bracket) ? "{" : "");
+}
+
+static void
+WriteMyIncludes(FILE *file, statement_t *stats)
+{
+	if (ServerHeaderFileName == strNULL || UseSplitHeaders)
+		WriteIncludes(file, FALSE, FALSE);
+	if (ServerHeaderFileName != strNULL)
+	{
+        register const char *cp;
+
+		/* Strip any leading path from ServerHeaderFileName. */
+		cp = strrchr(ServerHeaderFileName, '/');
+		if (cp == 0)
+			cp = ServerHeaderFileName;
+		else
+			cp++;       /* skip '/' */
+		fprintf(file, "#include \"%s\"\n", cp);
+	}
+	if (ServerHeaderFileName == strNULL || UseSplitHeaders)
+		WriteImplImports(file, stats, FALSE);
+	if (UseEventLogger) {
+		if (IsKernelServer) {
+			fprintf(file, "#if\t__MigKernelSpecificCode\n");
+			fprintf(file, "#include <mig_debug.h>\n");
+			fprintf(file, "#endif\t/* __MigKernelSpecificCode */\n");
+		}
+		fprintf(file, "#if  MIG_DEBUG\n");
+		fprintf(file, "#include <mach/mig_log.h>\n");
+		fprintf(file, "#endif /* MIG_DEBUG */\n");
+	}
+	fprintf(file, "\n");
+}
+
+static void
+WriteGlobalDecls(FILE *file)
+{
+	if (BeAnsiC) {
+		fprintf(file, "#define novalue void\n");
+    } else {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "#define novalue void\n");
+		fprintf(file, "#else\n");
+		fprintf(file, "#define novalue int\n");
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+		WriteRCSDecl(file, strconcat(SubsystemName, "_server"), RCSId);
+	}
+	/* Used for locations in the request message, *not* reply message.
+	   Reply message locations aren't dependent on IsKernelServer. */
+
+	if (IsKernelServer) {
+		fprintf(file, "#if\t__MigKernelSpecificCode\n");
+		fprintf(file, "#define msgh_request_port\tmsgh_remote_port\n");
+		fprintf(file, "#define MACH_MSGH_BITS_REQUEST(bits)");
+		fprintf(file, "\tMACH_MSGH_BITS_REMOTE(bits)\n");
+		fprintf(file, "#define msgh_reply_port\t\tmsgh_local_port\n");
+		fprintf(file, "#define MACH_MSGH_BITS_REPLY(bits)");
+		fprintf(file, "\tMACH_MSGH_BITS_LOCAL(bits)\n");
+		fprintf(file, "#else\n");
+	}
+	fprintf(file, "#define msgh_request_port\tmsgh_local_port\n");
+	fprintf(file, "#define MACH_MSGH_BITS_REQUEST(bits)");
+	fprintf(file, "\tMACH_MSGH_BITS_LOCAL(bits)\n");
+	fprintf(file, "#define msgh_reply_port\t\tmsgh_remote_port\n");
+	fprintf(file, "#define MACH_MSGH_BITS_REPLY(bits)");
+	fprintf(file, "\tMACH_MSGH_BITS_REMOTE(bits)\n");
+	if (IsKernelServer) {
+		fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+	}
+	fprintf(file, "\n");
+	if (UseEventLogger)
+		WriteLogDefines(file, "MACH_MSG_LOG_SERVER");
+	fprintf(file, "#define MIG_RETURN_ERROR(X, code)\t{\\\n");
+	fprintf(file, "\t\t\t\t((mig_reply_error_t *)X)->RetCode = code;\\\n");
+	fprintf(file, "\t\t\t\t((mig_reply_error_t *)X)->NDR = NDR_record;\\\n");
+	fprintf(file, "\t\t\t\treturn;\\\n");
+	fprintf(file, "\t\t\t\t}\n");
+	fprintf(file, "\n");
+}
+
+static void
+WriteForwardDeclarations(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	fprintf(file, "/* Forward Declarations */\n\n");
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine) {
+			fprintf(file, "\nmig_internal novalue _X%s\n", stat->stRoutine->rtName);
+			fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);\n");
+		}
+	fprintf(file, "\n");
+}
+
+static void
+WriteMIGCheckDefines(FILE *file)
+{
+	fprintf(file, "#define\t__MIG_check__Request__%s_subsystem__ 1\n", SubsystemName);
+	fprintf(file, "\n");
+}
+
+static void
+WriteNDRDefines(FILE *file)
+{
+	fprintf(file, "#define\t__NDR_convert__Request__%s_subsystem__ 1\n", SubsystemName);
+	fprintf(file, "\n");
+}
+
+static void
+WriteProlog(FILE *file, statement_t *stats)
+{
+	WriteIdentificationString(file);
+	fprintf(file, "\n");
+	fprintf(file, "/* Module %s */\n", SubsystemName);
+	fprintf(file, "\n");
+	WriteMIGCheckDefines(file);
+	if (CheckNDR)
+		WriteNDRDefines(file);
+	WriteMyIncludes(file, stats);
+	WriteBogusDefines(file);
+	WriteApplDefaults(file, "Rcv");
+	WriteGlobalDecls(file);
+	if (ServerHeaderFileName == strNULL) {
+		WriteRequestTypes(file, stats);
+		WriteReplyTypes(file, stats);
+		WriteServerReplyUnion(file, stats);
+	}
+}
+
+static void
+WriteSymTabEntries(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+	register u_int current = 0;
+
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine) {
+			register u_int num = stat->stRoutine->rtNumber;
+			const char	*name = stat->stRoutine->rtName;
+			while (++current <= num)
+				fprintf(file,"\t\t\t{ \"\", 0, 0 },\n");
+			fprintf(file, "\t{ \"%s\", %d, _X%s },\n", name, SubsystemBase + current - 1, name);
+		}
+	while (++current <= rtNumber)
+		fprintf(file,"\t{ \"\", 0, 0 },\n");
+}
+
+static void
+WriteRoutineEntries(FILE *file, statement_t *stats)
+{
+	register u_int current = 0;
+	register statement_t *stat;
+	char *sig_array, *rt_name;
+	int arg_count, descr_count;
+	int offset = 0;
+	size_t serverSubsysNameLen = strlen(ServerSubsys);
+
+	fprintf(file, "\t{\n");
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine)
+		{
+			register  routine_t *rt = stat->stRoutine;
+			size_t       rtNameLen = strlen(rt->rtName);
+
+			// Include length of rt->rtName in calculation of necessary buffer size, since that string
+			// is actually written into the buffer along with the Server Subsystem name.
+			sig_array = (char *) malloc(serverSubsysNameLen + rtNameLen + 80);
+			rt_name = (char *) malloc(rtNameLen + 5);
+			while (current++ < rt->rtNumber)
+				fprintf(file, "\t\t{0, 0, 0, 0, 0, 0},\n");
+			// NOTE: if either of the two string constants in the sprintf() function calls below get
+			// much longer, be sure to increase the constant '80' (in the first malloc() call) to ensure
+			// that the allocated buffer is large enough. (Currently, I count 66 characters in the first
+			// string constant, 65 in the second. 80 ought to be enough for now...)
+			if (UseRPCTrap) {
+				sprintf(sig_array, "&%s.arg_descriptor[%d], (mach_msg_size_t)sizeof(__Reply__%s_t)", ServerSubsys, offset, rt->rtName);
+			}
+			else {
+				sprintf(sig_array, "(routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__%s_t)", rt->rtName);
+			}
+			sprintf(rt_name, "_X%s", rt->rtName);
+			descr_count = rtCountArgDescriptors(rt->rtArgs, &arg_count);
+			offset += descr_count;
+			WriteRPCRoutineDescriptor(file, rt, arg_count, (UseRPCTrap) ? descr_count : 0, rt_name, sig_array);
+			fprintf(file, ",\n");
+			free(sig_array);
+			free(rt_name);
+		}
+	while (current++ < rtNumber)
+		fprintf(file, "\t\t{0, 0, 0, 0, 0, 0},\n");
+
+	fprintf(file, "\t}");
+}
+
+static void
+WriteArgDescriptorEntries(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	fprintf(file, ",\n\n\t{\n");
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine)
+		{
+			register routine_t *rt = stat->stRoutine;
+
+			/* For each arg of the routine, write an arg descriptor:
+			 */
+			WriteRPCRoutineArgDescriptor(file, rt);
+		}
+	fprintf(file, "\t},\n\n");
+}
+
+
+/*
+ * Write out the description of this subsystem, for use in direct RPC
+ */
+static void
+WriteSubsystem(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+	int descr_count = 0;
+
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine)
+		{
+			register routine_t *rt = stat->stRoutine;
+			descr_count += rtCountArgDescriptors(rt->rtArgs, (int *) 0);
+		}
+	fprintf(file, "\n");
+	if (ServerHeaderFileName == strNULL) {
+		WriteMigExternal(file);
+		fprintf(file, "boolean_t %s(", ServerDemux);
+		if (BeAnsiC) {
+			fprintf(file, "\n\t\tmach_msg_header_t *InHeadP,");
+			fprintf(file, "\n\t\tmach_msg_header_t *OutHeadP");
+		}
+		fprintf(file, ");\n\n");
+
+		WriteMigExternal(file);
+		fprintf(file, "mig_routine_t %s_routine(", ServerDemux);
+		if (BeAnsiC) {
+			fprintf(file, "\n\t\tmach_msg_header_t *InHeadP");
+		}
+		fprintf(file, ");\n\n");
+	}
+	fprintf(file, "\n/* Description of this subsystem, for use in direct RPC */\n");
+	if (ServerHeaderFileName == strNULL) {
+		fprintf(file, "extern const struct %s %s;\n", ServerSubsys, ServerSubsys);
+		fprintf(file, "const struct %s {\n", ServerSubsys);
+		if (UseRPCTrap) {
+			fprintf(file, "\tstruct subsystem *\tsubsystem;\t/* Reserved for system use */\n");
+		}
+		else {
+			fprintf(file, "\tmig_server_routine_t \tserver;\t/* Server routine */\n");
+		}
+		fprintf(file, "\tmach_msg_id_t\tstart;\t/* Min routine number */\n");
+		fprintf(file, "\tmach_msg_id_t\tend;\t/* Max routine number + 1 */\n");
+		fprintf(file, "\tunsigned int\tmaxsize;\t/* Max msg size */\n");
+		if (UseRPCTrap) {
+			fprintf(file, "\tvm_address_t\tbase_addr;\t/* Base address */\n");
+			fprintf(file, "\tstruct rpc_routine_descriptor\t/*Array of routine descriptors */\n");
+		}
+		else {
+			fprintf(file, "\tvm_address_t\treserved;\t/* Reserved */\n");
+			fprintf(file, "\tstruct routine_descriptor\t/*Array of routine descriptors */\n");
+		}
+		fprintf(file, "\t\troutine[%d];\n", rtNumber);
+		if (UseRPCTrap) {
+			fprintf(file, "\tstruct rpc_routine_arg_descriptor\t/*Array of arg descriptors */\n");
+			fprintf(file, "\t\targ_descriptor[%d];\n", descr_count);
+		}
+		fprintf(file, "} %s = {\n", ServerSubsys);
+	}
+	else {
+		fprintf(file, "const struct %s %s = {\n", ServerSubsys, ServerSubsys);
+	}
+	if (UseRPCTrap) {
+		fprintf(file, "\t0,\n");
+	}
+	else {
+		fprintf(file, "\t%s_routine,\n", ServerDemux);
+	}
+	fprintf(file, "\t%d,\n", SubsystemBase);
+	fprintf(file, "\t%d,\n", SubsystemBase + rtNumber);
+	fprintf(file, "\t(mach_msg_size_t)sizeof(union __ReplyUnion__%s),\n", ServerSubsys);
+	if (UseRPCTrap) {
+		fprintf(file, "\t(vm_address_t)&%s,\n", ServerSubsys);
+	}
+	else {
+		fprintf(file, "\t(vm_address_t)0,\n");
+	}
+	WriteRoutineEntries(file, stats);
+
+	if (UseRPCTrap)
+		WriteArgDescriptorEntries(file, stats);
+	else
+		fprintf(file, "\n");
+
+	fprintf(file, "};\n\n");
+}
+#if 0
+static void
+WriteArraySizes(file, stats)
+    FILE *file;
+    statement_t *stats;
+{
+	register u_int current = 0;
+	register statement_t *stat;
+
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine)
+		{
+			register routine_t *rt = stat->stRoutine;
+
+			while (current++ < rt->rtNumber)
+				fprintf(file, "\t\t0,\n");
+			fprintf(file, "\t\tsizeof(__Reply__%s_t),\n", rt->rtName);
+		}
+	while (current++ < rtNumber)
+		fprintf(file, "\t\t\t0,\n");
+}
+
+#endif /* NOT_CURRENTLY_USED */
+
+void
+WriteServerRequestUnion(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	fprintf(file, "\n");
+	fprintf(file, "/* union of all requests */\n\n");
+	fprintf(file, "#ifndef __RequestUnion__%s__defined\n", ServerSubsys);
+	fprintf(file, "#define __RequestUnion__%s__defined\n", ServerSubsys);
+	fprintf(file, "union __RequestUnion__%s {\n", ServerSubsys);
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		if (stat->stKind == skRoutine) {
+			register routine_t *rt;
+
+			rt = stat->stRoutine;
+			fprintf(file, "\t__Request__%s_t Request_%s;\n", rt->rtName, rt->rtName);
+		}
+	}
+	fprintf(file, "};\n");
+	fprintf(file, "#endif /* __RequestUnion__%s__defined */\n", ServerSubsys);
+}
+
+void
+WriteServerReplyUnion(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	fprintf(file, "\n");
+	fprintf(file, "/* union of all replies */\n\n");
+	fprintf(file, "#ifndef __ReplyUnion__%s__defined\n", ServerSubsys);
+	fprintf(file, "#define __ReplyUnion__%s__defined\n", ServerSubsys);
+	fprintf(file, "union __ReplyUnion__%s {\n", ServerSubsys);
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		if (stat->stKind == skRoutine) {
+			register routine_t *rt;
+
+			rt = stat->stRoutine;
+			fprintf(file, "\t__Reply__%s_t Reply_%s;\n", rt->rtName, rt->rtName);
+		}
+	}
+	fprintf(file, "};\n");
+	fprintf(file, "#endif /* __RequestUnion__%s__defined */\n", ServerSubsys);
+}
+
+static void
+WriteDispatcher(FILE *file, statement_t *stats)
+{
+	/*
+	 * Write the subsystem stuff.
+	 */
+	fprintf(file, "\n");
+	WriteSubsystem(file, stats);
+
+	/*
+	 * Then, the server routine
+	 */
+	fprintf(file, "mig_external boolean_t %s\n", ServerDemux);
+	if (BeAnsiC) {
+		fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)\n");
+    } else {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)\n");
+		fprintf(file, "#else\n");
+		fprintf(file, "\t(InHeadP, OutHeadP)\n");
+		fprintf(file, "\tmach_msg_header_t *InHeadP, *OutHeadP;\n");
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+	}
+
+	fprintf(file, "{\n");
+	fprintf(file, "\t/*\n");
+	fprintf(file, "\t * typedef struct {\n");
+	fprintf(file, "\t * \tmach_msg_header_t Head;\n");
+	fprintf(file, "\t * \tNDR_record_t NDR;\n");
+	fprintf(file, "\t * \tkern_return_t RetCode;\n");
+	fprintf(file, "\t * } mig_reply_error_t;\n");
+	fprintf(file, "\t */\n");
+	fprintf(file, "\n");
+
+	fprintf(file, "\tregister mig_routine_t routine;\n");
+	fprintf(file, "\n");
+
+	fprintf(file, "\tOutHeadP->msgh_bits = ");
+	fprintf(file, "MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0);\n");
+	fprintf(file, "\tOutHeadP->msgh_remote_port = InHeadP->msgh_reply_port;\n");
+	fprintf(file, "\t/* Minimal size: routine() will update it if different */\n");
+	fprintf(file, "\tOutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);\n");
+	fprintf(file, "\tOutHeadP->msgh_local_port = MACH_PORT_NULL;\n");
+	fprintf(file, "\tOutHeadP->msgh_id = InHeadP->msgh_id + 100;\n");
+	fprintf(file, "\n");
+
+	fprintf(file, "\tif ((InHeadP->msgh_id > %d) || (InHeadP->msgh_id < %d) ||\n", SubsystemBase + rtNumber - 1, SubsystemBase);
+	fprintf(file, "\t    ((routine = %s.routine[InHeadP->msgh_id - %d].stub_routine) == 0)) {\n", ServerSubsys, SubsystemBase);
+	fprintf(file, "\t\t((mig_reply_error_t *)OutHeadP)->NDR = NDR_record;\n");
+	fprintf(file, "\t\t((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID;\n");
+	if (UseEventLogger) {
+		fprintf(file, "#if  MIG_DEBUG\n");
+		fprintf(file, "\t\tLOG_ERRORS(MACH_MSG_LOG_SERVER, MACH_MSG_ERROR_UNKNOWN_ID,\n");
+		fprintf(file, "\t\t\t&InHeadP->msgh_id, __FILE__, __LINE__);\n");
+		fprintf(file, "#endif /* MIG_DEBUG */\n");
+	}
+	fprintf(file, "\t\treturn FALSE;\n");
+	fprintf(file, "\t}\n");
+
+	/* Call appropriate routine */
+	fprintf(file, "\t(*routine) (InHeadP, OutHeadP);\n");
+	fprintf(file, "\treturn TRUE;\n");
+	fprintf(file, "}\n");
+	fprintf(file, "\n");
+
+	/*
+	 * Then, the <subsystem>_server_routine routine
+	 */
+	fprintf(file, "mig_external mig_routine_t %s_routine\n", ServerDemux);
+	if (BeAnsiC) {
+		fprintf(file, "\t(mach_msg_header_t *InHeadP)\n");
+    } else {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "\t(mach_msg_header_t *InHeadP)\n");
+		fprintf(file, "#else\n");
+		fprintf(file, "\t(InHeadP)\n");
+		fprintf(file, "\tmach_msg_header_t *InHeadP;\n");
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+	}
+
+	fprintf(file, "{\n");
+	fprintf(file, "\tregister int msgh_id;\n");
+	fprintf(file, "\n");
+	fprintf(file, "\tmsgh_id = InHeadP->msgh_id - %d;\n", SubsystemBase);
+	fprintf(file, "\n");
+	fprintf(file, "\tif ((msgh_id > %d) || (msgh_id < 0))\n", rtNumber - 1);
+	fprintf(file, "\t\treturn 0;\n");
+	fprintf(file, "\n");
+	fprintf(file, "\treturn %s.routine[msgh_id].stub_routine;\n", ServerSubsys);
+	fprintf(file, "}\n");
+
+	/* symtab */
+
+	if (GenSymTab) {
+		fprintf(file,"\nmig_symtab_t _%sSymTab[] = {\n",SubsystemName);
+		WriteSymTabEntries(file,stats);
+		fprintf(file,"};\n");
+		fprintf(file,"int _%sSymTabBase = %d;\n",SubsystemName,SubsystemBase);
+		fprintf(file,"int _%sSymTabEnd = %d;\n",SubsystemName,SubsystemBase+rtNumber);
+	}
+}
+
+/*
+ *  Returns the return type of the server-side work function.
+ *  Suitable for "extern %s serverfunc()".
+ */
+#if 0
+static const char *
+ServerSideType(rt)
+    routine_t *rt;
+{
+	return rt->rtRetCode->argType->itTransType;
+}
+#endif
+static void
+WriteRetCode(file, ret)
+    FILE *file;
+    register argument_t *ret;
+{
+	register ipc_type_t *it = ret->argType;
+
+	if (akCheck(ret->argKind, akbVarNeeded)) {
+		fprintf(file, "\t%s %s;\n", it->itTransType, ret->argVarName);
+	}
+}
+
+static void
+WriteLocalVarDecl(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	register ipc_type_t *btype = it->itElement;
+
+	if (IS_VARIABLE_SIZED_UNTYPED(it))
+		fprintf(file, "\t%s %s[%d]", btype->itTransType, arg->argVarName, btype->itNumber ? it->itNumber/btype->itNumber : 0);
+	else if (IS_MULTIPLE_KPD(it)) {
+		if (btype->itTransType != strNULL)
+			fprintf(file, "\t%s %s[%d]", btype->itTransType, arg->argVarName, it->itKPD_Number);
+		else
+			/* arrays of ool or oolport */
+			fprintf(file, "\tvoid *%s[%d]", arg->argVarName, it->itKPD_Number);
+	} else
+		fprintf(file, "\t%s %s", it->itTransType, arg->argVarName);
+}
+
+#if 0
+static void
+WriteServerArgDecl(file, arg)
+    FILE *file;
+    argument_t *arg;
+{
+    fprintf(file, "%s %s%s",
+			arg->argType->itTransType,
+			arg->argByReferenceServer ? "*" : "",
+			arg->argVarName);
+}
+#endif
+/*
+ *  Writes the local variable declarations which are always
+ *  present:  InP, OutP, the server-side work function.
+ */
+static void
+WriteVarDecls(FILE *file, routine_t *rt)
+{
+	u_int i;
+
+	fprintf(file, "\tRequest *In0P = (Request *) InHeadP;\n");
+	for (i = 1; i <= rt->rtMaxRequestPos; i++)
+		fprintf(file, "\tRequest *In%dP = NULL;\n", i);
+	fprintf(file, "\tReply *OutP = (Reply *) OutHeadP;\n");
+
+	/* if reply is variable, we may need msgh_size_delta and msgh_size */
+	if (rt->rtNumReplyVar > 1)
+		fprintf(file, "\tunsigned int msgh_size;\n");
+	if (rt->rtMaxReplyPos > 0)
+		fprintf(file, "\tunsigned int msgh_size_delta;\n");
+	if (rt->rtNumReplyVar > 1 || rt->rtMaxReplyPos > 0)
+		fprintf(file, "\n");
+
+	if (rt->rtServerImpl) {
+		fprintf(file, "\tmach_msg_max_trailer_t *TrailerP;\n");
+		fprintf(file, "#if\t__MigTypeCheck\n");
+		fprintf(file, "\tunsigned int trailer_size;\n");
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	fprintf(file, "#ifdef\t__MIG_check__Request__%s_t__defined\n", rt->rtName);
+	fprintf(file, "\tkern_return_t check_result;\n");
+	fprintf(file, "#endif\t/* __MIG_check__Request__%s_t__defined */\n", rt->rtName);
+	fprintf(file, "\n");
+}
+
+static void
+WriteReplyInit(FILE *file, routine_t *rt)
+{
+	fprintf(file, "\n");
+	if  (rt->rtNumReplyVar > 1 || rt->rtMaxReplyPos)
+		/* WritheAdjustMsgSize() has been executed at least once! */
+		fprintf(file, "\tOutP = (Reply *) OutHeadP;\n");
+
+	if (!rt->rtSimpleReply)  /* complex reply message */
+		fprintf(file,
+				"\tOutP->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;\n");
+
+	if (rt->rtNumReplyVar == 0) {
+		fprintf(file, "\tOutP->Head.msgh_size = ");
+		rtMinReplySize(file, rt, "Reply");
+		fprintf(file, ";\n");
+    } else if (rt->rtNumReplyVar > 1)
+		fprintf(file, "\tOutP->Head.msgh_size = msgh_size;\n");
+	/* the case rt->rtNumReplyVar = 1 is taken care of in WriteAdjustMsgSize() */
+}
+
+static void
+WriteRetCArgCheckError(FILE *file, routine_t *rt __unused)
+{
+	fprintf(file, "\tif (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&\n");
+    fprintf(file, "\t    (In0P->Head.msgh_size == sizeof(mig_reply_error_t)))\n");
+	fprintf(file, "\t{\n");
+}
+
+static void
+WriteRetCArgFinishError(FILE *file, routine_t *rt)
+{
+	argument_t *retcode = rt->rtRetCArg;
+
+	fprintf(file, "\treturn;\n");
+	fprintf(file, "\t}\n");
+	retcode->argMsgField = "KERN_SUCCESS";
+}
+
+static void
+WriteCheckHead(FILE *file, routine_t *rt)
+{
+	fprintf(file, "#if\t__MigTypeCheck\n");
+	if (rt->rtNumRequestVar > 0)
+		fprintf(file, "\tmsgh_size = In0P->Head.msgh_size;\n");
+
+	if (rt->rtSimpleRequest) {
+		/* Expecting a simple message. */
+		fprintf(file, "\tif ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||\n");
+		if (rt->rtNumRequestVar > 0) {
+			fprintf(file, "\t    (msgh_size < ");
+			rtMinRequestSize(file, rt, "__Request");
+			fprintf(file, ") ||  (msgh_size > (mach_msg_size_t)sizeof(__Request)))\n");
+		}
+		else
+			fprintf(file, "\t    (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request)))\n");
+	}
+	else {
+		/* Expecting a complex message. */
+
+		fprintf(file, "\tif (");
+		if (rt->rtRetCArg != argNULL)
+			fprintf(file, "(");
+		fprintf(file, "!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||\n");
+		fprintf(file, "\t    (In0P->msgh_body.msgh_descriptor_count != %d) ||\n", rt->rtRequestKPDs);
+		if (rt->rtNumRequestVar > 0) {
+			fprintf(file, "\t    (msgh_size < ");
+			rtMinRequestSize(file, rt, "__Request");
+			fprintf(file, ") ||  (msgh_size > (mach_msg_size_t)sizeof(__Request))");
+		}
+		else
+			fprintf(file, "\t    (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))");
+		if (rt->rtRetCArg == argNULL)
+			fprintf(file, ")\n");
+		else {
+			fprintf(file, ") &&\n");
+			fprintf(file, "\t    ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||\n");
+			fprintf(file, "\t    In0P->Head.msgh_size != sizeof(mig_reply_error_t) ||\n");
+			fprintf(file, "\t    ((mig_reply_error_t *)In0P)->RetCode == KERN_SUCCESS))\n");
+		}
+	}
+	fprintf(file, "\t\treturn MIG_BAD_ARGUMENTS;\n");
+	fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	fprintf(file, "\n");
+}
+
+static void
+WriteRequestNDRConvertIntRepArgCond(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+
+	fprintf(file, "defined(__NDR_convert__int_rep__Request__%s_t__%s__defined)", rt->rtName, arg->argMsgField);
+}
+
+static void
+WriteRequestNDRConvertCharRepArgCond(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+  
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut)
+		fprintf(file, "defined(__NDR_convert__char_rep__Request__%s_t__%s__defined)", rt->rtName, arg->argMsgField);
+	else
+		fprintf(file, "0");
+}
+
+static void
+WriteRequestNDRConvertFloatRepArgCond(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut)
+		fprintf(file, "defined(__NDR_convert__float_rep__Request__%s_t__%s__defined)", rt->rtName, arg->argMsgField);
+	else
+		fprintf(file, "0");
+}
+
+static void
+WriteRequestNDRConvertIntRepArgDecl(FILE *file, argument_t *arg)
+{
+	WriteNDRConvertArgDecl(file, arg, "int_rep", "Request");
+}
+
+static void
+WriteRequestNDRConvertCharRepArgDecl(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut)
+		WriteNDRConvertArgDecl(file, arg, "char_rep", "Request");
+}
+
+static void
+WriteRequestNDRConvertFloatRepArgDecl(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut)
+		WriteNDRConvertArgDecl(file, arg, "float_rep", "Request");
+}
+
+static void
+WriteRequestNDRConvertArgUse(FILE *file, argument_t *arg, const char *convert)
+{
+	routine_t *rt = arg->argRoutine;
+	argument_t *count = arg->argCount;
+	char argname[MAX_STR_LEN];
+
+	if ((akIdent(arg->argKind) == akeCount || akIdent(arg->argKind) == akeCountInOut) &&
+		(arg->argParent && akCheck(arg->argParent->argKind, akbSendNdr)))
+		return;
+
+	if (arg->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR) {
+		if (count && !arg->argSameCount && !strcmp(convert, "int_rep")) {
+			fprintf(file, "#if defined(__NDR_convert__int_rep__Request__%s_t__%s__defined)\n", rt->rtName, count->argMsgField);
+			fprintf(file, "\t\t__NDR_convert__int_rep__Request__%s_t__%s(&In%dP->%s, In%dP->NDR.int_rep);\n", rt->rtName, count->argMsgField, count->argRequestPos, count->argMsgField, count->argRequestPos);
+			fprintf(file, "#endif\t/* __NDR_convert__int_rep__Request__%s_t__%s__defined */\n", rt->rtName, count->argMsgField);
+		}
+
+		sprintf(argname, "(%s)(In%dP->%s.address)", FetchServerType(arg->argType), arg->argRequestPos, arg->argMsgField);
+	}
+	else {
+		sprintf(argname, "&In%dP->%s", arg->argRequestPos, arg->argMsgField);
+	}
+
+	fprintf(file, "#if defined(__NDR_convert__%s__Request__%s_t__%s__defined)\n", convert, rt->rtName, arg->argMsgField);
+	fprintf(file, "\t\t__NDR_convert__%s__Request__%s_t__%s(%s, In0P->NDR.%s", convert, rt->rtName, arg->argMsgField, argname, convert);
+	if (count)
+		fprintf(file, ", In%dP->%s", count->argRequestPos, count->argMsgField);
+	fprintf(file, ");\n");
+	fprintf(file, "#endif\t/* __NDR_convert__%s__Request__%s_t__%s__defined */\n", convert, rt->rtName, arg->argMsgField);
+}
+
+static void
+WriteRequestNDRConvertIntRepOneArgUse(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+
+	fprintf(file, "#if defined(__NDR_convert__int_rep__Request__%s_t__%s__defined)\n", rt->rtName, arg->argMsgField);
+	fprintf(file, "\tif (In0P->NDR.int_rep != NDR_record.int_rep)\n");
+	fprintf(file, "\t\t__NDR_convert__int_rep__Request__%s_t__%s(&In%dP->%s, In%dP->NDR.int_rep);\n", rt->rtName, arg->argMsgField, arg->argRequestPos, arg->argMsgField, arg->argRequestPos);
+	fprintf(file, "#endif\t/* __NDR_convert__int_rep__Request__%s_t__%s__defined */\n", rt->rtName, arg->argMsgField);
+}
+
+static void
+WriteRequestNDRConvertIntRepArgUse(FILE *file, argument_t *arg)
+{
+	WriteRequestNDRConvertArgUse(file, arg, "int_rep");
+}
+
+static void
+WriteRequestNDRConvertCharRepArgUse(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut)
+		WriteRequestNDRConvertArgUse(file, arg, "char_rep");
+}
+
+static void
+WriteRequestNDRConvertFloatRepArgUse(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) != akeCountInOut)
+		WriteRequestNDRConvertArgUse(file, arg, "float_rep");
+}
+
+static void
+WriteCalcArgSize(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argType;
+
+	if (PackMsg == FALSE) {
+		fprintf(file, "%d", ptype->itTypeSize + ptype->itPadSize);
+		return;
+	}
+
+	if (IS_OPTIONAL_NATIVE(ptype))
+        fprintf(file, "(In%dP->__Present__%s ? _WALIGNSZ_(%s) : 0)" ,
+				arg->argRequestPos, arg->argMsgField, ptype->itServerType);
+    else
+    {
+		register ipc_type_t *btype = ptype->itElement;
+		argument_t *count = arg->argCount;
+		int multiplier = btype->itTypeSize;
+
+		if (btype->itTypeSize % itWordAlign != 0)
+			fprintf(file, "_WALIGN_");
+		fprintf(file, "(");
+
+		if (multiplier > 1)
+			fprintf(file, "%d * ", multiplier);
+		fprintf(file, "In%dP->%s", count->argRequestPos, count->argMsgField);
+		fprintf(file, ")");
+	}
+}
+
+static void
+WriteCheckArgSize(FILE *file, routine_t *rt, argument_t *arg, const char *comparator)
+{
+	register ipc_type_t *ptype = arg->argType;
+
+
+	fprintf(file, "\tif (((msgh_size - ");
+	rtMinRequestSize(file, rt, "__Request");
+	fprintf(file, ") ");
+	if (PackMsg == FALSE) {
+		fprintf(file, "%s %d)", comparator, ptype->itTypeSize + ptype->itPadSize);
+	} else if (IS_OPTIONAL_NATIVE(ptype)) {
+		fprintf(file, "%s (In%dP->__Present__%s ? _WALIGNSZ_(%s) : 0))" , comparator, arg->argRequestPos, arg->argMsgField, ptype->itServerType);
+	} else {
+		register ipc_type_t *btype = ptype->itElement;
+		argument_t *count = arg->argCount;
+		int multiplier = btype->itTypeSize;
+
+		if (multiplier > 1)
+			fprintf(file, "/ %d ", multiplier);
+		fprintf(file, "< In%dP->%s) ||\n", count->argRequestPos, count->argMsgField);
+		fprintf(file, "\t    (msgh_size %s ", comparator);
+		rtMinRequestSize(file, rt, "__Request");
+		fprintf(file, " + ");
+		WriteCalcArgSize(file, arg);
+		fprintf(file, ")");
+	}
+	fprintf(file, ")\n\t\treturn MIG_BAD_ARGUMENTS;\n");
+}
+
+static void
+WriteCheckMsgSize(FILE *file, register argument_t *arg)
+{
+	register routine_t *rt = arg->argRoutine;
+
+	if (arg->argCount && !arg->argSameCount)
+		WriteRequestNDRConvertIntRepOneArgUse(file, arg->argCount);
+	if (arg->argRequestPos == rt->rtMaxRequestPos)  {
+		fprintf(file, "#if\t__MigTypeCheck\n");
+
+		/* verify that the user-code-provided count does not exceed the maximum count allowed by the type. */
+		fprintf(file, "\t" "if ( In%dP->%s > %d )\n", arg->argCount->argRequestPos, arg->argCount->argMsgField, arg->argType->itNumber);
+		fputs("\t\t" "return MIG_BAD_ARGUMENTS;\n", file);
+		/* ...end... */
+
+		WriteCheckArgSize(file, rt, arg, "!=");
+
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	else {
+		/* If there aren't any more variable-sized arguments after this,
+		   then we must check for exact msg-size and we don't need to
+		   update msgh_size. */
+
+		boolean_t LastVarArg = arg->argRequestPos+1 == rt->rtNumRequestVar;
+
+		/* calculate the actual size in bytes of the data field.  note
+		   that this quantity must be a multiple of four.  hence, if
+		   the base type size isn't a multiple of four, we have to
+		   round up.  note also that btype->itNumber must
+		   divide btype->itTypeSize (see itCalculateSizeInfo). */
+
+		fprintf(file, "\tmsgh_size_delta = ");
+		WriteCalcArgSize(file, arg);
+		fprintf(file, ";\n");
+		fprintf(file, "#if\t__MigTypeCheck\n");
+
+		/* verify that the user-code-provided count does not exceed the maximum count allowed by the type. */
+		fprintf(file, "\t" "if ( In%dP->%s > %d )\n", arg->argCount->argRequestPos, arg->argCount->argMsgField, arg->argType->itNumber);
+		fputs("\t\t" "return MIG_BAD_ARGUMENTS;\n", file);
+		/* ...end... */
+
+		/* Don't decrement msgh_size until we've checked that
+		   it won't underflow. */
+		WriteCheckArgSize(file, rt, arg, LastVarArg ? "!=" : "<");
+
+		if (!LastVarArg)
+			fprintf(file, "\tmsgh_size -= msgh_size_delta;\n");
+
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	fprintf(file, "\n");
+}
+
+static char *
+InArgMsgField(register argument_t *arg,  const char *str)
+{
+	static char buffer[MAX_STR_LEN];
+	char who[20] = {0};
+
+	/*
+	 * Inside the kernel, the request and reply port fields
+	 * really hold ipc_port_t values, not mach_port_t values.
+	 * Hence we must cast the values.
+	 */
+
+	if (!(arg->argFlags & flRetCode)) {
+		if (akCheck(arg->argKind, akbServerImplicit))
+			sprintf(who, "TrailerP->");
+		else
+			sprintf(who, "In%dP->", arg->argRequestPos);
+	}
+
+#ifdef MIG_KERNEL_PORT_CONVERSION
+	if (IsKernelServer &&
+		((akIdent(arg->argKind) == akeRequestPort) ||
+		 (akIdent(arg->argKind) == akeReplyPort)))
+		sprintf(buffer, "(ipc_port_t) %s%s%s", who, str, (arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField);
+	else
+#endif
+		sprintf(buffer, "%s%s%s", who, str, (arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField);
+
+	return buffer;
+}
+
+static void
+WriteExtractArgValue(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	string_t recast;
+
+#ifdef MIG_KERNEL_PORT_CONVERSION
+	if (IsKernelServer && it->itPortType && streql(it->itServerType, "ipc_port_t")
+		&& akIdent(arg->argKind) != akeRequestPort
+		&& akIdent(arg->argKind) != akeReplyPort)
+		recast = "(mach_port_t)";
+	else
+#endif
+		recast = "";
+	if (it->itInTrans != strNULL)
+		WriteCopyType(file, it, "%s", "/* %s */ %s(%s%s)", arg->argVarName, it->itInTrans, recast, InArgMsgField(arg, ""));
+	else
+		WriteCopyType(file, it, "%s", "/* %s */ %s%s", arg->argVarName, recast, InArgMsgField(arg, ""));
+
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_Extract discipline for Port types.
+ */
+static void
+WriteExtractKPD_port(FILE *file,  register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *recast = "";
+
+	WriteKPD_Iterator(file, TRUE, it->itVarArray, arg, FALSE);
+	/* translation function do not apply to complex types */
+#ifdef MIG_KERNEL_PORT_CONVERSION
+	if (IsKernelServer)
+		recast = "(mach_port_t)";
+#endif
+	fprintf(file, "\t\t%s[i] = %sptr->name;\n", arg->argVarName, recast);
+	fprintf(file, "\t}\n");
+}
+
+/*
+ * argKPD_Extract discipline for out-of-line types.
+ */
+static void
+WriteExtractKPD_ool(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	WriteKPD_Iterator(file, TRUE, it->itVarArray, arg, FALSE);
+	fprintf(file, "\t\t%s[i] = ptr->address;\n", arg->argVarName);
+	fprintf(file, "\t}\n");
+}
+
+/*
+ * argKPD_Extract discipline for out-of-line Port types.
+ */
+static void
+WriteExtractKPD_oolport(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	WriteKPD_Iterator(file, TRUE, it->itVarArray, arg, FALSE);
+	fprintf(file, "\t\t%s[i] = ptr->address;\n", arg->argVarName);
+	fprintf(file, "\t}\n");
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbSendRcv)) {
+		register argument_t *poly = arg->argPoly;
+        register const char *pref = poly->argByReferenceServer ? "*" : "";
+
+        fprintf(file, "\t%s%s = In%dP->%s[0].disposition;\n",
+				pref, poly->argVarName, arg->argRequestPos, arg->argMsgField);
+	}
+}
+
+static void
+WriteInitializeCount(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argParent->argType;
+	register ipc_type_t *btype = ptype->itElement;
+	identifier_t newstr;
+
+	/*
+	 * Initialize 'count' argument for variable-length inline OUT parameter
+	 * with maximum allowed number of elements.
+	 */
+
+	if (akCheck(arg->argKind, akbVarNeeded))
+		newstr = arg->argMsgField;
+	else
+		newstr = (identifier_t)strconcat("OutP->", arg->argMsgField);
+
+	fprintf(file, "\t%s = ", newstr);
+	if (IS_MULTIPLE_KPD(ptype))
+		fprintf(file, "%d;\n", ptype->itKPD_Number);
+	else
+		fprintf(file, "%d;\n", btype->itNumber? ptype->itNumber/btype->itNumber : 0);
+
+	/*
+	 * If the user passed in a count, then we use the minimum.
+	 * We can't let the user completely override our maximum,
+	 * or the user might convince the server to overwrite the buffer.
+	 */
+
+	if (arg->argCInOut != argNULL) {
+		const char *msgfield = InArgMsgField(arg->argCInOut, "");
+
+		fprintf(file, "\tif (%s < %s)\n", msgfield, newstr);
+		fprintf(file, "\t\t%s = %s;\n", newstr, msgfield);
+	}
+
+	fprintf(file, "\n");
+}
+
+static void
+WriteAdjustRequestMsgPtr(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argType;
+
+	if (PackMsg == FALSE) {
+		fprintf(file, "\t*In%dPP = In%dP = (__Request *) ((pointer_t) In%dP);\n\n", arg->argRequestPos+1, arg->argRequestPos+1, arg->argRequestPos);
+		return;
+	}
+
+	fprintf(file, "\t*In%dPP = In%dP = (__Request *) ((pointer_t) In%dP + msgh_size_delta - ", arg->argRequestPos+1, arg->argRequestPos+1, arg->argRequestPos);
+	if (IS_OPTIONAL_NATIVE(ptype))
+		fprintf(file, "_WALIGNSZ_(%s)", ptype->itUserType);
+	else
+		fprintf(file, "%d", ptype->itTypeSize + ptype->itPadSize);
+	fprintf(file, ");\n\n");
+}
+
+static void
+WriteCheckRequestTrailerArgs(FILE *file, routine_t *rt)
+{
+	register argument_t *arg;
+
+	if (rt->rtServerImpl)
+		WriteCheckTrailerHead(file, rt, FALSE);
+
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		if (akCheck(arg->argKind, akbServerImplicit))
+			WriteCheckTrailerSize(file, FALSE, arg);
+	}
+}
+
+static void
+WriteExtractArg(FILE *file, register argument_t *arg)
+{
+	if (akCheckAll(arg->argKind, akbSendRcv|akbVarNeeded)) {
+		if (akCheck(arg->argKind, akbSendKPD))
+			(*arg->argKPD_Extract)(file, arg);
+		else
+			WriteExtractArgValue(file, arg);
+	}
+
+	if ((akIdent(arg->argKind) == akeCount) &&
+		akCheck(arg->argKind, akbReturnSnd)) {
+
+		register ipc_type_t *ptype = arg->argParent->argType;
+		/*
+		 * the count will be initialized to 0 in the case of
+		 * unbounded arrays (MigInLine = TRUE): this is because
+		 * the old interface used to pass to the target procedure
+		 * the maximum in-line size (it was 2048 bytes)
+		 */
+		if (IS_VARIABLE_SIZED_UNTYPED(ptype) ||
+			IS_MIG_INLINE_EMUL(ptype) ||
+			(IS_MULTIPLE_KPD(ptype) && ptype->itVarArray))
+			WriteInitializeCount(file, arg);
+	}
+}
+
+static void
+WriteServerCallArg(FILE *file, register argument_t *arg)
+{
+	ipc_type_t *it = arg->argType;
+	boolean_t NeedClose = FALSE;
+	string_t  at = (arg->argByReferenceServer ||
+					it->itNativePointer) ? "&" : "";
+	string_t  star = (arg->argByReferenceServer) ? " *" : "";
+	string_t  msgfield =
+		(arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField;
+
+	if (BeVerbose)
+		fprintf(file, "\n/* begin WriteServerCallArg */\n");
+	if ((it->itInTrans != strNULL) &&
+		akCheck(arg->argKind, akbSendRcv) &&
+		!akCheck(arg->argKind, akbVarNeeded)) {
+		fprintf(file, "%s%s(", at, it->itInTrans);
+		NeedClose = TRUE;
+	}
+
+	if (akCheckAll(arg->argKind, akbVarNeeded|akbServerArg)) {
+		fprintf(file, "%s%s", at, arg->argVarName);
+	} else if (akCheckAll(arg->argKind, akbSendRcv|akbSendKPD)) {
+		if (!it->itInLine)
+			/* recast the void *, although it is not necessary */
+			fprintf(file, "(%s%s)%s(%s)", it->itTransType, star, at, InArgMsgField(arg, ""));
+		else
+#ifdef MIG_KERNEL_PORT_CONVERSION
+			if (IsKernelServer && streql(it->itServerType, "ipc_port_t"))
+				/* recast the port to the kernel internal form value */
+				fprintf(file, "(ipc_port_t%s)%s(%s)", star, at, InArgMsgField(arg, ""));
+			else
+#endif
+			{
+				fprintf(file, "%s%s", at, InArgMsgField(arg, ""));
+			}
+	}
+	else if (akCheck(arg->argKind, akbSendRcv)) {
+		if (IS_OPTIONAL_NATIVE(it)) {
+			fprintf(file, "(%s ? ", InArgMsgField(arg, "__Present__"));
+			fprintf(file, "%s%s.__Real__%s : %s)", at, InArgMsgField(arg, ""), arg->argMsgField, it->itBadValue);
+		}
+		else {
+			fprintf(file, "%s%s", at, InArgMsgField(arg, ""));
+		}
+	}
+	else if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnKPD)) {
+		if (!it->itInLine)
+			/* recast the void *, although it is not necessary */
+			fprintf(file, "(%s%s)%s(OutP->%s)", it->itTransType, star, at, msgfield);
+		else
+#ifdef MIG_KERNEL_PORT_CONVERSION
+			if (IsKernelServer && streql(it->itServerType, "ipc_port_t"))
+				/* recast the port to the kernel internal form value */
+				fprintf(file, "(mach_port_t%s)%s(OutP->%s)", star, at, msgfield);
+			else
+#endif
+				fprintf(file, "%sOutP->%s", at, msgfield);
+
+	}
+	else  if (akCheck(arg->argKind, akbReturnSnd))
+		fprintf(file, "%sOutP->%s", at, msgfield);
+
+	if (NeedClose)
+		fprintf(file, ")");
+	if (BeVerbose)
+		fprintf(file, "\n/* end WriteServerCallArg */\n");
+}
+
+/*
+ * Shrunk version of WriteServerCallArg, to implement the RetCode functionality:
+ * we have received a mig_reply_error_t, therefore we want to call the target
+ * routine with all 0s except for the error code (and the implicit data).
+ * We know that we are a SimpleRoutine.
+ */
+static void
+WriteConditionalCallArg(FILE *file, register argument_t *arg)
+{
+	ipc_type_t *it = arg->argType;
+	boolean_t NeedClose = FALSE;
+
+	if (BeVerbose)
+		fprintf(file, "/* begin WriteConditionalCallArg */\n");
+	if ((it->itInTrans != strNULL) &&
+		akCheck(arg->argKind, akbSendRcv) &&
+		!akCheck(arg->argKind, akbVarNeeded))
+    {
+		fprintf(file, "%s(", it->itInTrans);
+		NeedClose = TRUE;
+	}
+
+	if (akCheck(arg->argKind, akbSendRcv)) {
+		if (akIdent(arg->argKind) == akeRequestPort ||
+			akCheck(arg->argKind, akbServerImplicit))
+			fprintf(file, "%s", InArgMsgField(arg, ""));
+		else if (akIdent(arg->argKind) == akeRetCode)
+			fprintf(file, "((mig_reply_error_t *)In0P)->RetCode");
+		else
+			fprintf(file, "(%s)(0)", it->itTransType);
+	}
+
+	if (NeedClose)
+		fprintf(file, ")");
+	if (BeVerbose)
+		fprintf(file, "/* end WriteConditionalCallArg */\n");
+}
+
+static void
+WriteDestroyArg(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	/*
+	 * Deallocate IN/INOUT out-of-line args if specified by "auto" flag.
+	 *
+	 * We also have to deallocate in the cases where the target routine
+	 * is given a itInLine semantic whereas the underlying transmission
+	 * was out-of-line
+	 */
+	if ((argIsIn(arg) && akCheck(arg->argKind, akbSendKPD|akbReturnKPD) &&
+		 arg->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR &&
+		 (arg->argFlags & flAuto))
+		||
+		IS_MIG_INLINE_EMUL(it)
+		) {
+		/*
+		 * Deallocate only if out-of-line.
+		 */
+		argument_t *count = arg->argCount;
+		ipc_type_t *btype = it->itElement;
+		int multiplier = btype->itNumber ? btype->itSize / (8 * btype->itNumber) : 0;
+
+		if (IsKernelServer) {
+			fprintf(file, "#if __MigKernelSpecificCode\n");
+			fprintf(file, "\tvm_map_copy_discard(%s);\n", InArgMsgField(arg, ""));
+			fprintf(file, "#else\n");
+		}
+		fprintf(file, "\tmig_deallocate((vm_offset_t) %s, ", InArgMsgField(arg, ""));
+		if (it->itVarArray) {
+			if (multiplier > 1)
+				fprintf(file, "%d * ", multiplier);
+			fprintf(file, "%s);\n", InArgMsgField(count, ""));
+	    } else
+			fprintf(file, "%d);\n", (it->itNumber * it->itSize + 7) / 8);
+		if (IsKernelServer) {
+			fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+		}
+		fprintf(file, "\t%s = (void *) 0;\n", InArgMsgField(arg, ""));
+		fprintf(file, "\tIn%dP->%s.%s = (mach_msg_size_t) 0;\n", arg->argRequestPos, arg->argMsgField, (RPCPortArray(arg) ? "count" : "size"));
+	}
+	else {
+		if (akCheck(arg->argKind, akbVarNeeded))
+			fprintf(file, "\t%s(%s);\n", it->itDestructor, arg->argVarName);
+		else
+			fprintf(file, "\t%s(%s);\n", it->itDestructor, InArgMsgField(arg, ""));
+	}
+}
+
+static void
+WriteDestroyPortArg(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	/*
+	 * If a translated port argument occurs in the body of a request
+	 * message, and the message is successfully processed, then the
+	 * port right should be deallocated.  However, the called function
+	 * didn't see the port right; it saw the translation.  So we have
+	 * to release the port right for it.
+	 *
+	 *  The test over it->itInTrans will exclude any complex type
+	 *  made out of ports
+	 */
+	if ((it->itInTrans != strNULL) &&
+		(it->itOutName == MACH_MSG_TYPE_PORT_SEND)) {
+		fprintf(file, "\n");
+		fprintf(file, "\tif (IP_VALID((ipc_port_t)%s))\n", InArgMsgField(arg, ""));
+		fprintf(file, "\t\tipc_port_release_send((ipc_port_t)%s);\n", InArgMsgField(arg, ""));
+	}
+}
+
+/*
+ * Check whether WriteDestroyPortArg would generate any code for arg.
+ */
+static boolean_t
+CheckDestroyPortArg(argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	if ((it->itInTrans != strNULL) &&
+		(it->itOutName == MACH_MSG_TYPE_PORT_SEND))
+    {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+WriteServerCall(FILE *file, routine_t *rt,  void (*func)())
+{
+	argument_t *arg = rt->rtRetCode;
+	ipc_type_t *it = arg->argType;
+	boolean_t NeedClose = FALSE;
+
+	fprintf(file, "\t");
+	if (akCheck(arg->argKind, akbVarNeeded))
+		fprintf(file, "%s = ", arg->argMsgField);
+	else
+		fprintf(file, "OutP->%s = ", arg->argMsgField);
+	if (it->itOutTrans != strNULL) {
+		fprintf(file, "%s(", it->itOutTrans);
+		NeedClose = TRUE;
+	}
+	fprintf(file, "%s(", rt->rtServerName);
+	if (BeVerbose)
+		fprintf(file, "\n/* before WriteServerCall's WriteList func=%p mask=%x */\n", func, akbServerArg);
+	WriteList(file, rt->rtArgs, func, akbServerArg, ", ", "");
+	if (BeVerbose)
+		fprintf(file, "\n/* after WriteServerCall's WriteList */\n");
+	if (NeedClose)
+		fprintf(file, ")");
+	fprintf(file, ");\n");
+}
+
+static void
+WriteCheckReturnValue(FILE *file, register routine_t *rt)
+{
+	argument_t *arg = rt->rtRetCode;
+	char string[MAX_STR_LEN];
+
+	if (akCheck(arg->argKind, akbVarNeeded))
+		sprintf(string, "%s", arg->argMsgField);
+	else
+		sprintf(string, "OutP->%s", arg->argMsgField);
+	fprintf(file, "\tif (%s != KERN_SUCCESS) {\n", string);
+	fprintf(file, "\t\tMIG_RETURN_ERROR(OutP, %s);\n", string);
+	fprintf(file, "\t}\n");
+}
+
+/*
+ * WriteInitKPD_port, WriteInitKPD_ool, WriteInitKPD_oolport
+ * initializes the OutP KPD fields (this job cannot be done once
+ * the target routine has been called, otherwise informations
+ * would be lost)
+ */
+/*
+ * argKPD_Init discipline for Port types.
+ */
+static void
+WriteInitKPD_port(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *subindex = "";
+	boolean_t close = FALSE;
+	char firststring[MAX_STR_LEN];
+	char string[MAX_STR_LEN];
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, arg, TRUE);
+		(void)sprintf(firststring, "\t*ptr");
+		(void)sprintf(string, "\tptr->");
+		subindex = "[i]";
+		close = TRUE;
+    } else {
+		(void)sprintf(firststring, "OutP->%s", arg->argMsgField);
+		(void)sprintf(string, "OutP->%s.", arg->argMsgField);
+	}
+
+	fprintf(file, "#if\tUseStaticTemplates\n");
+	fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName);
+	fprintf(file, "#else\t/* UseStaticTemplates */\n");
+	if (IS_MULTIPLE_KPD(it) && it->itVarArray)
+		fprintf(file, "\t%sname = MACH_PORT_NULL;\n", string);
+	if (arg->argPoly == argNULL) {
+		if (IsKernelServer) {
+			fprintf(file, "#if __MigKernelSpecificCode\n");
+			fprintf(file, "\t%sdisposition = %s;\n", string, it->itOutNameStr);
+			fprintf(file, "#else\n");
+		}
+		fprintf(file, "\t%sdisposition = %s;\n", string, it->itInNameStr);
+		if (IsKernelServer)
+			fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+	}
+	fprintf(file, "\t%stype = MACH_MSG_PORT_DESCRIPTOR;\n", string);
+	fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+	if (close)
+		fprintf(file, "\t    }\n\t}\n");
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_Init discipline for out-of-line types.
+ */
+static void
+WriteInitKPD_ool(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	char firststring[MAX_STR_LEN];
+	char string[MAX_STR_LEN];
+	boolean_t VarArray;
+	u_int howmany, howbig;
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, arg, TRUE);
+		(void)sprintf(firststring, "\t*ptr");
+		(void)sprintf(string, "\tptr->");
+		VarArray = it->itElement->itVarArray;
+		howmany = it->itElement->itNumber;
+		howbig = it->itElement->itSize;
+    } else {
+		(void)sprintf(firststring, "OutP->%s", arg->argMsgField);
+		(void)sprintf(string, "OutP->%s.", arg->argMsgField);
+		VarArray = it->itVarArray;
+		howmany = it->itNumber;
+		howbig = it->itSize;
+	}
+
+	fprintf(file, "#if\tUseStaticTemplates\n");
+	fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName);
+	fprintf(file, "#else\t/* UseStaticTemplates */\n");
+	if (!VarArray)
+        fprintf(file, "\t%ssize = %d;\n", string, 
+				(howmany * howbig + 7)/8);
+	if (arg->argDeallocate != d_MAYBE)
+		fprintf(file, "\t%sdeallocate =  %s;\n", string,
+				(arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
+    fprintf(file, "\t%scopy = %s;\n", string, 
+			(arg->argFlags & flPhysicalCopy) ? "MACH_MSG_PHYSICAL_COPY" : "MACH_MSG_VIRTUAL_COPY");
+#ifdef ALIGNMENT
+    fprintf(file, "\t%salignment = MACH_MSG_ALIGN_%d;\n", string, arg->argMsgField,
+			(howbig < 8) ? 1 : howbig / 8);
+#endif
+	fprintf(file, "\t%stype = MACH_MSG_OOL_DESCRIPTOR;\n", string);
+	fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+
+	if (IS_MULTIPLE_KPD(it))
+		fprintf(file, "\t    }\n\t}\n");
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_Init discipline for out-of-line Port types.
+ */
+static void
+WriteInitKPD_oolport(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	boolean_t VarArray;
+	ipc_type_t *howit;
+	u_int howmany;
+	char firststring[MAX_STR_LEN];
+	char string[MAX_STR_LEN];
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, arg, TRUE);
+		(void)sprintf(firststring, "\t*ptr");
+		(void)sprintf(string, "\tptr->");
+		VarArray = it->itElement->itVarArray;
+		howmany = it->itElement->itNumber;
+		howit = it->itElement;
+    } else {
+		(void)sprintf(firststring, "OutP->%s", arg->argMsgField);
+		(void)sprintf(string, "OutP->%s.", arg->argMsgField);
+		VarArray = it->itVarArray;
+		howmany = it->itNumber;
+		howit = it;
+	}
+
+	fprintf(file, "#if\tUseStaticTemplates\n");
+	fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName);
+	fprintf(file, "#else\t/* UseStaticTemplates */\n");
+
+	if (!VarArray)
+		fprintf(file, "\t%scount = %d;\n", string, howmany);
+	if (arg->argPoly == argNULL) {
+		if (IsKernelServer) {
+			fprintf(file, "#if\t__MigKernelSpecificCode\n");
+			fprintf(file, "\t%sdisposition = %s;\n", string, howit->itOutNameStr);
+			fprintf(file, "#else\n");
+		}
+		fprintf(file, "\t%sdisposition = %s;\n", string, howit->itInNameStr);
+		if (IsKernelServer)
+			fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+	}
+	if (arg->argDeallocate != d_MAYBE)
+        fprintf(file, "\t%sdeallocate =  %s;\n", string,
+				(arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
+	fprintf(file, "\t%stype = MACH_MSG_OOL_PORTS_DESCRIPTOR;\n", string);
+	fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+
+	if (IS_MULTIPLE_KPD(it))
+		fprintf(file, "\t    }\n\t}\n");
+	fprintf(file, "\n");
+}
+
+static void
+WriteInitKPDValue(FILE *file, register argument_t *arg)
+{
+	(*arg->argKPD_Init)(file, arg);
+}
+
+static void
+WriteAdjustMsgCircular(FILE *file, register argument_t *arg)
+{
+	fprintf(file, "\n");
+
+	fprintf(file,"#if\t__MigKernelSpecificCode\n");
+	if (arg->argType->itOutName == MACH_MSG_TYPE_POLYMORPHIC)
+		fprintf(file, "\tif (%s == MACH_MSG_TYPE_PORT_RECEIVE)\n",
+				arg->argPoly->argVarName);
+
+	/*
+	 * The carried port right can be accessed in OutP->XXXX.  Normally
+	 * the server function stuffs it directly there.  If it is InOut,
+	 * then it has already been copied into the reply message.
+	 * If the server function deposited it into a variable (perhaps
+	 * because the reply message is variable-sized) then it has already
+	 * been copied into the reply message.
+	 *
+	 *  The old MiG does not check for circularity in the case of
+	 *  array of ports. So do I ...
+	 */
+
+	fprintf(file, "\t  if (IP_VALID((ipc_port_t) In0P->Head.msgh_reply_port) &&\n");
+	fprintf(file, "\t    IP_VALID((ipc_port_t) OutP->%s.name) &&\n", arg->argMsgField);
+	fprintf(file, "\t    ipc_port_check_circularity((ipc_port_t) OutP->%s.name, (ipc_port_t) In0P->Head.msgh_reply_port))\n", arg->argMsgField);
+	fprintf(file, "\t\tOutP->Head.msgh_bits |= MACH_MSGH_BITS_CIRCULAR;\n");
+	fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+}
+
+/*
+ * argKPD_Pack discipline for Port types.
+ */
+static void
+WriteKPD_port(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *subindex = "";
+    const char *recast = "";
+	boolean_t close = FALSE;
+	char string[MAX_STR_LEN];
+	ipc_type_t *real_it;
+
+	if (akCheck(arg->argKind, akbVarNeeded)) {
+		if (IS_MULTIPLE_KPD(it)) {
+			WriteKPD_Iterator(file, FALSE, it->itVarArray, arg, TRUE);
+			(void)sprintf(string, "\tptr->");
+			subindex = "[i]";
+			close = TRUE;
+			real_it = it->itElement;
+		} else {
+			(void)sprintf(string, "OutP->%s.", arg->argMsgField);
+			real_it = it;
+		}
+#ifdef MIG_KERNEL_PORT_CONVERSIONS
+		if (IsKernelServer && streql(real_it->itTransType, "ipc_port_t"))
+			recast = "(mach_port_t)";
+#endif
+
+		if (it->itOutTrans != strNULL && !close)
+			fprintf(file, "\t%sname = (mach_port_t)%s(%s);\n", string, it->itOutTrans, arg->argVarName);
+		else
+			fprintf(file, "\t%sname = %s%s%s;\n", string, recast, arg->argVarName, subindex);
+		if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbReturnSnd)) {
+			register argument_t *poly = arg->argPoly;
+
+			if  (akCheck(arg->argPoly->argKind, akbVarNeeded))
+				fprintf(file, "\t%sdisposition = %s;\n", string, poly->argVarName);
+			else if (close)
+				fprintf(file, "\t%sdisposition = OutP->%s;\n", string, poly->argSuffix);
+		}
+		if (close)
+			fprintf(file, "\t    }\n\t}\n");
+		fprintf(file, "\n");
+	}
+	else  if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbReturnSnd|akbVarNeeded))
+		fprintf(file, "\tOutP->%s.disposition = %s;\n", arg->argMsgField, arg->argPoly->argVarName);
+	/*
+	 * If this is a KernelServer, and the reply message contains
+	 * a receive right, we must check for the possibility of a
+	 * port/message circularity.  If queueing the reply message
+	 * would cause a circularity, we mark the reply message
+	 * with the circular bit.
+	 */
+	if (IsKernelServer && !(IS_MULTIPLE_KPD(it)) &&
+		((arg->argType->itOutName == MACH_MSG_TYPE_PORT_RECEIVE) ||
+		 (arg->argType->itOutName == MACH_MSG_TYPE_POLYMORPHIC)))
+		WriteAdjustMsgCircular(file, arg);
+}
+
+/*
+ * argKPD_Pack discipline for out-of-line types.
+ */
+static void
+WriteKPD_ool(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	char string[MAX_STR_LEN];
+	boolean_t VarArray;
+	argument_t *count;
+	u_int howbig;
+    const char *subindex;
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, it->itVarArray, arg, TRUE);
+		(void)sprintf(string, "\tptr->");
+		VarArray = it->itElement->itVarArray;
+		count = arg->argSubCount;
+		howbig = it->itElement->itSize;
+		subindex = "[i]";
+    } else {
+		(void)sprintf(string, "OutP->%s.", arg->argMsgField);
+		VarArray = it->itVarArray;
+		count = arg->argCount;
+		howbig = it->itSize;
+		subindex = "";
+	}
+
+	if (akCheck(arg->argKind, akbVarNeeded))
+		fprintf(file, "\t%saddress = (void *)%s%s;\n", string, 
+				arg->argMsgField, subindex);
+	if (arg->argDealloc != argNULL)
+		if (akCheck(arg->argDealloc->argKind, akbVarNeeded) || IS_MULTIPLE_KPD(it))
+			fprintf(file, "\t%sdeallocate = %s;\n", string, arg->argDealloc->argVarName);
+	if (VarArray) {
+		fprintf(file, "\t%ssize = ", string);
+		if (akCheck(count->argKind, akbVarNeeded))
+			fprintf(file, "%s%s", count->argName, subindex);
+		else
+			fprintf(file, "OutP->%s%s", count->argMsgField, subindex);
+
+		if (count->argMultiplier > 1 || howbig > 8)
+			fprintf(file, " * %d;\n", count->argMultiplier * howbig / 8);
+		else
+			fprintf(file, ";\n");
+	}
+
+	if (IS_MULTIPLE_KPD(it)) {
+		fprintf(file, "\t    }\n");
+		if (it->itVarArray && !it->itElement->itVarArray) {
+			fprintf(file, "\t    for (i = j; i < %d; ptr++, i++)\n", it->itKPD_Number);
+			/* since subordinate arrays aren't variable, they are initialized from template:
+			   here we must no-op 'em */
+			fprintf(file, "\t\tptr->size = 0;\n");
+		}
+		fprintf(file, "\t}\n");
+	}
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_Pack discipline for out-of-line Port types.
+ */
+static void
+WriteKPD_oolport(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	boolean_t VarArray;
+	argument_t *count;
+    const char *subindex;
+	char string[MAX_STR_LEN];
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, it->itVarArray, arg, TRUE);
+		(void)sprintf(string, "\tptr->");
+		VarArray = it->itElement->itVarArray;
+		count = arg->argSubCount;
+		subindex = "[i]";
+    } else {
+		(void)sprintf(string, "OutP->%s.", arg->argMsgField);
+		VarArray = it->itVarArray;
+		count = arg->argCount;
+		subindex = "";
+	}
+
+	if (akCheck(arg->argKind, akbVarNeeded))
+        fprintf(file, "\t%saddress = (void *)%s%s;\n", string,
+				arg->argMsgField, subindex);
+	if (arg->argDealloc != argNULL)
+		if (akCheck(arg->argDealloc->argKind, akbVarNeeded) || IS_MULTIPLE_KPD(it))
+            fprintf(file, "\t%sdeallocate = %s;\n", string,
+					arg->argDealloc->argVarName);
+	if (VarArray) {
+		fprintf(file, "\t%scount = ", string);
+		if (akCheck(count->argKind, akbVarNeeded))
+			fprintf(file, "%s%s;\n", count->argName, subindex);
+		else
+			fprintf(file, "OutP->%s%s;\n", count->argMsgField, subindex);
+	}
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbReturnSnd))
+		if (akCheck(arg->argPoly->argKind, akbVarNeeded) || IS_MULTIPLE_KPD(it))
+            fprintf(file, "\t%sdisposition = %s;\n", string,
+					arg->argPoly->argVarName);
+	if (IS_MULTIPLE_KPD(it)) {
+		fprintf(file, "\t    }\n");
+		if (it->itVarArray && !it->itElement->itVarArray) {
+			fprintf(file, "\t    for (i = j; i < %d; ptr++, i++)\n", it->itKPD_Number);
+			/* since subordinate arrays aren't variable, they are initialized from template:
+			   here we must no-op 'em */
+			fprintf(file, "\t%scount = 0;\n", string);
+		}
+		fprintf(file, "\t}\n");
+	}
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_TypeCheck discipline for Port types.
+ */
+static void
+WriteTCheckKPD_port(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *tab = "";
+	char string[MAX_STR_LEN];
+	boolean_t close = FALSE;
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, TRUE, FALSE, arg, TRUE);
+		(void)sprintf(string, "ptr->");
+		tab = "\t";
+		close = TRUE;
+    } else 
+		(void)sprintf(string, "In%dP->%s.", arg->argRequestPos, arg->argMsgField);
+
+	fprintf(file, "\t%sif (%stype != MACH_MSG_PORT_DESCRIPTOR", tab, string);
+	/*
+	 * We can't check disposition on varArray
+	 * (because some of the entries could be empty).
+	 */
+	if (!it->itVarArray) {
+		if (arg->argPoly != argNULL) {
+			switch (it->itOutName) {
+
+			case MACH_MSG_TYPE_MOVE_RECEIVE:
+				fprintf(file, " || \n\t%s    %sdisposition != MACH_MSG_TYPE_MOVE_RECEIVE", tab, string);
+				break;
+
+			case MACH_MSG_TYPE_MOVE_SEND_ONCE:
+				fprintf(file, " || (\n\t%s    %sdisposition != MACH_MSG_TYPE_MOVE_SEND_ONCE", tab, string);
+				fprintf(file, " &&  \n\t%s    %sdisposition != MACH_MSG_TYPE_MAKE_SEND_ONCE)", tab, string);
+				break;
+
+			case MACH_MSG_TYPE_MOVE_SEND:
+				fprintf(file, " || (\n\t%s    %sdisposition != MACH_MSG_TYPE_MOVE_SEND", tab, string);
+				fprintf(file, " &&  \n\t%s    %sdisposition != MACH_MSG_TYPE_MAKE_SEND", tab, string);
+				fprintf(file, " &&  \n\t%s    %sdisposition != MACH_MSG_TYPE_COPY_SEND)", tab, string);
+				break;
+			}
+		}
+		else {
+			fprintf(file, " ||\n\t%s    %sdisposition != %s", tab, string, it->itOutNameStr);
+		}
+	}
+	fprintf(file, ")\n");
+	fprintf(file, "\t\treturn MIG_TYPE_ERROR;\n");
+	if (close)
+		fprintf(file, "\t    }\n\t}\n");
+}
+
+/*
+ * argKPD_TypeCheck discipline for out-of-line types.
+ */
+static void
+WriteTCheckKPD_ool(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *tab;
+	char string[MAX_STR_LEN];
+	boolean_t test;
+	u_int howmany, howbig;
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, TRUE, FALSE, arg, TRUE);
+		tab = "\t\t\t";
+		sprintf(string, "ptr->");
+		howmany = it->itElement->itNumber;
+		howbig = it->itElement->itSize;
+		test = !it->itVarArray && !it->itElement->itVarArray;
+    } else {
+		tab = "";
+		sprintf(string, "In%dP->%s.", arg->argRequestPos, arg->argMsgField);
+		howmany = it->itNumber;
+		howbig = it->itSize;
+		test = !it->itVarArray;
+	}
+
+	fprintf(file, "\t%sif (%stype != MACH_MSG_OOL_DESCRIPTOR", tab, string);
+    if (test)
+		/* if VarArray we may use no-op; if itElement->itVarArray size might change */
+		fprintf(file, " ||\n\t%s    %ssize != %d", tab, string, 
+				(howmany * howbig + 7)/8);
+	fprintf(file, ")\n");
+	fprintf(file, "\t\t%s" "return MIG_TYPE_ERROR;\n", tab);
+  
+	if (IS_MULTIPLE_KPD(it))
+		fprintf(file, "\t    }\n\t}\n");
+}
+
+/*
+ * argKPD_TypeCheck discipline for out-of-line Port types.
+ */
+static void
+WriteTCheckKPD_oolport(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *tab;
+	char string[MAX_STR_LEN];
+	boolean_t test;
+	u_int howmany;
+    const char *howstr;
+
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, TRUE, FALSE, arg, TRUE);
+		tab = "\t";
+		sprintf(string, "ptr->");
+		howmany = it->itElement->itNumber;
+		test = !it->itVarArray && !it->itElement->itVarArray;
+		howstr = it->itElement->itOutNameStr;
+    } else {
+		tab = "";
+		sprintf(string, "In%dP->%s.", arg->argRequestPos, arg->argMsgField);
+		howmany = it->itNumber;
+		test = !it->itVarArray;
+		howstr = it->itOutNameStr;
+	}
+
+	fprintf(file, "\t%sif (%stype != MACH_MSG_OOL_PORTS_DESCRIPTOR", tab, string);
+	if (test)
+		/* if VarArray we may use no-op; if itElement->itVarArray size might change */
+        fprintf(file, " ||\n\t%s    %scount != %d", tab, string,
+				howmany);
+	if (arg->argPoly == argNULL)
+        fprintf(file, " ||\n\t%s    %sdisposition != %s", tab, string,
+				howstr);
+	fprintf(file, ")\n");
+	fprintf(file, "\t\treturn MIG_TYPE_ERROR;\n");
+
+	if (IS_MULTIPLE_KPD(it))
+		fprintf(file, "\t    }\n\t}\n");
+}
+
+/*************************************************************
+ *  Writes code to check that the type of each of the arguments
+ *  in the reply message is what is expected. Called by
+ *  WriteRoutine for each in && typed argument in the request message.
+ *************************************************************/
+static void
+WriteTypeCheck(FILE *file, register argument_t *arg)
+{
+	fprintf(file, "#if\t__MigTypeCheck\n");
+	(*arg->argKPD_TypeCheck)(file, arg);
+	fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+}
+
+static void
+WritePackArgValueNormal(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	if (IS_VARIABLE_SIZED_UNTYPED(it) || it->itNoOptArray) {
+		if (it->itString) {
+			/*
+			 * Copy variable-size C string with mig_strncpy.
+			 * Save the string length (+ 1 for trailing 0)
+			 * in the argument`s count field.
+			 */
+			fprintf(file, "\tOutP->%s = mig_strncpy(OutP->%s, %s, %d);\n", arg->argCount->argMsgField, arg->argMsgField, arg->argVarName, it->itNumber);
+		}
+		else if (it->itNoOptArray)
+			fprintf(file, "\t(void)memcpy((char *) OutP->%s, (const char *) %s, %d);\n", arg->argMsgField, arg->argVarName, it->itTypeSize);
+		else {
+			register argument_t *count = arg->argCount;
+			register ipc_type_t *btype = it->itElement;
+			identifier_t newstr;
+
+			/* Note btype->itNumber == count->argMultiplier */
+
+			fprintf(file, "\t(void)memcpy((char *) OutP->%s, (const char *) %s, ", arg->argMsgField, arg->argVarName);
+			if (btype->itTypeSize > 1)
+				fprintf(file, "%d * ", btype->itTypeSize);
+			/* count is a akbVarNeeded if arg is akbVarNeeded */
+			if (akCheck(count->argKind, akbVarNeeded))
+				newstr = count->argVarName;
+			else
+				newstr = (identifier_t)strconcat("OutP->", count->argMsgField);
+			fprintf(file, "%s);\n", newstr);
+		}
+	}
+	else if (it->itOutTrans != strNULL)
+		WriteCopyType(file, it, "OutP->%s", "/* %s */ %s(%s)", arg->argMsgField, it->itOutTrans, arg->argVarName);
+	else
+		WriteCopyType(file, it, "OutP->%s", "/* %s */ %s", arg->argMsgField, arg->argVarName);
+}
+
+static void
+WritePackArgValueVariable(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+
+	/*
+	 * only itString are treated here so far
+	 */
+	if (it->itString) {
+		/*
+		 * Emit logic to call strlen to calculate the size of the argument, and ensure that it fits within the 32-bit result field
+		 * in the Reply, when targeting a 64-bit architecture. If a 32-bit architecture is the target, we emit code to just call
+		 * strlen() directly (since it'll return a 32-bit value that is guaranteed to fit).
+		 */
+		fputs("#ifdef __LP64__\n", file);
+		fprintf(file, "\t{\n"
+				"\t\t" "size_t strLength = strlen(OutP->%s) + 1;\n", arg->argMsgField);
+		fputs(        "\t\t" "if (strLength > 0xffffffff)\n"
+					  "\t\t\t"  "MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS);\n", file);
+		fprintf(file, "\t\t" "OutP->%s = (mach_msg_type_number_t) strLength;\n"
+				"\t}\n", arg->argCount->argMsgField);
+		fputs("#else\n", file);
+		fprintf(file, "\tOutP->%s = (mach_msg_type_number_t) strlen(OutP->%s) + 1;\n", arg->argCount->argMsgField, arg->argMsgField);
+		fputs("#endif /* __LP64__ */\n", file);
+
+	}
+}
+
+static void
+WriteCopyArgValue(FILE *file, argument_t *arg)
+{
+	fprintf(file, "\n");
+	WriteCopyType(file, arg->argType, "/* %d */ OutP->%s", "In%dP->%s", arg->argRequestPos, (arg->argSuffix != strNULL) ? arg->argSuffix : arg->argMsgField);
+}
+
+static void
+WriteInitArgValue(FILE *file, argument_t *arg)
+{
+	fprintf(file, "\n");
+	fprintf(file, "\tOutP->%s = %s;\n\n", arg->argMsgField, arg->argVarName);
+}
+
+/*
+ * Calculate the size of a variable-length message field.
+ */
+static void
+WriteArgSize(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argType;
+	register int bsize = ptype->itElement->itTypeSize;
+	register argument_t *count = arg->argCount;
+
+	/* If the base type size of the data field isn`t a multiple of 4,
+	   we have to round up. */
+	if (bsize % itWordAlign != 0)
+		fprintf(file, "_WALIGN_");
+
+	/* Here, we generate ((value + %d) & ~%d). We have to put two (( at the
+	 * the beginning.
+	 */
+	fprintf(file, "((");
+	if (bsize > 1)
+		fprintf(file, "%d * ", bsize);
+	if (ptype->itString || !akCheck(count->argKind, akbVarNeeded))
+		/* get count from descriptor in message */
+		fprintf(file, "OutP->%s", count->argMsgField);
+	else
+		/* get count from argument */
+		fprintf(file, "%s", count->argVarName);
+
+	/*
+	 * If the base type size is not a multiple of sizeof(natural_t),
+	 * we have to round up.
+	 */
+	if (bsize % sizeof(natural_t) != 0)
+		fprintf(file, " + %ld) & ~%ld)", sizeof(natural_t)-1, sizeof(natural_t)-1);
+	else
+		fprintf(file, "))");
+}
+
+/*
+ * Adjust message size and advance reply pointer.
+ * Called after packing a variable-length argument that
+ * has more arguments following.
+ */
+static void
+WriteAdjustMsgSize(FILE *file, register argument_t *arg)
+{
+	register routine_t *rt = arg->argRoutine;
+	register ipc_type_t *ptype = arg->argType;
+
+	/* There are more Out arguments.  We need to adjust msgh_size
+	   and advance OutP, so we save the size of the current field
+	   in msgh_size_delta. */
+
+	fprintf(file, "\tmsgh_size_delta = ");
+	WriteArgSize(file, arg);
+	fprintf(file, ";\n");
+
+	if (rt->rtNumReplyVar == 1) {
+		/* We can still address the message header directly.  Fill
+		   in the size field. */
+
+		fprintf(file, "\tOutP->Head.msgh_size = ");
+		rtMinReplySize(file, rt, "Reply");
+		fprintf(file, " + msgh_size_delta;\n");
+    } else if (arg->argReplyPos == 0) {
+		/* First variable-length argument.  The previous msgh_size value
+		   is the minimum reply size. */
+
+		fprintf(file, "\tmsgh_size = ");
+		rtMinReplySize(file, rt, "Reply");
+		fprintf(file, " + msgh_size_delta;\n");
+    } else
+		fprintf(file, "\tmsgh_size += msgh_size_delta;\n");
+
+    fprintf(file,
+			"\tOutP = (Reply *) ((pointer_t) OutP + msgh_size_delta - %d);\n",
+			ptype->itTypeSize + ptype->itPadSize);
+}
+
+/*
+ * Calculate the size of the message.  Called after the
+ * last argument has been packed.
+ */
+static void
+WriteFinishMsgSize(FILE *file, register argument_t *arg)
+{
+	/* No more Out arguments.  If this is the only variable Out
+	   argument, we can assign to msgh_size directly. */
+
+	if (arg->argReplyPos == 0) {
+		fprintf(file, "\tOutP->Head.msgh_size = ");
+		rtMinReplySize(file, arg->argRoutine, "Reply");
+		fprintf(file, " + (");
+		WriteArgSize(file, arg);
+		fprintf(file, ");\n");
+	}
+	else {
+		fprintf(file, "\tmsgh_size += ");
+		WriteArgSize(file, arg);
+		fprintf(file, ";\n");
+	}
+}
+
+/*
+ * Handle reply arguments - fill in message types and copy arguments
+ * that need to be copied.
+ */
+static void
+WriteReplyArgs(FILE *file, register routine_t *rt)
+{
+	register argument_t *arg;
+	register argument_t *lastVarArg;
+
+	/*
+	 * 1. The Kernel Processed Data
+	 */
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+		if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnKPD))
+			(*arg->argKPD_Pack)(file, arg);
+	/*
+	 * 2. The Data Stream
+	 */
+	lastVarArg = argNULL;
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)  {
+		/*
+		 * Adjust message size and advance message pointer if
+		 * the last request argument was variable-length and the
+		 * request position will change.
+		 */
+		if (lastVarArg != argNULL &&
+			lastVarArg->argReplyPos < arg->argReplyPos) {
+			WriteAdjustMsgSize(file, lastVarArg);
+			lastVarArg = argNULL;
+		}
+
+		if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnBody|akbVarNeeded))
+			WritePackArgValueNormal(file, arg);
+		else if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnBody|akbVariable))
+			WritePackArgValueVariable(file, arg);
+
+		if (akCheck(arg->argKind, akbReplyCopy))
+			WriteCopyArgValue(file, arg);
+		if (akCheck(arg->argKind, akbReplyInit))
+			WriteInitArgValue(file, arg);
+		/*
+		 * Remember whether this was variable-length.
+		 */
+		if (akCheckAll(arg->argKind, akbReturnSnd|akbReturnBody|akbVariable))
+			lastVarArg = arg;
+	}
+	/*
+	 * Finish the message size.
+	 */
+	if (lastVarArg != argNULL)
+		WriteFinishMsgSize(file, lastVarArg);
+}
+
+static void
+WriteFieldDecl(FILE *file, argument_t *arg)
+{
+	if (akCheck(arg->argKind, akbSendKPD) ||
+		akCheck(arg->argKind, akbReturnKPD))
+		WriteFieldDeclPrim(file, arg, FetchKPDType);
+	else
+		WriteFieldDeclPrim(file, arg, FetchServerType);
+}
+
+static void
+InitKPD_Disciplines(argument_t *args)
+{
+	argument_t *arg;
+	extern void KPD_noop();
+	extern void KPD_error();
+	extern void WriteTemplateKPD_port();
+	extern void WriteTemplateKPD_ool();
+	extern void WriteTemplateKPD_oolport();
+
+	/*
+	 * WriteInitKPD_port, WriteKPD_port,  WriteExtractKPD_port,
+	 * WriteInitKPD_ool, WriteKPD_ool,  WriteExtractKPD_ool,
+	 * WriteInitKPD_oolport, WriteKPD_oolport,  WriteExtractKPD_oolport
+	 * are local to this module (which is the reason why this initialization
+	 * takes place here rather than in utils.c).
+	 * Common routines for user and server will be established SOON, and
+	 * all of them (including the initialization) will be transfert to
+	 * utils.c
+	 * All the KPD disciplines are defaulted to be KPD_error().
+	 * Note that akbSendKPD and akbReturnKPd are not exclusive,
+	 * because of inout type of parameters.
+	 */
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD))
+			switch (arg->argKPD_Type) {
+
+			case MACH_MSG_PORT_DESCRIPTOR:
+				if akCheck(arg->argKind, akbSendKPD) {
+						arg->argKPD_Extract =
+							(IS_MULTIPLE_KPD(arg->argType)) ? WriteExtractKPD_port : WriteExtractArgValue;
+						arg->argKPD_TypeCheck = WriteTCheckKPD_port;
+					}
+				if akCheck(arg->argKind, akbReturnKPD) {
+						arg->argKPD_Template = WriteTemplateKPD_port;
+						arg->argKPD_Init = WriteInitKPD_port;
+						arg->argKPD_Pack = WriteKPD_port;
+					}
+				break;
+
+			case MACH_MSG_OOL_DESCRIPTOR:
+				if akCheck(arg->argKind, akbSendKPD) {
+						arg->argKPD_Extract =
+							(IS_MULTIPLE_KPD(arg->argType)) ? WriteExtractKPD_ool : WriteExtractArgValue;
+						arg->argKPD_TypeCheck = WriteTCheckKPD_ool;
+					}
+				if akCheck(arg->argKind, akbReturnKPD) {
+						arg->argKPD_Template = WriteTemplateKPD_ool;
+						arg->argKPD_Init = WriteInitKPD_ool;
+						arg->argKPD_Pack = WriteKPD_ool;
+					}
+				break;
+
+			case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+				if akCheck(arg->argKind, akbSendKPD) {
+						arg->argKPD_Extract =
+							(IS_MULTIPLE_KPD(arg->argType)) ? WriteExtractKPD_oolport : WriteExtractArgValue;
+						arg->argKPD_TypeCheck = WriteTCheckKPD_oolport;
+					}
+				if akCheck(arg->argKind, akbReturnKPD) {
+						arg->argKPD_Template = WriteTemplateKPD_oolport;
+						arg->argKPD_Init = WriteInitKPD_oolport;
+						arg->argKPD_Pack = WriteKPD_oolport;
+					}
+				break;
+
+			default:
+				printf("MiG internal error: type of kernel processed data unknown\n");
+				exit(1);
+			}   /* end of switch */
+}
+
+static void WriteStringTerminatorCheck(FILE *file, routine_t *rt)
+{
+	// generate code to verify that the length of a C string is not greater than the size of the
+	// buffer in which it is stored.
+	argument_t  *argPtr;
+	int msg_limit_calculated = FALSE;
+	int found_string_argument = FALSE;
+	int variable_length_args_present = (rt->rtMaxRequestPos > 0);
+
+	// scan through arguments to see if there are any strings
+	for (argPtr = rt->rtArgs; argPtr != NULL; argPtr = argPtr->argNext) {
+		if ((argPtr->argKind & akbRequest) && argPtr->argType->itString) {
+			found_string_argument = TRUE;
+			break;
+		}
+	}
+
+	if (found_string_argument) {
+		// create a new scope, for local variables
+		fputs("#if __MigTypeCheck\n" "\t" "{" "\n", file);
+
+		for (argPtr = rt->rtArgs; argPtr != NULL; argPtr = argPtr->argNext) {
+			if ((argPtr->argKind & akbRequest) && argPtr->argType->itString) {
+				//fprintf(stderr, "### found itString: variable name = %s, max length = %d\n", argPtr->argName, argPtr->argType->itNumber);
+
+				if (!msg_limit_calculated) {
+					msg_limit_calculated = TRUE; // only need to do this once
+					fputs("\t\t" "char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size;\n", file);
+					if (IsKernelServer) {
+						fputs("#if __MigKernelSpecificCode\n", file);
+						fputs("\t\t" "size_t strnlen_limit;" "\n", file);
+						fputs("#else\n", file);
+					}
+					fputs("\t\t" "size_t memchr_limit;" "\n", file);
+					if (IsKernelServer) {
+						fputs("#endif /* __MigKernelSpecificCode */" "\n", file);
+					}
+					fputc('\n', file);
+				}
+
+				// I would really prefer to use strnlen() here, to ensure that the byte scanning logic does not extend beyond
+				// the end of the buffer, but it's not necessarily guaranteed to be available. Instead, I'll use memchr(),
+				// and let it look for the terminating null byte.
+				// (later...)
+				// It turns out that the kernel does not have memchr() available, but strnlen() IS available, so we'll just
+				// have to emit some conditional code to use the appropriate runtime environment scanning function.
+				//
+				if (IsKernelServer) {
+					fputs("#if __MigKernelSpecificCode\n", file);
+					fputs("\t\t" "strnlen_limit = min((msg_limit - ", file);
+					// If there are variable-length arguments within the message, the proper (adjusted)
+					// pointers must be used to access those strings
+					fprintf(file, "In%dP->%s),  %d);" "\n", (variable_length_args_present ? argPtr->argRequestPos : 0), argPtr->argName, argPtr->argType->itNumber);
+					fputs("\t\t" "if (", file);
+					fprintf(file, "( strnlen(In%dP->%s, strnlen_limit) >= %d + 1 )", (variable_length_args_present ? argPtr->argRequestPos : 0), argPtr->argName, argPtr->argType->itNumber);
+					fputs(")" "\n" "\t\t\t" "return MIG_BAD_ARGUMENTS; // string length exceeds buffer length!" "\n", file);
+					fputs("#else\n", file);
+				}
+				// If there are variable-length arguments within the message, the proper (adjusted)
+				// pointers must be used to access those strings
+				fprintf(file, "\t\t" "memchr_limit = min((msg_limit - In%dP->%s),  %d);" "\n", (variable_length_args_present ? argPtr->argRequestPos : 0), argPtr->argName, argPtr->argType->itNumber);
+				fputs("\t\t" "if (", file);
+				fprintf(file, "( memchr(In%dP->%s, '\\0', memchr_limit) == NULL )", (variable_length_args_present ? argPtr->argRequestPos : 0), argPtr->argName);
+				fputs(")" "\n" "\t\t\t" "return MIG_BAD_ARGUMENTS; // string length exceeds buffer length!" "\n", file);
+				if (IsKernelServer) {
+					fputs("#endif /* __MigKernelSpecificCode */" "\n", file);
+				}
+			}
+		}
+		fputs("\t" "}" "\n" "#endif" "\t" "/* __MigTypeCheck */" "\n\n", file); // terminate new scope
+	}
+
+	return;
+}
+
+static void
+WriteOOLSizeCheck(FILE *file, routine_t *rt)
+{
+	/* Emit code to validate the actual size of ool data vs. the reported size */
+
+	argument_t  *argPtr;
+	boolean_t   openedTypeCheckConditional = FALSE;
+
+	// scan through arguments to see if there are any ool data blocks
+	for (argPtr = rt->rtArgs; argPtr != NULL; argPtr = argPtr->argNext) {
+		if (akCheck(argPtr->argKind, akbSendKPD) && (argPtr->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR)) {
+			register ipc_type_t *it = argPtr->argType;
+			const char *tab;
+			char string[MAX_STR_LEN];
+			boolean_t test;
+			argument_t  *argCountPtr;
+  
+			if ( !openedTypeCheckConditional ) {
+				openedTypeCheckConditional = TRUE;
+				fputs("#if __MigTypeCheck\n", file);
+			}
+
+			if (IS_MULTIPLE_KPD(it)) {
+				WriteKPD_Iterator(file, TRUE, FALSE, argPtr, TRUE);
+				tab = "\t\t\t";
+				sprintf(string, "ptr->");
+				test = !it->itVarArray && !it->itElement->itVarArray;
+				it = it->itElement; // point to element descriptor, so size calculation is correct
+				argCountPtr = argPtr->argSubCount;
+			}
+			else {
+				tab = "";
+				sprintf(string, "In%dP->%s.", argPtr->argRequestPos, argPtr->argMsgField);
+				test = !it->itVarArray;
+				argCountPtr = argPtr->argCount;
+			}
+    
+			if (!test) {
+				int multiplier = (argCountPtr->argMultiplier > 1 || it->itSize > 8) ? argCountPtr->argMultiplier * it->itSize / 8 : 1;
+				fprintf(file, "\t%s" "if (%ssize ", tab, string);
+				if (multiplier > 1)
+					fprintf(file, "/ %d ", multiplier);
+				fprintf(file,"!= In%dP->%s%s)\n", argCountPtr->argRequestPos, argCountPtr->argVarName, IS_MULTIPLE_KPD(it) ? "[i]" : "");
+
+				fprintf(file, "\t\t%s" "return MIG_TYPE_ERROR;\n", tab);
+			}
+      
+			if (IS_MULTIPLE_KPD(it))
+				fprintf(file, "\t    }\n\t}\n");
+
+		}
+	}
+
+	if ( openedTypeCheckConditional )
+		fputs("#endif" "\t" "/* __MigTypeCheck */" "\n\n", file);
+}
+
+
+static void
+WriteCheckRequest(FILE *file, routine_t *rt)
+{
+	u_int i;
+
+	/* initialize the disciplines for the handling of KPDs */
+	InitKPD_Disciplines(rt->rtArgs);
+
+	fprintf(file, "\n");
+	fprintf(file, "#if ( __MigTypeCheck ");
+	if (CheckNDR) 
+		fprintf(file, "|| __NDR_convert__ ");
+	fprintf(file, ")\n");
+	fprintf(file, "#if __MIG_check__Request__%s_subsystem__\n", SubsystemName);
+	fprintf(file, "#if !defined(__MIG_check__Request__%s_t__defined)\n", rt->rtName);
+	fprintf(file, "#define __MIG_check__Request__%s_t__defined\n", rt->rtName);
+	if (CheckNDR && akCheck(rt->rtNdrCode->argKind, akbRequest)) {
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertIntRepArgDecl, akbSendNdr, "", "");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertCharRepArgDecl, akbSendNdr, "", "");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertFloatRepArgDecl, akbSendNdr, "", "");
+	}
+	fprintf(file, "\n");
+	fprintf(file, "mig_internal kern_return_t __MIG_check__Request__%s_t(__attribute__((__unused__)) __Request__%s_t *In0P", rt->rtName, rt->rtName);
+	for (i = 1; i <= rt->rtMaxRequestPos; i++)
+		fprintf(file, ", __attribute__((__unused__)) __Request__%s_t **In%dPP", rt->rtName, i);
+	fprintf(file, ")\n{\n");
+
+	fprintf(file, "\n\ttypedef __Request__%s_t __Request;\n", rt->rtName);
+	for (i = 1; i <= rt->rtMaxRequestPos; i++)
+		fprintf(file, "\t__Request *In%dP;\n", i);
+	if (rt->rtNumRequestVar > 0) {
+		fprintf(file, "#if\t__MigTypeCheck\n");
+		fprintf(file, "\tunsigned int msgh_size;\n");
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	if (rt->rtMaxRequestPos > 0)
+		fprintf(file, "\tunsigned int msgh_size_delta;\n");
+	if (rt->rtNumRequestVar > 0 || rt->rtMaxRequestPos > 0)
+		fprintf(file, "\n");
+
+	WriteCheckHead(file, rt);
+
+	WriteList(file, rt->rtArgs, WriteTypeCheck, akbSendKPD, "\n", "\n");
+
+	{
+		argument_t *arg, *lastVarArg;
+
+		lastVarArg = argNULL;
+		for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+			if (lastVarArg != argNULL &&
+				lastVarArg->argRequestPos < arg->argRequestPos) {
+				WriteAdjustRequestMsgPtr(file, lastVarArg);
+				lastVarArg = argNULL;
+			}
+			if (akCheckAll(arg->argKind, akbSendRcv|akbSendBody)) {
+				if (akCheck(arg->argKind, akbVariable)) {
+					WriteCheckMsgSize(file, arg);
+					lastVarArg = arg;
+				}
+			}
+		}
+	}
+
+	if (CheckNDR && akCheck(rt->rtNdrCode->argKind, akbRequest)) {
+		fprintf(file, "#if\t");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertIntRepArgCond, akbSendNdr, " || \\\n\t", "\n");
+		fprintf(file, "\tif (In0P->NDR.int_rep != NDR_record.int_rep) {\n");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertIntRepArgUse, akbSendNdr, "", "");
+		fprintf(file, "\t}\n#endif\t/* defined(__NDR_convert__int_rep...) */\n\n");
+
+		WriteOOLSizeCheck(file, rt);
+
+		fprintf(file, "#if\t");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertCharRepArgCond, akbSendNdr, " || \\\n\t", "\n");
+		fprintf(file, "\tif (In0P->NDR.char_rep != NDR_record.char_rep) {\n");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertCharRepArgUse, akbSendNdr, "", "");
+		fprintf(file, "\t}\n#endif\t/* defined(__NDR_convert__char_rep...) */\n\n");
+
+		fprintf(file, "#if\t");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertFloatRepArgCond, akbSendNdr, " || \\\n\t", "\n");
+		fprintf(file, "\tif (In0P->NDR.float_rep != NDR_record.float_rep) {\n");
+		WriteList(file, rt->rtArgs, WriteRequestNDRConvertFloatRepArgUse, akbSendNdr, "", "");
+		fprintf(file, "\t}\n#endif\t/* defined(__NDR_convert__float_rep...) */\n\n");
+	} else {
+		WriteOOLSizeCheck(file, rt);
+	}
+
+	WriteStringTerminatorCheck(file, rt);
+  
+	fprintf(file, "\treturn MACH_MSG_SUCCESS;\n");
+	fprintf(file, "}\n");
+	fprintf(file, "#endif /* !defined(__MIG_check__Request__%s_t__defined) */\n", rt->rtName);
+	fprintf(file, "#endif /* __MIG_check__Request__%s_subsystem__ */\n", SubsystemName);
+	fprintf(file, "#endif /* ( __MigTypeCheck ");
+	if (CheckNDR)
+		fprintf(file, "|| __NDR_convert__ ");
+	fprintf(file, ") */\n");
+	fprintf(file, "\n");
+}
+
+static void
+WriteCheckRequestCall(FILE *file, routine_t *rt)
+{
+	u_int i;
+
+	fprintf(file, "\n");
+	fprintf(file, "#if\tdefined(__MIG_check__Request__%s_t__defined)\n", rt->rtName);
+	fprintf(file, "\tcheck_result = __MIG_check__Request__%s_t((__Request *)In0P", rt->rtName);
+	for (i = 1; i <= rt->rtMaxRequestPos; i++)
+		fprintf(file, ", (__Request **)&In%dP", i);
+	fprintf(file, ");\n");
+	fprintf(file, "\tif (check_result != MACH_MSG_SUCCESS)\n");
+	fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, check_result); }\n");
+	fprintf(file, "#endif\t/* defined(__MIG_check__Request__%s_t__defined) */\n", rt->rtName);
+	fprintf(file, "\n");
+}
+
+void
+WriteCheckRequests(FILE *file, statement_t *stats)
+{
+	statement_t *stat;
+
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine)
+			WriteCheckRequest(file, stat->stRoutine);
+}
+
+static void
+WriteRoutine(FILE *file, register routine_t *rt)
+{
+	/*  Declare the server work function: */
+	if (ServerHeaderFileName == strNULL)
+		WriteServerRoutine(file, rt);
+
+	fprintf(file, "\n");
+
+	fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
+	fprintf(file, "mig_internal novalue _X%s\n", rt->rtName);
+	if (BeAnsiC) {
+		fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)\n");
+    } else {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "\t(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)\n");
+		fprintf(file, "#else\n");
+		fprintf(file, "\t(InHeadP, OutHeadP)\n");
+		fprintf(file, "\tmach_msg_header_t *InHeadP, *OutHeadP;\n");
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+	}
+
+	fprintf(file, "{\n");
+	WriteStructDecl(file, rt->rtArgs, WriteFieldDecl, akbRequest, "Request", rt->rtSimpleRequest, TRUE, rt->rtServerImpl, FALSE);
+	fprintf(file, "\ttypedef __Request__%s_t __Request;\n", rt->rtName);
+	fprintf(file, "\ttypedef __Reply__%s_t Reply;\n\n", rt->rtName);
+
+	/*
+	 * Define a Minimal Reply structure to be used in case of errors
+	 */
+	fprintf(file, "\t/*\n");
+	fprintf(file, "\t * typedef struct {\n");
+	fprintf(file, "\t * \tmach_msg_header_t Head;\n");
+	fprintf(file, "\t * \tNDR_record_t NDR;\n");
+	fprintf(file, "\t * \tkern_return_t RetCode;\n");
+	fprintf(file, "\t * } mig_reply_error_t;\n");
+	fprintf(file, "\t */\n");
+	fprintf(file, "\n");
+
+	WriteVarDecls(file, rt);
+
+	if (IsKernelServer) {
+		fprintf(file, "#if\t__MigKernelSpecificCode\n");
+		WriteList(file, rt->rtArgs, WriteTemplateDeclOut, akbReturnKPD, "\n", "\n");
+		fprintf(file, "#else\n");
+	}
+	WriteList(file, rt->rtArgs, WriteTemplateDeclIn, akbReturnKPD, "\n", "\n");
+	if (IsKernelServer) {
+		fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+	}
+	WriteRetCode(file, rt->rtRetCode);
+	WriteList(file, rt->rtArgs, WriteLocalVarDecl, akbVarNeeded | akbServerArg, ";\n", ";\n\n");
+	WriteApplMacro(file, "Rcv", "Declare", rt);
+	WriteApplMacro(file, "Rcv", "Before", rt);
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest) {
+		WriteRetCArgCheckError(file, rt);
+		if (rt->rtServerImpl)
+			WriteCheckTrailerHead(file, rt, FALSE);
+		WriteServerCall(file, rt, WriteConditionalCallArg);
+		WriteRetCArgFinishError(file, rt);
+	} else
+		fprintf(file, "/* RetCArg=%p rtSimpleRequest=%u */\n", rt->rtRetCArg, rt->rtSimpleRequest);
+
+	WriteCheckRequestCall(file, rt);
+
+	WriteCheckRequestTrailerArgs(file, rt);
+
+
+	/*
+	 * Initialize the KPD records in the Reply structure with the
+	 * templates. We do this beforehand because the call to the procedure
+	 * will overwrite some of the values (after the call it would be impossible
+	 * to initialize the KPD records from the static Templates, because we
+	 * would lose data).
+	 */
+	WriteList(file, rt->rtArgs, WriteInitKPDValue, akbReturnKPD, "\n", "\n");
+
+	WriteList(file, rt->rtArgs, WriteExtractArg, akbNone, "", "");
+
+	if (UseEventLogger)
+		WriteLogMsg(file, rt, LOG_SERVER, LOG_REQUEST);
+
+
+	WriteServerCall(file, rt, WriteServerCallArg);
+
+
+	WriteReverseList(file, rt->rtArgs, WriteDestroyArg, akbDestroy, "", "");
+
+	/*
+	 * For one-way routines, it doesn`t make sense to check the return
+	 * code, because we return immediately afterwards.  However,
+	 * kernel servers may want to deallocate port arguments - and the
+	 * deallocation must not be done if the return code is not KERN_SUCCESS.
+	 */
+	if (rt->rtOneWay || rt->rtNoReplyArgs) {
+		if (IsKernelServer) {
+			fprintf(file,"#if\t__MigKernelSpecificCode\n");
+			if (rtCheckMaskFunction(rt->rtArgs, akbSendKPD, CheckDestroyPortArg)) {
+				WriteCheckReturnValue(file, rt);
+			}
+			WriteReverseList(file, rt->rtArgs, WriteDestroyPortArg, akbSendKPD, "", "");
+			fprintf(file,"#endif /* __MigKernelSpecificCode */\n");
+		}
+		/* although we have an empty reply, we still have to make sure that
+		   some fields such as NDR get properly initialized */
+		if (!rt->rtOneWay)
+			WriteList(file, rt->rtArgs, WriteInitArgValue, akbReplyInit, "\n", "\n");
+    } else {
+		WriteCheckReturnValue(file, rt);
+
+		if (IsKernelServer) {
+			fprintf(file,"#if\t__MigKernelSpecificCode\n");
+			WriteReverseList(file, rt->rtArgs, WriteDestroyPortArg, akbSendKPD, "", "");
+			fprintf(file,"#endif /* __MigKernelSpecificCode */\n");
+		}
+		WriteReplyArgs(file, rt);
+		WriteReplyInit(file, rt);
+		if (!rt->rtSimpleReply)
+			fprintf(file, "\tOutP->msgh_body.msgh_descriptor_count = %d;\n", rt->rtReplyKPDs);
+	}
+	if (UseEventLogger)
+		WriteLogMsg(file, rt, LOG_SERVER, LOG_REPLY);
+
+	WriteApplMacro(file, "Rcv", "After", rt);
+	fprintf(file, "}\n");
+}
+
+void
+WriteServer(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+
+	WriteProlog(file, stats);
+	if (BeAnsiC)
+		WriteForwardDeclarations(file, stats);
+	for (stat = stats; stat != stNULL; stat = stat->stNext) {
+		switch (stat->stKind) {
+		case skRoutine:
+			WriteCheckRequest(file, stat->stRoutine);
+			WriteRoutine(file, stat->stRoutine);
+			break;
+		case skIImport:
+		case skImport:
+		case skSImport:
+		case skDImport:
+		case skUImport:
+			break;
+
+		default:
+			fatal("WriteServer(): bad statement_kind_t (%d)",
+				  (int) stat->stKind);
+		}
+	}
+	WriteDispatcher(file, stats);
+}


Property changes on: trunk/usr.bin/migcom/server.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/shims/errno.h
===================================================================
--- trunk/usr.bin/migcom/shims/errno.h	                        (rev 0)
+++ trunk/usr.bin/migcom/shims/errno.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1 @@
+#include <sys/errno.h>


Property changes on: trunk/usr.bin/migcom/shims/errno.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/shims/stdarg.h
===================================================================
--- trunk/usr.bin/migcom/shims/stdarg.h	                        (rev 0)
+++ trunk/usr.bin/migcom/shims/stdarg.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1 @@
+#include <machine/stdarg.h>


Property changes on: trunk/usr.bin/migcom/shims/stdarg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/shims/stdint.h
===================================================================
--- trunk/usr.bin/migcom/shims/stdint.h	                        (rev 0)
+++ trunk/usr.bin/migcom/shims/stdint.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1 @@
+#include <sys/stdint.h>


Property changes on: trunk/usr.bin/migcom/shims/stdint.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/statement.c
===================================================================
--- trunk/usr.bin/migcom/statement.c	                        (rev 0)
+++ trunk/usr.bin/migcom/statement.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,87 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/02/05  17:55:44  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:55:45  mrt]
+ * 
+ * 90/06/02  15:05:37  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:13:24  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include <stdio.h>
+#include "error.h"
+#include "alloc.h"
+#include "statement.h"
+
+statement_t *defs_stats = stNULL;
+static statement_t **last = &defs_stats;
+
+statement_t *
+stAlloc(void)
+{
+    register statement_t *new;
+
+    new = (statement_t *) malloc(sizeof *new);
+    if (new == stNULL)
+	fatal("stAlloc(): %s", strerror(errno));
+    *last = new;
+    last = &new->stNext;
+    new->stNext = stNULL;
+    return new;
+}


Property changes on: trunk/usr.bin/migcom/statement.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/statement.h
===================================================================
--- trunk/usr.bin/migcom/statement.h	                        (rev 0)
+++ trunk/usr.bin/migcom/statement.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,108 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/02/05  17:55:47  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:55:51  mrt]
+ * 
+ * 90/06/02  15:05:41  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:13:34  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#ifndef	_STATEMENT_H
+#define	_STATEMENT_H
+
+#include "routine.h"
+
+typedef enum statement_kind
+{
+    skRoutine,
+    skImport,
+    skUImport,
+    skSImport,
+    skDImport,
+    skIImport,
+    skRCSDecl
+} statement_kind_t;
+
+typedef struct statement
+{
+    statement_kind_t stKind;
+    struct statement *stNext;
+    union
+    {
+	/* when stKind == skRoutine */
+	routine_t *_stRoutine;
+	/* when stKind == skImport, skUImport, skSImport, skDImport, 
+	                  skIImport */
+	string_t _stFileName;
+    } data;
+} statement_t;
+
+#define	stRoutine	data._stRoutine
+#define	stFileName	data._stFileName
+
+#define stNULL		((statement_t *) 0)
+
+/* stNext will be initialized to put the statement in the list */
+extern statement_t *stAlloc(void);
+
+/* list of statements, in order they occur in the .defs file */
+extern statement_t *defs_stats;
+
+#endif	/* _STATEMENT_H */


Property changes on: trunk/usr.bin/migcom/statement.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/strdefs.h
===================================================================
--- trunk/usr.bin/migcom/strdefs.h	                        (rev 0)
+++ trunk/usr.bin/migcom/strdefs.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,95 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/02/05  17:55:57  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:56:03  mrt]
+ * 
+ * 90/06/02  15:05:49  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:13:56  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 15-Jun-87  David Black (dlb) at Carnegie-Mellon University
+ *	Fixed strNULL to be the null string instead of the null string
+ *	pointer.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#ifndef	STRDEFS_H
+#define	STRDEFS_H
+
+#include <mach/message.h>
+#include <string.h>
+
+typedef const char *string_t;
+typedef string_t identifier_t;
+
+#define MAX_STR_LEN 200 
+
+#define	strNULL		((string_t) 0)
+
+extern string_t strmake(string_t string);
+extern string_t strconcat(string_t left, string_t right);
+extern string_t strphrase(string_t left, string_t right);
+extern void strfree(string_t string);
+
+#define	streql(a, b)	(strcmp((a), (b)) == 0)
+
+extern const char *strbool(boolean_t bool);
+extern const char *strstring(string_t string);
+extern char *toupperstr(char *string);
+
+#endif	/* STRDEFS_H */


Property changes on: trunk/usr.bin/migcom/strdefs.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/string.c
===================================================================
--- trunk/usr.bin/migcom/string.c	                        (rev 0)
+++ trunk/usr.bin/migcom/string.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,186 @@
+/* $MidnightBSD$ */
+
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/02/05  17:55:52  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:55:57  mrt]
+ * 
+ * 90/06/02  15:05:46  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:13:46  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 15-Jun-87  David Black (dlb) at Carnegie-Mellon University
+ *	Declare and initialize charNULL here for strNull def in string.h
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include <mach/boolean.h>
+#include <ctype.h>
+#include "error.h"
+#include "alloc.h"
+#include "strdefs.h"
+
+string_t
+strmake(const char *string)
+{
+    register char *saved;
+
+    saved = malloc(strlen(string) + 1);
+    if (saved == strNULL)
+		fatal("strmake('%s'): %s", string, strerror(errno));
+    return strcpy(saved, string);
+}
+
+string_t
+strconcat(left, right)
+    string_t left, right;
+{
+    register char *saved;
+
+    saved = malloc(strlen(left) + strlen(right) + 1);
+    if (saved == strNULL)
+		fatal("strconcat('%s', '%s'): %s",
+			  left, right, strerror(errno));
+    return strcat(strcpy(saved, left), right);
+}
+
+string_t
+strphrase(left, right)
+    string_t left, right;
+{
+    char *saved;
+    char *current;
+    size_t llen;
+
+    llen = strlen(left);
+    saved = malloc(llen + strlen(right) + 2);
+    if (saved == strNULL)
+		fatal("strphrase('%s', '%s'): %s",
+			  left, right, strerror(errno));
+    strcpy(saved, left);
+    current = saved + llen;
+    *(current++) = ' ';
+    strcpy(current, right);
+    free(__DECONST(char *, left));
+    return(saved);
+}
+
+void
+strfree(string_t string)
+{
+    free(__DECONST(char *,string));
+}
+
+const char *
+strbool(bool)
+    boolean_t bool;
+{
+    if (bool)
+		return "TRUE";
+    else
+		return "FALSE";
+}
+
+const char *
+strstring(string)
+    string_t string;
+{
+    if (string == strNULL)
+		return "NULL";
+    else
+		return string;
+}
+
+char *
+toupperstr(char *p)
+{
+    register char *s = p;
+    char c;
+
+    while ((c = *s)) {
+        if (islower(c))
+			*s = toupper(c);
+        s++;
+    }
+    return(p);
+}


Property changes on: trunk/usr.bin/migcom/string.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/test.c
===================================================================
--- trunk/usr.bin/migcom/test.c	                        (rev 0)
+++ trunk/usr.bin/migcom/test.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,26 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+
+/* comment */


Property changes on: trunk/usr.bin/migcom/test.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/type.c
===================================================================
--- trunk/usr.bin/migcom/type.c	                        (rev 0)
+++ trunk/usr.bin/migcom/type.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,1014 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 at 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.
+ */
+/*
+ * 92/03/03  16:25:23  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:32:39  jeffreyh]
+ * 
+ * 92/01/14  16:46:47  rpd
+ * 	Changed Indefinite types from MustBeLong to ShouldBeLong.
+ * 	Added itCheckFlags, itCheckDeallocate, itCheckIsLong.
+ * 	Removed itServerCopy.
+ * 	[92/01/09            rpd]
+ * 
+ * 91/08/28  11:17:27  jsb
+ * 	Removed itMsgKindType.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/07/31  18:11:12  dbg
+ * 	Indefinite-length inline arrays.
+ * 
+ * 	Change itDeallocate to an enumerated type, to allow for
+ * 	user-specified deallocate flag.
+ * 
+ * 	Add itCStringDecl.
+ * 	[91/07/17            dbg]
+ * 
+ * 91/06/25  10:32:09  rpd
+ * 	Changed itCalculateNameInfo to change type names from mach_port_t
+ * 	to ipc_port_t for KernelServer and KernelUser interfaces.
+ * 	[91/05/28            rpd]
+ * 
+ * 91/02/05  17:56:02  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:56:12  mrt]
+ * 
+ * 90/06/02  15:05:54  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:14:07  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 17-Aug-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Removed translation of MSG_TYPE_INVALID as that type
+ *	is no longer defined by the kernel.
+ * 
+ * 19-Feb-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed itPrintTrans and itPrintDecl to reflect new translation syntax.
+ *	Changed itCheckDecl to set itServerType to itType if is is strNULL.
+ *
+ *  4-Feb-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added a check to itCheckDecl to make sure that in-line
+ *	variable length arrays have a non-zero maximum length.
+ *
+ * 22-Dec-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Removed warning message for translation.
+ *
+ * 16-Nov-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Changed itVarArrayDecl to take a 'max' parameter for maximum
+ *	number of elements, and to make type not be 'struct'.
+ *	Added itDestructor.
+ *
+ * 18-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added initialization of itPortType
+ *
+ * 14-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added initialization for itTidType
+ *
+ * 15-Jun-87  David Black (dlb) at Carnegie-Mellon University
+ *	Fixed prototype for itAlloc; was missing itServerType field.
+ *
+ * 10-Jun-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Removed extern from procedure definitions to make hi-c happy
+ *	Changed the c type names of itDummyType from caddr_t to
+ *	char * and of itCountType from u_int to unsigned int to
+ *	eliminate the need to import sys/types.h into the mig generated
+ *	code.
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include <stdio.h>
+
+#include "type.h"
+#include <sys/types.h>
+#include <mach/message.h>
+#include <mach/std_types.h>
+#include <mach/ndr.h>
+#include "mig_machine.h"
+#include "routine.h"
+#include "error.h"
+#include "alloc.h"
+#include "global.h"
+#include "strdefs.h"
+
+#define PortSize  (sizeof (mach_port_t) * NBBY)
+
+ipc_type_t *itRetCodeType;      /* used for return codes */
+ipc_type_t *itNdrCodeType;      /* used for NDR format labels */
+ipc_type_t *itDummyType;        /* used for camelot dummy args */
+ipc_type_t *itTidType;          /* used for camelot tids */
+ipc_type_t *itRequestPortType;  /* used for default Request port arg */
+ipc_type_t *itZeroReplyPortType;/* used for dummy Reply port arg */
+ipc_type_t *itRealReplyPortType;/* used for default Reply port arg */
+ipc_type_t *itWaitTimeType;     /* used for dummy WaitTime args */
+ipc_type_t *itMsgOptionType;    /* used for dummy MsgOption args */
+
+static ipc_type_t *list = itNULL;
+
+static string_t machine_integer_name;
+static u_int machine_integer_size;
+static u_int machine_integer_bits;
+
+/*
+ *  Searches for a named type.  We use a simple
+ *  self-organizing linked list.
+ */
+ipc_type_t *
+itLookUp(identifier_t name)
+{
+	register ipc_type_t *it, **last;
+  
+	for (it = *(last = &list); it != itNULL; it = *(last = &it->itNext))
+		if (streql(name, it->itName))
+		{
+			/* move this type to the front of the list */
+			*last = it->itNext;
+			it->itNext = list;
+			list = it;
+      
+			return it;
+		}
+  
+	return itNULL;
+}
+
+/*
+ *  Enters a new name-type association into
+ *  our self-organizing linked list.
+ */
+void
+itInsert(identifier_t name, ipc_type_t *it)
+{
+	it->itName = name;
+	it->itNext = list;
+	list = it;
+}
+
+static ipc_type_t *
+itAlloc(void)
+{
+	static ipc_type_t prototype =
+		{
+			strNULL,  /* identifier_t itName */
+			0,        /* ipc_type_t *itNext */
+			0,        /* u_int itTypeSize */
+			0,        /* u_int itPadSize */
+			0,        /* u_int itMinTypeSize */
+			0,        /* u_int itInName */
+			0,        /* u_int itOutName */
+			0,        /* u_int itSize */
+			1,        /* u_int itNumber */
+			0,        /* u_int itKPD_Number */
+			TRUE,     /* boolean_t itInLine */
+			FALSE,    /* boolean_t itMigInLine */
+			FALSE,    /* boolean_t itPortType */
+			strNULL,  /* string_t itInNameStr */
+			strNULL,  /* string_t itOutNameStr */
+			TRUE,     /* boolean_t itStruct */
+			FALSE,    /* boolean_t itString */
+			FALSE,    /* boolean_t itVarArray */
+			FALSE,    /* boolean_t itNoOptArray */
+			FALSE,    /* boolean_t itNative */
+			FALSE,    /* boolean_t itNativePointer */
+			itNULL,   /* ipc_type_t *itElement */
+			strNULL,  /* identifier_t itUserType */
+			strNULL,  /* identifier_t itServerType */
+			strNULL,  /* identifier_t itTransType */
+			strNULL,  /* identifier_t itUserKPDType */
+			strNULL,  /* identifier_t itServerKPDType */
+			strNULL,  /* identifier_t itInTrans */
+			strNULL,  /* identifier_t itOutTrans */
+			strNULL  /* identifier_t itDestructor */
+		};
+	register ipc_type_t *new;
+  
+	new = (ipc_type_t *) malloc(sizeof *new);
+	if (new == itNULL)
+		fatal("itAlloc(): %s", strerror(errno));
+	*new = prototype;
+	return new;
+}
+
+/*
+ * Convert an IPC type-name into a string.
+ */
+static const char *
+itNameToString(u_int name)
+{
+	char buffer[100];
+  
+	(void) sprintf(buffer, "%u", name);
+	return strmake(buffer);
+}
+
+/*
+ * Calculate itTypeSize, itPadSize, itMinTypeSize
+ * Every type needs this info; it is recalculated
+ * when itInLine, itNumber, or itSize changes.
+ */
+static void
+itCalculateSizeInfo(register ipc_type_t *it)
+{
+	if (!IS_KERN_PROC_DATA(it))
+	{
+		u_int bytes = (it->itNumber * it->itSize + 7) / 8;
+		u_int padding = machine_padding(bytes);
+    
+		it->itTypeSize = bytes;
+		it->itPadSize = padding;
+		if (IS_VARIABLE_SIZED_UNTYPED(it)) {
+			/*
+			 * for these arrays, the argCount is not a akbRequest|akbReply,
+			 * therefore we need to account here for the space of the count
+			 * (itMinTypeSize is used only in rtFindSize)
+			 */
+			it->itMinTypeSize = sizeof (mach_msg_type_number_t);
+			/*
+			 * NDR encoded VarString carry the extra offset 4-bytes fields
+			 * for MIG, it should be always 0;
+			 */
+			if (it->itString)
+				it->itMinTypeSize += sizeof (mach_msg_type_number_t);
+		} else
+			it->itMinTypeSize = bytes + padding;
+    } else {
+		/*
+		 * 1) ports 2) OOL 3) ports OOL
+		 * all have the same size = sizeof(mach_msg_descriptor_t)
+		 */
+		u_int bytes;
+		if (IS_MULTIPLE_KPD(it))
+			bytes = it->itKPD_Number * sizeof(mach_msg_descriptor_t);
+		else
+			bytes = sizeof(mach_msg_descriptor_t);
+    
+		it->itTypeSize = bytes;
+		it->itPadSize = 0;
+		it->itMinTypeSize = bytes;
+	}
+  
+	/* Unfortunately, these warning messages can't give a type name;
+	   we haven't seen a name yet (it might stay anonymous.) */
+  
+	if ((it->itTypeSize == 0) && !it->itVarArray && !it->itNative)
+		warn("sizeof(%s) == 0");
+}
+
+/*
+ * Fill in default values for some fields used in code generation:
+ *  itInNameStr, itOutNameStr, itUserType, itServerType, itTransType
+ * Every argument's type should have these values filled in.
+ */
+static void
+itCalculateNameInfo(register ipc_type_t *it)
+{
+	if (it->itInNameStr == strNULL)
+		it->itInNameStr = strmake(itNameToString(it->itInName));
+	if (it->itOutNameStr == strNULL)
+		it->itOutNameStr = strmake(itNameToString(it->itOutName));
+  
+	if (it->itUserType == strNULL)
+		it->itUserType = it->itName;
+	if (it->itServerType == strNULL)
+		it->itServerType = it->itName;
+#if 0
+	/*
+	 *  KernelServer and KernelUser interfaces get special treatment here.
+	 *  On the kernel side of the interface, ports are really internal
+	 *  port pointers (ipc_port_t), not port names (mach_port_t).
+	 *  At this point, we don't know if the argument is in or out,
+	 *  so we don't know if we should look at itInName or itOutName.
+	 *  Looking at both should be OK.
+	 *
+	 *  This is definitely a hack, but I think it is cleaner than
+	 *  mucking with type declarations throughout the kernel .def files,
+	 *  hand-conditionalizing on KERNEL_SERVER and KERNEL_USER.
+	 */
+  
+	if (IsKernelServer &&
+		streql(it->itServerType, "mach_port_t") &&
+		(((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) &&
+		  (it->itOutName == MACH_MSG_TYPE_POLYMORPHIC)) ||
+		 MACH_MSG_TYPE_PORT_ANY(it->itInName) ||
+		 MACH_MSG_TYPE_PORT_ANY(it->itOutName)))
+		it->itServerType = "ipc_port_t";
+  
+	if (IsKernelUser &&
+		streql(it->itUserType, "mach_port_t") &&
+		(((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) &&
+		  (it->itOutName == MACH_MSG_TYPE_POLYMORPHIC)) ||
+		 MACH_MSG_TYPE_PORT_ANY(it->itInName) ||
+		 MACH_MSG_TYPE_PORT_ANY(it->itOutName)))
+		it->itUserType = "ipc_port_t";
+#endif /* 0 */
+  
+	if (it->itTransType == strNULL)
+		it->itTransType = it->itServerType;
+}
+
+/******************************************************
+ *  Checks for non-implemented types, conflicting type
+ *  flags and whether the long or short form of msg type
+ *  descriptor is appropriate. Called after each type statement
+ *  is parsed.
+ ******************************************************/
+static void
+itCheckDecl(identifier_t name, register ipc_type_t *it)
+{
+	it->itName = name;
+  
+	itCalculateNameInfo(it);
+  
+	/* do a bit of error checking, mostly necessary because of
+	   limitations in Mig */
+  
+	if (it->itVarArray) {
+		if ((it->itInTrans != strNULL) || (it->itOutTrans != strNULL))
+			error("%s: can't translate variable-sized arrays", name);
+    
+		if (it->itDestructor != strNULL)
+			error("%s: can't destroy variable-sized array", name);
+	}
+}
+
+/*
+ *  Pretty-prints translation/destruction/type information.
+ */
+static void
+itPrintTrans(register ipc_type_t *it)
+{
+	if (!streql(it->itName, it->itUserType))
+		printf("\tCUserType:\t%s\n", it->itUserType);
+  
+	if (!streql(it->itName, it->itServerType))
+		printf("\tCServerType:\t%s\n", it->itServerType);
+  
+	if (it->itInTrans != strNULL)
+		printf("\tInTran:\t\t%s %s(%s)\n",
+			   it->itTransType, it->itInTrans, it->itServerType);
+  
+	if (it->itOutTrans != strNULL)
+		printf("\tOutTran:\t%s %s(%s)\n",
+			   it->itServerType, it->itOutTrans, it->itTransType);
+  
+	if (it->itDestructor != strNULL)
+		printf("\tDestructor:\t%s(%s)\n", it->itDestructor, it->itTransType);
+}
+
+/*
+ *  Pretty-prints type declarations.
+ */
+static void
+itPrintDecl(identifier_t name, ipc_type_t *it)
+{
+	printf("Type %s = ", name);
+	if (!it->itInLine)
+		printf("^ ");
+	if (it->itVarArray)
+		if (it->itNumber == 0 || it->itMigInLine)
+			printf("array [] of ");
+		else
+			printf("array [*:%d] of ", it->itNumber);
+    else if (it->itStruct && ((it->itNumber != 1) ||
+                              (it->itInName == MACH_MSG_TYPE_STRING_C)))
+		printf("struct [%d] of ", it->itNumber);
+    else if (it->itNumber != 1)
+		printf("array [%d] of ", it->itNumber);
+  
+	if (streql(it->itInNameStr, it->itOutNameStr))
+		printf("(%s,", it->itInNameStr);
+	else
+		printf("(%s|%s", it->itInNameStr, it->itOutNameStr);
+  
+	printf(" %d)\n", it->itSize);
+  
+	itPrintTrans(it);
+  
+	printf("\n");
+}
+
+/*
+ *  Handles named type-specs, which can occur in type
+ *  declarations or in argument lists.  For example,
+ * type foo = type-spec; // itInsert will get called later
+ * routine foo(arg : bar = type-spec); // itInsert won't get called
+ */
+void
+itTypeDecl(identifier_t name, ipc_type_t *it)
+{
+	itCheckDecl(name, it);
+  
+	if (BeVerbose)
+		itPrintDecl(name, it);
+}
+
+/*
+ *  Handles declarations like
+ * type new = name;
+ * type new = inname|outname;
+ */
+ipc_type_t *
+itShortDecl(u_int inname,  string_t instr, u_int outname, string_t outstr, u_int defsize)
+{
+	register ipc_type_t *it;
+  
+	if (defsize == 0)
+		error("must use full IPC type decl");
+  
+	it = itAlloc();
+	it->itInName = inname;
+	it->itInNameStr = instr;
+	it->itOutName = outname;
+	it->itOutNameStr = outstr;
+	it->itSize = defsize;
+	if (inname == MACH_MSG_TYPE_STRING_C)
+	{
+		it->itStruct = FALSE;
+		it->itString = TRUE;
+	}
+	/*
+	 * I check only inname, because outname
+	 * has to be a port as well (polymorphic types
+	 * are now restricted to port rights)
+	 */
+	if (MACH_MSG_TYPE_PORT_ANY(inname) ||
+		inname == MACH_MSG_TYPE_POLYMORPHIC) {
+		it->itPortType = TRUE;
+		it->itKPD_Number = 1;
+	}
+  
+	itCalculateSizeInfo(it);
+	return it;
+}
+
+static ipc_type_t *
+itCopyType(ipc_type_t *old)
+{
+	register ipc_type_t *new = itAlloc();
+  
+	*new = *old;
+	new->itName = strNULL;
+	new->itNext = itNULL;
+	new->itElement = old;
+  
+	/* size info still valid */
+	return new;
+}
+
+/*
+ * A call to itCopyType is almost always followed with itResetType.
+ * The exception is itPrevDecl.  Also called before adding any new
+ * translation/destruction/type info (see parser.y).
+ *
+ * type new = old; // new doesn't get old's info
+ * type new = array[*:10] of old;
+ * // new doesn't get old's info, but new->itElement does
+ * type new = array[*:10] of struct[3] of old;
+ * // new and new->itElement don't get old's info
+ */
+
+ipc_type_t *
+itResetType(ipc_type_t *old)
+{
+	/* reset all special translation/destruction/type info */
+  
+	old->itInTrans = strNULL;
+	old->itOutTrans = strNULL;
+	old->itDestructor = strNULL;
+	old->itUserType = strNULL;
+	old->itServerType = strNULL;
+	old->itTransType = strNULL;
+	return old;
+}
+
+/*
+ *  Handles the declaration
+ * type new = old;
+ */
+ipc_type_t *
+itPrevDecl(identifier_t name)
+{
+	register ipc_type_t *old;
+  
+	old = itLookUp(name);
+	if (old == itNULL) {
+		error("type '%s' not defined", name);
+		return itAlloc();
+	}
+	else
+		return itCopyType(old);
+}
+
+/*
+ *  Handles the declarations
+ * type new = array[] of old; // number is oo
+ * type new = array[*] of old; // number is oo
+ * type new = array[*:number] of old;
+ */
+ipc_type_t *
+itVarArrayDecl(u_int number, register ipc_type_t *old)
+{
+	register ipc_type_t *it = itResetType(itCopyType(old));
+  
+	if (!it->itInLine) {
+		/* already an initialized KPD */
+		if (it->itKPD_Number != 1 || !number)
+			error("IPC type decl is too complicated for Kernel Processed Data");
+		it->itKPD_Number *= number;
+		it->itNumber = 1;
+		it->itInLine = FALSE;
+		it->itStruct = FALSE;
+    } else if (it->itVarArray)
+		error("IPC type decl is too complicated");
+	else if (number) {
+		it->itNumber *= number;
+		/*
+		 * Bounded [Scalar, Port] VarArray: in-line!
+		 */
+		it->itInLine = TRUE;
+		it->itStruct = FALSE;
+		if (it->itPortType)
+			it->itKPD_Number *= number;
+    } else {
+		it->itNumber = 0;
+		/*
+		 * UnBounded [Scalar, Port] VarArray: always in-line
+		 * interface and out-of-line mechanism!
+		 */
+		it->itMigInLine = TRUE;
+		it->itInLine = FALSE;
+		it->itStruct = TRUE;
+		it->itKPD_Number = 1;
+	}
+  
+	it->itVarArray = TRUE;
+	it->itString = FALSE;
+  
+	itCalculateSizeInfo(it);
+	return it;
+}
+
+/*
+ *  Handles the declaration
+ * type new = array[number] of old;
+ */
+ipc_type_t *
+itArrayDecl(u_int number, ipc_type_t *old)
+{
+	register ipc_type_t *it = itResetType(itCopyType(old));
+  
+	if (!it->itInLine) {
+		/* already an initialized KPD */
+		if (it->itKPD_Number != 1)
+			error("IPC type decl is too complicated for Kernel Processed Data");
+		it->itKPD_Number *= number;
+		it->itNumber = 1;
+		it->itStruct = FALSE;
+		it->itString = FALSE;
+		it->itVarArray = FALSE;
+    } else if (it->itVarArray)
+		error("IPC type decl is too complicated");
+	else {
+		it->itNumber *= number;
+		it->itStruct = FALSE;
+		it->itString = FALSE;
+		if (it->itPortType)
+			it->itKPD_Number *= number;
+	}
+  
+	itCalculateSizeInfo(it);
+	return it;
+}
+
+/*
+ *  Handles the declaration
+ * type new = ^ old;
+ */
+ipc_type_t *
+itPtrDecl(ipc_type_t *it)
+{
+	if (!it->itInLine && !it->itMigInLine)
+		error("IPC type decl is already defined to be Out-Of-Line");
+	it->itInLine = FALSE;
+	it->itStruct = TRUE;
+	it->itString = FALSE;
+	it->itMigInLine = FALSE;
+	it->itKPD_Number = 1;
+  
+	itCalculateSizeInfo(it);
+	return it;
+}
+
+/*
+ *  Handles the declaration
+ * type new = struct[number] of old;
+ */
+ipc_type_t *
+itStructDecl(u_int number, ipc_type_t *old)
+{
+	register ipc_type_t *it = itResetType(itCopyType(old));
+  
+	if (!it->itInLine || it->itVarArray)
+		error("IPC type decl is too complicated");
+	it->itNumber *= number;
+	it->itStruct = TRUE;
+	it->itString = FALSE;
+  
+	itCalculateSizeInfo(it);
+	return it;
+}
+
+/*
+ * Treat 'c_string[n]' as
+ * 'array[n] of (MSG_TYPE_STRING_C, 8)'
+ */
+ipc_type_t *
+itCStringDecl(u_int count, boolean_t varying)
+{
+	register ipc_type_t *it;
+	register ipc_type_t *itElement;
+  
+    itElement = itShortDecl(MACH_MSG_TYPE_STRING_C,
+							"MACH_MSG_TYPE_STRING_C",
+							MACH_MSG_TYPE_STRING_C,
+							"MACH_MSG_TYPE_STRING_C",
+							8);
+	itCheckDecl("char", itElement);
+  
+	it = itResetType(itCopyType(itElement));
+	it->itNumber = count;
+	it->itVarArray = varying;
+	it->itStruct = FALSE;
+	it->itString = TRUE;
+  
+	itCalculateSizeInfo(it);
+	return it;
+}
+
+extern ipc_type_t *
+itMakeSubCountType(u_int count, boolean_t varying, string_t name __unused)
+{
+	register ipc_type_t *it;
+	register ipc_type_t *itElement;
+  
+    itElement = itShortDecl(machine_integer_size,
+							machine_integer_name,
+							machine_integer_size,
+							machine_integer_name,
+							machine_integer_bits);
+	itCheckDecl("mach_msg_type_number_t", itElement);
+  
+	it = itResetType(itCopyType(itElement));
+	it->itNumber = count;
+	/*
+	 * I cannot consider it as a Fixed array, otherwise MiG will try
+	 * to follow the path for efficient copy of arrays
+	 */
+	it->itVarArray = FALSE;
+	it->itStruct = FALSE;
+	it->itString = FALSE;
+	it->itInLine = TRUE;
+	it->itName = "mach_msg_type_number_t *";
+	if (varying)
+		it->itVarArray = TRUE;
+	else
+		/* to skip the optimized copy of fixed array: in fact we need to
+		 * reference each element and we also miss a user type for it */
+		it->itNoOptArray = TRUE;
+  
+	itCalculateSizeInfo(it);
+	itCalculateNameInfo(it);
+	return it;
+}
+
+extern ipc_type_t *
+itMakeCountType(void)
+{
+	ipc_type_t *it = itAlloc();
+  
+	it->itName = "mach_msg_type_number_t";
+	it->itInName = machine_integer_size;
+	it->itInNameStr = machine_integer_name;
+	it->itOutName = machine_integer_size;
+	it->itOutNameStr = machine_integer_name;
+	it->itSize = machine_integer_bits;
+  
+	itCalculateSizeInfo(it);
+	itCalculateNameInfo(it);
+	return it;
+}
+
+extern ipc_type_t *
+itMakePolyType(void)
+{
+	ipc_type_t *it = itAlloc();
+  
+	it->itName = "mach_msg_type_name_t";
+	it->itInName = machine_integer_size;
+	it->itInNameStr = machine_integer_name;
+	it->itOutName = machine_integer_size;
+	it->itOutNameStr = machine_integer_name;
+	it->itSize = machine_integer_bits;
+  
+	itCalculateSizeInfo(it);
+	itCalculateNameInfo(it);
+	return it;
+}
+
+extern ipc_type_t *
+itMakeDeallocType(void)
+{
+	ipc_type_t *it = itAlloc();
+  
+	it->itName = "boolean_t";
+	it->itInName = MACH_MSG_TYPE_BOOLEAN;
+	it->itInNameStr = "MACH_MSG_TYPE_BOOLEAN";
+	it->itOutName = MACH_MSG_TYPE_BOOLEAN;
+	it->itOutNameStr = "MACH_MSG_TYPE_BOOLEAN";
+	it->itSize = machine_integer_bits;
+  
+	itCalculateSizeInfo(it);
+	itCalculateNameInfo(it);
+	return it;
+}
+
+extern ipc_type_t *
+itNativeType(id, ptr, badval)
+    identifier_t id;
+    boolean_t ptr;
+    identifier_t badval;
+{
+	ipc_type_t *it = itAlloc();
+  
+	it->itInName = MACH_MSG_TYPE_BYTE;
+	it->itInNameStr = "MACH_MSG_TYPE_BYTE";
+	it->itOutName = MACH_MSG_TYPE_BYTE;
+	it->itOutNameStr = "MACH_MSG_TYPE_BYTE";
+	it->itInLine = TRUE;
+	it->itNative = TRUE;
+	it->itNativePointer = ptr;
+	it->itServerType = id;
+	it->itUserType = id;
+	it->itTransType = id;
+	it->itBadValue = badval;
+  
+	itCalculateSizeInfo(it);
+	itCalculateNameInfo(it);
+	return it;
+}
+
+/*
+ *  Initializes the pre-defined types.
+ */
+void
+init_type(void)
+{
+	u_int size;
+  
+	size = NBBY * sizeof (natural_t);
+	if (size == 32) {
+		machine_integer_name = "MACH_MSG_TYPE_INTEGER_32";
+		machine_integer_size = MACH_MSG_TYPE_INTEGER_32;
+	}
+	else if (size == 64) {
+		machine_integer_name = "MACH_MSG_TYPE_INTEGER_64";
+		machine_integer_size = MACH_MSG_TYPE_INTEGER_64;
+	}
+	else
+		error("init_type unknown size %d", size);
+  
+	machine_integer_bits = size;
+  
+	itRetCodeType = itAlloc();
+	itRetCodeType->itName = "kern_return_t";
+	itRetCodeType->itInName = machine_integer_size;
+	itRetCodeType->itInNameStr = machine_integer_name;
+	itRetCodeType->itOutName = machine_integer_size;
+	itRetCodeType->itOutNameStr = machine_integer_name;
+	itRetCodeType->itSize = machine_integer_bits;
+	itCalculateSizeInfo(itRetCodeType);
+	itCalculateNameInfo(itRetCodeType);
+  
+	itNdrCodeType = itAlloc();
+	itNdrCodeType->itName = "NDR_record_t";
+	itNdrCodeType->itInName = 0;
+	itNdrCodeType->itInNameStr = "NDR_record_t";
+	itNdrCodeType->itOutName = 0;
+	itNdrCodeType->itOutNameStr = "NDR_record_t";
+	itNdrCodeType->itSize = sizeof(NDR_record_t) * 8;
+	itCalculateSizeInfo(itNdrCodeType);
+	itCalculateNameInfo(itNdrCodeType);
+  
+	itDummyType = itAlloc();
+	itDummyType->itName = "char *";
+	itDummyType->itInName = MACH_MSG_TYPE_UNSTRUCTURED;
+	itDummyType->itInNameStr = "MACH_MSG_TYPE_UNSTRUCTURED";
+	itDummyType->itOutName = MACH_MSG_TYPE_UNSTRUCTURED;
+	itDummyType->itOutNameStr = "MACH_MSG_TYPE_UNSTRUCTURED";
+	itDummyType->itSize = PortSize;
+	itCalculateSizeInfo(itDummyType);
+	itCalculateNameInfo(itDummyType);
+  
+	itTidType = itAlloc();
+	itTidType->itName = "tid_t";
+	itTidType->itInName = machine_integer_size;
+	itTidType->itInNameStr = machine_integer_name;
+	itTidType->itOutName = machine_integer_size;
+	itTidType->itOutNameStr = machine_integer_name;
+	itTidType->itSize = machine_integer_bits;
+	itTidType->itNumber = 6;
+	itCalculateSizeInfo(itTidType);
+	itCalculateNameInfo(itTidType);
+  
+	itRequestPortType = itAlloc();
+	itRequestPortType->itName = "mach_port_t";
+	itRequestPortType->itInName = MACH_MSG_TYPE_COPY_SEND;
+	itRequestPortType->itInNameStr = "MACH_MSG_TYPE_COPY_SEND";
+	itRequestPortType->itOutName = MACH_MSG_TYPE_PORT_SEND;
+	itRequestPortType->itOutNameStr = "MACH_MSG_TYPE_PORT_SEND";
+	itRequestPortType->itSize = PortSize;
+	itCalculateSizeInfo(itRequestPortType);
+	itCalculateNameInfo(itRequestPortType);
+  
+	itZeroReplyPortType = itAlloc();
+	itZeroReplyPortType->itName = "mach_port_t";
+	itZeroReplyPortType->itInName = 0;
+	itZeroReplyPortType->itInNameStr = "0";
+	itZeroReplyPortType->itOutName = 0;
+	itZeroReplyPortType->itOutNameStr = "0";
+	itZeroReplyPortType->itSize = PortSize;
+	itCalculateSizeInfo(itZeroReplyPortType);
+	itCalculateNameInfo(itZeroReplyPortType);
+  
+	itRealReplyPortType = itAlloc();
+	itRealReplyPortType->itName = "mach_port_t";
+	itRealReplyPortType->itInName = MACH_MSG_TYPE_MAKE_SEND_ONCE;
+	itRealReplyPortType->itInNameStr = "MACH_MSG_TYPE_MAKE_SEND_ONCE";
+	itRealReplyPortType->itOutName = MACH_MSG_TYPE_PORT_SEND_ONCE;
+	itRealReplyPortType->itOutNameStr = "MACH_MSG_TYPE_PORT_SEND_ONCE";
+	itRealReplyPortType->itSize = PortSize;
+	itCalculateSizeInfo(itRealReplyPortType);
+	itCalculateNameInfo(itRealReplyPortType);
+  
+	itWaitTimeType = itMakeCountType();
+	itMsgOptionType = itMakeCountType();
+}
+
+/******************************************************
+ *  Make sure return values of functions are assignable.
+ ******************************************************/
+void
+itCheckReturnType(identifier_t name, ipc_type_t *it)
+{
+	if (!it->itStruct)
+		error("type of %s is too complicated", name);
+	if ((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) ||
+		(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC))
+		error("type of %s can't be polymorphic", name);
+}
+
+
+/******************************************************
+ *  Called by routine.c to check that request ports are
+ *  simple and correct ports with send rights.
+ ******************************************************/
+void
+itCheckRequestPortType(identifier_t name, ipc_type_t *it)
+{
+/*    error("Port size = %d %d name = %s\n", PortSize, it->itSize, it->itName);
+	  error("server = %s user = %x\n",it->itServerType, it->itUserType);
+*/
+	if (((it->itOutName != MACH_MSG_TYPE_PORT_SEND) &&
+		 (it->itOutName != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
+		 (it->itOutName != MACH_MSG_TYPE_POLYMORPHIC)) ||
+		(it->itNumber != 1) ||
+		(it->itSize != PortSize) ||
+		!it->itInLine ||
+		!it->itStruct ||
+		it->itVarArray)
+		error("argument %s isn't a proper request port", name);
+}
+
+
+/******************************************************
+ *  Called by routine.c to check that reply ports are
+ *  simple and correct ports with send rights.
+ ******************************************************/
+void
+itCheckReplyPortType(identifier_t name, ipc_type_t *it)
+{
+	if (((it->itOutName != MACH_MSG_TYPE_PORT_SEND) &&
+		 (it->itOutName != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
+		 (it->itOutName != MACH_MSG_TYPE_POLYMORPHIC) &&
+		 (it->itOutName != 0)) ||
+		(it->itNumber != 1) ||
+		(it->itSize != PortSize) ||
+		!it->itInLine ||
+		!it->itStruct ||
+		it->itVarArray)
+		error("argument %s isn't a proper reply port", name);
+}
+
+
+/******************************************************
+ *  Used by routine.c to check that WaitTime is a
+ *  simple bit machine_integer_bits integer.
+ ******************************************************/
+void
+itCheckIntType(identifier_t name, ipc_type_t *it)
+{
+	if ((it->itInName != machine_integer_size) ||
+		(it->itOutName != machine_integer_size) ||
+		(it->itNumber != 1) ||
+		(it->itSize != machine_integer_bits) ||
+		!it->itInLine ||
+		!it->itStruct ||
+		it->itVarArray)
+		error("argument %s isn't a proper integer", name);
+}
+
+void
+itCheckTokenType(identifier_t name, ipc_type_t *it)
+{
+	if (it->itMigInLine || it->itNoOptArray || it->itString ||
+		it->itTypeSize != 8 || !it->itInLine || !it->itStruct ||
+		it->itVarArray || it->itPortType)
+		error("argument %s isn't a proper Token", name);
+}


Property changes on: trunk/usr.bin/migcom/type.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/type.h
===================================================================
--- trunk/usr.bin/migcom/type.h	                        (rev 0)
+++ trunk/usr.bin/migcom/type.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,327 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 at 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.
+ */
+/*
+ * 92/03/03  16:25:29  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:32:47  jeffreyh]
+ * 
+ * 92/01/14  16:46:51  rpd
+ * 	Added itCheckFlags, itCheckDeallocate, itCheckIsLong.
+ * 	Removed itServerCopy.
+ * 	[92/01/09            rpd]
+ * 
+ * 92/01/03  20:30:23  dbg
+ * 	Add flCountInOut.
+ * 	[91/11/11            dbg]
+ * 
+ * 91/08/28  11:17:30  jsb
+ * 	Removed itMsgKindType.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/07/31  18:11:22  dbg
+ * 	Add flServerCopy.
+ * 	[91/06/05            dbg]
+ * 
+ * 	Add itIndefinite.
+ * 	[91/04/10            dbg]
+ * 
+ * 	Change itDeallocate to an enumerated type, to allow for
+ * 	user-specified deallocate flag.
+ * 
+ * 	Add itCStringDecl.
+ * 	[91/04/03            dbg]
+ * 
+ * 91/02/05  17:56:13  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:56:19  mrt]
+ * 
+ * 90/06/02  15:05:59  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:14:28  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 16-Nov-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Changed itVarArrayDecl to take a 'max' parameter.
+ *	Added itDestructor.
+ *
+ *  18-Aug-87	Mary Thompson @ Carnegie Mellon
+ *	Added itPortType
+ *	Added itTidType
+ */
+
+#ifndef	_TYPE_H
+#define	_TYPE_H
+
+#include <sys/types.h>
+#include <sys/param.h>
+typedef u_int ipc_flags_t;
+#include "strdefs.h"
+
+
+/*
+ * MIG built-in types 
+ */
+#define MACH_MSG_TYPE_UNSTRUCTURED      0
+#define MACH_MSG_TYPE_BIT               0
+#define MACH_MSG_TYPE_BOOLEAN           0
+#define MACH_MSG_TYPE_INTEGER_8         9
+#define MACH_MSG_TYPE_INTEGER_16        1
+#define MACH_MSG_TYPE_INTEGER_32        2
+#define MACH_MSG_TYPE_INTEGER_64        3
+#define MACH_MSG_TYPE_CHAR              8
+#define MACH_MSG_TYPE_BYTE              9
+#define MACH_MSG_TYPE_REAL_32           10
+#define MACH_MSG_TYPE_REAL_64           11
+#define MACH_MSG_TYPE_STRING            12
+#define MACH_MSG_TYPE_STRING_C          12
+
+#define	flNone		 (0x00)
+#define flPhysicalCopy   (0x01)	/* Physical Copy specified */
+#define flOverwrite      (0x02)	/* Overwrite mode specified */
+#define	flDealloc	 (0x04)	/* Dealloc specified */
+#define	flNotDealloc	 (0x08)	/* NotDealloc specified */
+#define	flMaybeDealloc	 (0x10)	/* Dealloc[] specified */
+#define	flSameCount	 (0x20)	/* SamCount specified, used by co-bounded arrays */
+#define	flCountInOut	 (0x40)	/* CountInOut specified */
+#define	flRetCode	 (0x80)	/* RetCode specified */
+#define	flAuto		(0x100)	/* Will not be referenced by server after RPC */
+#define	flConst		(0x200)	/* Will not be modified by server during RPC */
+
+
+typedef enum dealloc {
+	d_NO,			/* do not deallocate */
+	d_YES,			/* always deallocate */
+	d_MAYBE			/* deallocate according to parameter */
+} dealloc_t;
+
+/* Convert dealloc_t to TRUE/FALSE */
+#define	strdealloc(d)	(strbool(d == d_YES))
+
+/*
+ * itName and itNext are internal fields (not used for code generation).
+ * They are only meaningful for types entered into the symbol table.
+ * The symbol table is a simple self-organizing linked list.
+ *
+ * The function itCheckDecl checks & fills in computed information.
+ * Every type actually used (pointed at by argType) is so processed.
+ *
+ * The itInName, itOutName, itSize, itNumber, fields correspond directly 
+ * to mach_msg_type_t fields.
+ * For out-of-line variable sized types, itNumber is zero.  For
+ * in-line variable sized types, itNumber is the maximum size of the
+ * array.  itInName is the name value supplied to the kernel,
+ * and itOutName is the name value received from the kernel.
+ * When the type describes a MACH port, either or both may be 
+ * MACH_MSG_TYPE_POLYMORPHIC, indicating a "polymorphic" name.  
+ * For itInName, this means the user supplies the value with an argument.  
+ * For itOutName, this means the value is returned in an argument.
+ *
+ * The itInNameStr and itOutNameStr fields contain "printing" versions
+ * of the itInName and itOutName values.  The mapping from number->string
+ * is not into (eg, MACH_MSG_TYPE_UNSTRUCTURED/MACH_MSG_TYPE_BOOLEAN/
+ * MACH_MSG_TYPE_BIT).  These fields are used for code-generation and
+ * pretty-printing.
+ *
+ * itTypeSize is the calculated size of the C type, in bytes.
+ * itPadSize is the size of any padded needed after the data field.
+ * itMinTypeSize is the minimum size of the data field, including padding.
+ * For variable-length inline data, it is zero.
+ *
+ * itUserType, itServerType, itTransType are the C types used in
+ * code generation.  itUserType is the C type passed to the user-side stub
+ * and used for msg declarations in the user-side stub.  itServerType
+ * is the C type used for msg declarations in the server-side stub.
+ * itTransType is the C type passed to the server function by the
+ * server-side stub.  Normally it differs from itServerType only when
+ * translation functions are defined.
+ *
+ * itInTrans and itOutTrans are translation functions.  itInTrans
+ * takes itServerType values and returns itTransType values.  itOutTrans
+ * takes itTransType vaulues and returns itServerType values.
+ * itDestructor is a finalization function applied to In arguments
+ * after the server-side stub calls the server function.  It takes
+ * itTransType values.  Any combination of these may be defined.
+ *
+ * The following type specification syntax modifies these values:
+ *	type new = old
+ *		ctype: name		// itUserType and itServerType
+ *		cusertype: itUserType
+ *		cservertype: itServerType
+ *		intran: itTransType itInTrans(itServerType)
+ *		outtran: itServerType itOutTrans(itTransType)
+ *		destructor: itDestructor(itTransType);
+ *
+ * At most one of itStruct and itString should be TRUE.  If both are
+ * false, then this is assumed to be an array type (msg data is passed
+ * by reference).  If itStruct is TRUE, then msg data is passed by value
+ * and can be assigned with =.  If itString is TRUE, then the msg_data
+ * is a null-terminated string, assigned with strncpy.  The itNumber
+ * value is a maximum length for the string; the msg field always
+ * takes up this much space.
+ * NoOptArray has been introduced for the cases where the special
+ * code generated for array assignments would not work (either because 
+ * there is  not a ctype (array of automagically generated MiG variables)
+ * or because we need to reference the single elements of the array
+ * (array of variable sized ool regions).
+ *
+ * itVarArray means this is a variable-sized array.  If it is inline,
+ * then itStruct and itString are FALSE.  If it is out-of-line, then
+ * itStruct is TRUE (because pointers can be assigned).
+ *
+ * itMigInLine means this is an indefinite-length array. Although the 
+ * argument was not specified as out-of-line, MIG will send it anyway
+ * os an out-of-line.  
+ *
+ * itUserKPDType (itServerKPDType) identify the type of Kernel Processed 
+ * Data that we must deal with: it can be either "mach_msg_port_descriptor_t"
+ * or "mach_msg_ool_ports_descriptor_t" or "mach_msg_ool_descriptor_t".
+ *
+ * itKPD_Number is used any time a single argument require more than
+ * one Kernel Processed Data entry: i.e., an in-line array of ports, an array
+ * of pointers (out-of-line data)
+ * 
+ * itElement points to any substructure that the type may have.
+ * It is only used with variable-sized array types.
+ */
+
+typedef struct ipc_type
+{
+    identifier_t itName;	/* Mig's name for this type */
+    struct ipc_type *itNext;	/* next type in symbol table */
+
+    u_int itTypeSize;		/* size of the C type */
+    u_int itPadSize;		/* amount of padding after data */
+    u_int itMinTypeSize;	/* minimal amount of space occupied by data */
+
+    u_int itInName;		/* name supplied to kernel in sent msg */
+    u_int itOutName;		/* name in received msg */
+    u_int itSize;
+    u_int itNumber;
+    u_int itKPD_Number; 	/* number of Kernel Processed Data entries */
+    boolean_t itInLine;
+    boolean_t itMigInLine; 	/* MiG presents data as InLine, although it is sent OOL */
+    boolean_t itPortType;
+
+    string_t itInNameStr;	/* string form of itInName */
+    string_t itOutNameStr;	/* string form of itOutName */
+
+    boolean_t itStruct;
+    boolean_t itString;
+    boolean_t itVarArray;
+    boolean_t itNoOptArray;
+    boolean_t itNative;         /* User specified a native (C) type. */
+    boolean_t itNativePointer;  /* The user will pass a pointer to the */
+                                /* native C type. */
+
+    struct ipc_type *itElement;	/* may be NULL */
+
+    identifier_t itUserType;
+    identifier_t itServerType;
+    identifier_t itTransType;
+
+    identifier_t itKPDType; /* descriptors for KPD type of arguments */
+
+
+    identifier_t itInTrans;	/* may be NULL */
+    identifier_t itOutTrans;	/* may be NULL */
+    identifier_t itDestructor;	/* may be NULL */
+    identifier_t itBadValue;    /* Excluded value for PointerToIfNot.  May
+                                   be NULL. */
+} ipc_type_t;
+
+#define	itNULL		((ipc_type_t *) 0)
+
+#define itWordAlign     (sizeof(void *))
+
+extern ipc_type_t *itLookUp(identifier_t name);
+extern void itInsert(identifier_t name, ipc_type_t *it);
+extern void itTypeDecl(identifier_t name, ipc_type_t *it);
+
+extern ipc_type_t *itShortDecl(u_int inname, string_t instr,
+				  u_int outname, string_t outstr,
+				  u_int dfault);
+extern ipc_type_t *itPrevDecl(identifier_t name);
+extern ipc_type_t *itResetType(ipc_type_t *it);
+extern ipc_type_t *itVarArrayDecl(u_int number, ipc_type_t *it);
+extern ipc_type_t *itArrayDecl(u_int number, ipc_type_t *it);
+extern ipc_type_t *itPtrDecl(ipc_type_t *it);
+extern ipc_type_t *itStructDecl(u_int number, ipc_type_t *it);
+extern ipc_type_t *itCStringDecl(u_int number, boolean_t varying);
+extern ipc_type_t *itNativeType(identifier_t CType, boolean_t pointer,
+                                   identifier_t NotVal);
+
+extern ipc_type_t *itRetCodeType;
+extern ipc_type_t *itNdrCodeType;
+extern ipc_type_t *itDummyType;
+extern ipc_type_t *itTidType;
+extern ipc_type_t *itRequestPortType;
+extern ipc_type_t *itZeroReplyPortType;
+extern ipc_type_t *itRealReplyPortType;
+extern ipc_type_t *itWaitTimeType;
+extern ipc_type_t *itMsgOptionType;
+extern ipc_type_t *itMakeCountType(void);
+extern ipc_type_t *itMakeSubCountType(u_int count, boolean_t varying, string_t name);
+extern ipc_type_t *itMakePolyType(void);
+extern ipc_type_t *itMakeDeallocType(void);
+
+extern void init_type(void);
+
+extern void itCheckReturnType(identifier_t name, ipc_type_t *it);
+extern void itCheckRequestPortType(identifier_t name, ipc_type_t *it);
+extern void itCheckReplyPortType(identifier_t name, ipc_type_t *it);
+extern void itCheckIntType(identifier_t name, ipc_type_t *it);
+extern void itCheckTokenType(identifier_t name, ipc_type_t *it);
+
+#include "statement.h"
+
+#endif	/* _TYPE_H */


Property changes on: trunk/usr.bin/migcom/type.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/user.c
===================================================================
--- trunk/usr.bin/migcom/user.c	                        (rev 0)
+++ trunk/usr.bin/migcom/user.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,3341 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 29-Sep-92  John Loverso (loverso) at Open Software Foundation
+ *	Changes to deallocate memory on various error codes
+ *
+ * 92/03/03  16:25:33  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:32:55  jeffreyh]
+ * 
+ * 92/01/14  16:46:59  rpd
+ * 	Changed CountInOut code generation, to send the minimum
+ * 	of the reply msg buffer size and the user's buffer size.
+ * 	[92/01/13            rpd]
+ * 
+ * 	Fixed WriteExtractArgValue/itIndefinite, in the case when
+ * 	the data is in-line but doesn't fit.
+ * 	Fixed Indefinite code generation, to allow short type descriptors.
+ * 	Added deallocate bit handling to Indefinite code generation.
+ * 	[92/01/08            rpd]
+ * 
+ * 92/01/03  20:30:38  dbg
+ * 	Redo handling of OUT arrays that are passed in-line or
+ * 	out-of-line.  Treat more like out-of-line arrays:
+ * 	user allocates buffer and pointer
+ * 	fills in pointer with buffer address
+ * 	passes pointer to stub
+ * 	stub copies data to *pointer, or changes pointer
+ * 	User can always use *pointer.
+ * 
+ * 	Change argByReferenceUser to a field in argument_t.
+ * 	[91/09/04            dbg]
+ * 
+ * 91/08/28  11:17:34  jsb
+ * 	Added MIG_SERVER_DIED.
+ * 	[91/08/21            rpd]
+ * 	Removed Camelot and TrapRoutine support.
+ * 	Changed MsgKind to MsgSeqno.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/07/31  18:11:31  dbg
+ * 	Allow indefinite-length variable arrays.  They may be copied
+ * 	either in-line or out-of-line, depending on size.
+ * 
+ * 	Copy variable-length C Strings with mig_strncpy, to combine
+ * 	'strcpy' and 'strlen' operations.
+ * 
+ * 	New method for advancing request message pointer past
+ * 	variable-length arguments.  We no longer have to know the order
+ * 	of variable-length arguments and their count arguments.
+ * 
+ * 	Remove redundant assignments (to msgh_simple, msgh_size) in
+ * 	generated code.
+ * 	[91/07/17            dbg]
+ * 
+ * 91/06/26  14:39:44  rpd
+ * 	Removed the dummy user initialization function,
+ * 	which was kept for backwards-compatibility.
+ * 	[91/06/26            rpd]
+ * 
+ * 91/06/25  10:32:22  rpd
+ * 	Cast request and reply ports to mach_port_t in KernelUser stubs.
+ * 	[91/05/27            rpd]
+ * 
+ * 	Changed HeaderFileName to UserHeaderFileName.
+ * 	Changed WriteVarDecl to WriteUserVarDecl.
+ * 	[91/05/23            rpd]
+ * 
+ * 91/02/05  17:56:20  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:56:28  mrt]
+ * 
+ * 90/06/19  23:01:20  rpd
+ * 	Added UserFilePrefix support.
+ * 	[90/06/03            rpd]
+ * 
+ * 90/06/02  15:06:03  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:14:40  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 21-Feb-89  David Golub (dbg) at Carnegie-Mellon University
+ *	Get name for header file from HeaderFileName, since it can
+ *	change.
+ *
+ *  8-Feb-89  David Golub (dbg) at Carnegie-Mellon University
+ *	Added WriteUserIndividual to put each user-side routine in its
+ *	own file.
+ *
+ *  8-Jul-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Declared routines to be mig_external instead of extern,
+ *	where mig_external is conditionally defined in <subsystem>.h.
+ *	The Avalon folks want to define mig_external to be static
+ *	in their compilations because they inlcude the User.c code in
+ *	their programs.
+ *
+ * 23-Feb-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed the include of camelot_types.h to cam/camelot_types.h
+ *
+ * 19-Feb-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added comments for each routine. Called WriteMsgError
+ *	for MIG_ARRAY_TOO_LARGE errors.
+ *
+ * 19-Jan-88  David Golub (dbg) at Carnegie-Mellon University
+ *	Change variable-length inline array declarations to use
+ *	maximum size specified to Mig.  Make message variable
+ *	length if the last item in the message is variable-length
+ *	and inline.  Use argMultiplier field to convert between
+ *	argument and IPC element counts.
+ *
+ * 19-Jan-88  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	In WriteInitRoutine changed reference from reply_port; to reply_port++;
+ *	for lint code.
+ *
+ * 17-Jan-88  David Detlefs (dld) at Carnegie-Mellon University
+ *	Modified to produce C++ compatible code via #ifdefs.
+ *	All changes have to do with argument declarations.
+ *
+ * 16-Nov-87  David Golub (dbg) at Carnegie-Mellon University
+ *	Handle variable-length inline arrays.
+ *
+ * 22-Oct-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ * 	Added a reference to rep_port in the InitRoutine
+ *	with an ifdef lint conditional.
+ *
+ * 22-Sep-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Fixed check for TransId to be a not equal test
+ *	rather than an equal test.
+ *
+ *  2-Sep-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed WriteCheckIdentity to check TransId instead
+ *	of msgh_id for a returned camelot reply
+ *
+ * 24-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added a  LINTLIBRARY  line to keep lint
+ *	from complaining about routines that are not used.
+ *
+ * 21-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added Flag parameter to WritePackMsgType.
+ *
+ * 12-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Made various camelot changes: include of camelot_types.h
+ *	Check for death_pill before correct msg-id.
+ *
+ * 10-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Renamed get_reply_port and dealloc_reply_port to
+ *	mig_get_reply_port and mig_dealloc_reply_port.
+ *	Fixed WriteRequestHead to handle MsgType parameter.
+ *
+ *  3-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Fixed to generate code that is the same for multi-threaded and
+ *	single threaded use. Gets reply port from library routine
+ *	get_reply_port and deallocates with routine
+ *	dealloc_reply_port. Removed all routines in mig interface code
+ *	to keep track of the reply port. The init routine still exists
+ *	but does nothing.
+ * 
+ * 29-Jul_87  Mary Thompson (mrt) at Carnegie-Mellon University
+ * 	Fixed call to WriteVarDecl to use correspond to
+ *	the changes that were made in that routine.
+ *
+ * 16-Jul-87  Robert Sansom (rds) at Carnegie Mellon University
+ *	Added write of MsgType to WriteSetMsgTypeRoutine.
+ *
+ *  8-Jun-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Removed #include of sys/types.h from WriteIncludes.
+ *	Changed the KERNEL include from ../h to sys/
+ *	Removed extern from WriteUser to make hi-c happy
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <mach/message.h>
+#include "write.h"
+#include "error.h"
+#include "utils.h"
+#include "global.h"
+#include "alloc.h"
+
+const char *MessAllocRoutine = "mig_user_allocate";
+const char *MessFreeRoutine = "mig_user_deallocate";
+
+static char stRetCode[] = "ReturnValue";
+static char stRetNone[] = "";
+
+void WriteLogDefines();
+void WriteIdentificationString();
+
+static void
+WriteKPD_Iterator(FILE *file, boolean_t in, boolean_t overwrite, boolean_t varying, argument_t *arg, boolean_t bracket)
+{
+	register ipc_type_t *it = arg->argType;
+	char string[MAX_STR_LEN];
+  
+	fprintf(file, "\t{\n");
+	fprintf(file, "\t    register\t%s\t*ptr;\n", it->itKPDType);
+	fprintf(file, "\t    register int\ti");
+	if (varying && !in)
+		fprintf(file, ", j");
+	fprintf(file, ";\n\n");
+  
+	if (in)
+		sprintf(string, "InP");
+	else if (overwrite)
+		sprintf(string, "InOvTemplate");
+	else
+		sprintf(string, "Out%dP", arg->argRequestPos);
+  
+	fprintf(file, "\t    ptr = &%s->%s[0];\n", string, arg->argMsgField);
+  
+	if (varying) {
+		register argument_t *count = arg->argCount;
+		register const char *cref = count->argByReferenceUser ? "*" : "";
+    
+		if (in || overwrite) {
+			fprintf(file, "\t    if (%s%s > %d)\n", cref, count->argVarName,
+					it->itKPD_Number);
+			WriteReturnMsgError(file, arg->argRoutine, TRUE, arg, "MIG_ARRAY_TOO_LARGE");
+            fprintf(file, "\t    for (i = 0; i < %s%s; ptr++, i++) %s\n",
+					cref, count->argVarName, (bracket) ? "{" : "");
+		} else {
+			fprintf(file, "\t    j = min(Out%dP->%s, %s%s);\n", count->argReplyPos, 
+					count->argVarName, cref, count->argVarName);
+			fprintf(file, "\t    for (i = 0; i < j; ptr++, i++) %s\n",
+					(bracket) ? "{" : "");
+		}
+    } else
+        fprintf(file, "\t    for (i = 0; i < %d; ptr++, i++) %s\n", it->itKPD_Number,
+				(bracket) ? "{" : "");
+}
+
+/*************************************************************
+ * Writes the standard includes. The subsystem specific
+ * includes  are in <SubsystemName>.h and writen by
+ * header:WriteHeader. Called by WriteProlog.
+ *************************************************************/
+static void
+WriteMyIncludes(FILE *file, statement_t *stats)
+{
+#ifdef MIG_KERNEL_PORT_CONVERSION
+	if (IsKernelServer)
+	{
+		/*
+		 * We want to get the user-side definitions of types
+		 * like task_t, ipc_space_t, etc. in mach/mach_types.h.
+		 */
+    
+		fprintf(file, "#undef\tMACH_KERNEL\n");
+    
+		if (InternalHeaderFileName != strNULL)
+		{
+			register const char *cp;
+      
+			/* Strip any leading path from InternalHeaderFileName. */
+			cp = strrchr(InternalHeaderFileName, '/');
+			if (cp == 0)
+				cp = InternalHeaderFileName;
+			else
+				cp++; /* skip '/' */
+			fprintf(file, "#include \"%s\"\n", cp);
+		}
+	}
+#endif
+  
+	if (UserHeaderFileName == strNULL || UseSplitHeaders)
+		WriteIncludes(file, TRUE, FALSE);
+	if (UserHeaderFileName != strNULL)
+	{
+		register const char *cp;
+    
+		/* Strip any leading path from UserHeaderFileName. */
+		cp = strrchr(UserHeaderFileName, '/');
+		if (cp == 0)
+			cp = UserHeaderFileName;
+		else
+			cp++; /* skip '/' */
+		fprintf(file, "#include \"%s\"\n", cp);
+	}
+	if (UseSplitHeaders)
+		WriteImplImports(file, stats, TRUE);
+  
+	if (UseEventLogger) {
+		if (IsKernelUser) {
+			fprintf(file, "#if\t__MigKernelSpecificCode\n");
+			fprintf(file, "#include <mig_debug.h>\n");
+			fprintf(file, "#endif\t/* __MigKernelSpecificCode */\n");
+		}
+		fprintf(file, "#if  MIG_DEBUG\n");
+		fprintf(file, "#include <mach/mig_log.h>\n");
+		fprintf(file, "#endif /* MIG_DEBUG */\n");
+	}
+    fprintf(file, "/* LINTLIBRARY */\n");
+	fprintf(file, "\n");
+	if (!BeAnsiC) {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "#else\t/* %s */\n", NewCDecl);
+		fprintf(file, "extern mach_port_t mig_get_reply_port();\n");
+		fprintf(file, "extern void mig_dealloc_reply_port();\n");
+		fprintf(file, "extern char *%s();\n", MessAllocRoutine);
+		fprintf(file, "extern void %s();\n", MessFreeRoutine);
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+	}
+	fprintf(file, "\n");
+}
+
+static void
+WriteGlobalDecls(FILE *file)
+{
+	if (RCSId != strNULL)
+		WriteRCSDecl(file, strconcat(SubsystemName, "_user"), RCSId);
+  
+	fprintf(file, "#define msgh_request_port\tmsgh_remote_port\n");
+	fprintf(file, "#define msgh_reply_port\t\tmsgh_local_port\n");
+	fprintf(file, "\n");
+	if (UseEventLogger)
+		WriteLogDefines(file, "MACH_MSG_LOG_USER");
+	fprintf(file, "\n");
+}
+
+static void
+WriteOneMachErrorDefine(FILE *file, const char *name, boolean_t timeout)
+{
+	fprintf(file, "#ifndef\t%s\n", name);
+	fprintf(file, "#define\t%s(_R_) { \\\n", name);
+	fprintf(file, "\tswitch (_R_) { \\\n");
+    fprintf(file, "\tcase MACH_SEND_INVALID_REPLY: \\\n");
+    fprintf(file, "\tcase MACH_RCV_INVALID_NAME: \\\n");
+    fprintf(file, "\tcase MACH_RCV_IN_SET: \\\n");
+    fprintf(file, "\tcase MACH_RCV_PORT_DIED: \\\n");
+    fprintf(file, "\tcase MACH_RCV_PORT_CHANGED: \\\n");
+    fprintf(file, "\tcase MACH_SEND_INVALID_MEMORY: \\\n");
+    fprintf(file, "\tcase MACH_SEND_INVALID_RIGHT: \\\n");
+    fprintf(file, "\tcase MACH_SEND_INVALID_TYPE: \\\n");
+    fprintf(file, "\tcase MACH_SEND_MSG_TOO_SMALL: \\\n");
+    fprintf(file, "\tcase MACH_SEND_INVALID_RT_OOL_SIZE: \\\n");
+    if (timeout)
+		fprintf(file, "\tcase MACH_RCV_TIMED_OUT: \\\n");
+	fprintf(file, "\t\tmig_dealloc_reply_port(InP->Head.msgh_reply_port); \\\n");
+	fprintf(file, "\t} \\\n}\n");
+	fprintf(file, "#endif\t/* %s */\n", name);
+	fprintf(file, "\n");
+}
+
+static void
+WriteMachErrorDefines(FILE *file)
+{
+	WriteOneMachErrorDefine(file, "__MachMsgErrorWithTimeout", TRUE);
+	WriteOneMachErrorDefine(file, "__MachMsgErrorWithoutTimeout", FALSE);
+}
+
+static void
+WriteMIGCheckDefines(FILE *file)
+{
+	fprintf(file, "#define\t__MIG_check__Reply__%s_subsystem__ 1\n", SubsystemName);
+	fprintf(file, "\n");
+}
+  
+static void
+WriteNDRDefines(FILE *file)
+{
+	fprintf(file, "#define\t__NDR_convert__Reply__%s_subsystem__ 1\n", SubsystemName);
+	fprintf(file, "#define\t__NDR_convert__mig_reply_error_subsystem__ 1\n");
+	fprintf(file, "\n");
+}
+
+/*************************************************************
+ * Writes the standard #includes, #defines, and
+ * RCS declaration. Called by WriteUser.
+ *************************************************************/
+static void
+WriteProlog(FILE *file, statement_t *stats)
+{
+	WriteIdentificationString(file);
+	WriteMIGCheckDefines(file);
+	if (CheckNDR)
+		WriteNDRDefines(file);
+	WriteMyIncludes(file, stats);
+	WriteBogusDefines(file);
+	WriteMachErrorDefines(file);
+	WriteApplDefaults(file, "Send");
+	WriteGlobalDecls(file);
+}
+
+/*ARGSUSED*/
+static void
+WriteEpilog(FILE *file __unused)
+{
+}
+
+static string_t
+WriteHeaderPortType(argument_t *arg)
+{
+	if (arg->argType->itInName == MACH_MSG_TYPE_POLYMORPHIC)
+		return arg->argPoly->argVarName;
+	else
+		return arg->argType->itInNameStr;
+}
+
+static void
+WriteRequestHead(FILE *file, routine_t *rt)
+{
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest)
+		fprintf(file, "ready_to_send:\n");
+  
+	if (rt->rtMaxRequestPos > 0) {
+		if (rt->rtOverwrite)
+			fprintf(file, "\tInP = &MessRequest;\n");
+		else
+			fprintf(file, "\tInP = &Mess%sIn;\n",
+					(rtMessOnStack(rt) ? "." : "->"));
+	}
+	fprintf(file, "\tInP->Head.msgh_bits =");
+	if (rt->rtRetCArg == argNULL && !rt->rtSimpleRequest)
+		fprintf(file, " MACH_MSGH_BITS_COMPLEX|");
+	fprintf(file, "\n");
+    fprintf(file, "\t\tMACH_MSGH_BITS(%s, %s);\n",
+			WriteHeaderPortType(rt->rtRequestPort),
+			WriteHeaderPortType(rt->rtReplyPort));
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest) {
+		fprintf(file, "\tif (!%s)\n", rt->rtRetCArg->argVarName);
+		fprintf(file, "\t\tInP->Head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;\n");
+	}
+  
+  
+	fprintf(file, "\t/* msgh_size passed as argument */\n");
+  
+	/*
+	 * KernelUser stubs need to cast the request and reply ports
+	 * from ipc_port_t to mach_port_t.
+	 */
+  
+#ifdef MIG_KERNEL_PORT_CONVERSION
+	if (IsKernelUser)
+		fprintf(file, "\tInP->%s = (mach_port_t) %s;\n",
+				rt->rtRequestPort->argMsgField,
+				rt->rtRequestPort->argVarName);
+	else
+#endif	  
+		fprintf(file, "\tInP->%s = %s;\n",
+				rt->rtRequestPort->argMsgField,
+				rt->rtRequestPort->argVarName);
+  
+	if (akCheck(rt->rtReplyPort->argKind, akbUserArg)) {
+#ifdef MIG_KERNEL_PORT_CONVERSION
+		if (IsKernelUser)
+			fprintf(file, "\tInP->%s = (mach_port_t) %s;\n", rt->rtReplyPort->argMsgField, rt->rtReplyPort->argVarName);
+		else
+#endif
+			fprintf(file, "\tInP->%s = %s;\n", rt->rtReplyPort->argMsgField, rt->rtReplyPort->argVarName);
+	}
+	else if (rt->rtOneWay)
+		fprintf(file, "\tInP->%s = MACH_PORT_NULL;\n", rt->rtReplyPort->argMsgField);
+	else
+		fprintf(file, "\tInP->%s = mig_get_reply_port();\n", rt->rtReplyPort->argMsgField);
+  
+	fprintf(file, "\tInP->Head.msgh_id = %d;\n", rt->rtNumber + SubsystemBase);
+
+
+	if (IsVoucherCodeAllowed && !IsKernelUser && !IsKernelServer) {
+		fprintf(file, "\t\n/* BEGIN VOUCHER CODE */\n\n");
+		fprintf(file, "#ifdef USING_VOUCHERS\n");
+		fprintf(file, "\tif (voucher_mach_msg_set != NULL) {\n");
+		fprintf(file, "\t\tvoucher_mach_msg_set(&InP->Head);\n");
+		fprintf(file, "\t}\n");
+		fprintf(file, "#endif // USING_VOUCHERS\n");
+		fprintf(file, "\t\n/* END VOUCHER CODE */\n");
+	}
+}
+
+/*************************************************************
+ *  Writes declarations for the message types, variables
+ *  and return  variable if needed. Called by WriteRoutine.
+ *************************************************************/
+static void
+WriteVarDecls(FILE *file, routine_t *rt)
+{
+    register u_int i;
+  
+	if (rt->rtOverwrite) {
+		fprintf(file, "\tRequest MessRequest;\n");
+		fprintf(file, "\tRequest *InP = &MessRequest;\n\n");
+    
+		fprintf(file, "\tunion {\n");
+		fprintf(file, "\t\tOverwriteTemplate In;\n");
+		fprintf(file, "\t\tReply Out;\n");
+		fprintf(file, "\t} MessReply;\n");
+    
+		fprintf(file, "\tOverwriteTemplate *InOvTemplate = &MessReply.In;\n");
+		fprintf(file, "\tReply *Out0P = &MessReply.Out;\n");
+		for (i = 1; i <= rt->rtMaxReplyPos; i++)
+			fprintf(file, "\t" "Reply *Out%dP = NULL;\n", i);
+	}
+	else {
+		if (rtMessOnStack(rt))
+			fprintf(file, "\tunion {\n");
+		else
+			fprintf(file, "\tunion %sMessU {\n", rt->rtName);
+		fprintf(file, "\t\tRequest In;\n");
+		if (!rt->rtOneWay)
+			fprintf(file, "\t\tReply Out;\n");
+		if (rtMessOnStack(rt))
+			fprintf(file, "\t} Mess;\n");
+		else
+			fprintf(file, "\t} *Mess = (union %sMessU *) %s(sizeof(*Mess));\n",
+					rt->rtName, MessAllocRoutine);
+		fprintf(file, "\n");
+    
+		fprintf(file, "\tRequest *InP = &Mess%sIn;\n", (rtMessOnStack(rt) ? "." : "->"));
+		if (!rt->rtOneWay) {
+			fprintf(file, "\tReply *Out0P = &Mess%sOut;\n", (rtMessOnStack(rt) ? "." : "->"));
+			for (i = 1; i <= rt->rtMaxReplyPos; i++)
+				fprintf(file, "\t" "Reply *Out%dP = NULL;\n", i);
+		}
+	}
+  
+	fprintf(file, "\n");
+  
+	fprintf(file, "\tmach_msg_return_t msg_result;\n");
+  
+	/* if request is variable, we need msgh_size_delta and msgh_size */
+	if (rt->rtNumRequestVar > 0)
+		fprintf(file, "\tunsigned int msgh_size;\n");
+	if (rt->rtMaxRequestPos > 0)
+		fprintf(file, "\tunsigned int msgh_size_delta;\n");
+	if (rt->rtNumRequestVar > 1 || rt->rtMaxRequestPos > 0)
+		fprintf(file, "\n");
+  
+	if (rt->rtUserImpl) {
+		fprintf(file, "\tmach_msg_max_trailer_t *TrailerP;\n");
+		fprintf(file, "#if\t__MigTypeCheck\n");
+		fprintf(file, "\tunsigned int trailer_size;\n");
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	fprintf(file, "\n");
+	fprintf(file, "#ifdef\t__MIG_check__Reply__%s_t__defined\n", rt->rtName);
+	fprintf(file, "\tkern_return_t check_result;\n");
+	fprintf(file, "#endif\t/* __MIG_check__Reply__%s_t__defined */\n", rt->rtName);
+	fprintf(file, "\n");
+	WriteApplMacro(file, "Send", "Declare", rt);
+	fprintf(file, "\n");
+}
+
+static void
+WriteReturn(FILE *file, routine_t *rt, const char *before, const char *value, const char *after)
+{
+    if (rtMessOnStack(rt) && value != stRetCode)
+    {
+		/* get the easy case (no braces needed) out of the way */
+		fprintf(file, "%sreturn%s%s;%s",
+				before, (*value ? " " : ""), value, after);
+		return;
+    }
+
+    /* get the easy case (no braces needed) out of the way */
+    if (rtMessOnStack(rt))
+    {
+		if (value == stRetNone)
+			fprintf(file, "%sreturn;%s",
+					before, after);
+		else if (value == stRetCode)
+			fprintf(file, "%sreturn Out0P->RetCode;%s",
+					before, after);
+		else
+			fprintf(file, "%sreturn %s;%s",
+					before, value, after);
+		return;
+    }
+  
+	if (value == stRetCode) {
+		fprintf(file, "%s{\n%s\t%s ReturnValue;\n", before, before, ReturnTypeStr(rt));
+		fprintf(file, "%s\tReturnValue = Out0P->RetCode;\n%s\t", before, before);
+	}
+	else {
+		fprintf(file, "%s{ ", before);
+	}
+  
+	fprintf(file, "%s((char *) Mess, sizeof(*Mess)); ", MessFreeRoutine);
+  
+	if (value == stRetCode)
+		fprintf(file, "return ReturnValue;\n%s}%s", before, after);
+	else if (value == stRetNone)
+		fprintf(file, "return; }%s", after);
+	else
+		fprintf(file, "return %s; }%s", value, after);
+}
+
+static void
+WriteRetCodeArg(FILE *file, register routine_t *rt)
+{
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest) {
+		register argument_t *arg = rt->rtRetCArg;
+    
+		fprintf(file, "\tif (%s) {\n", arg->argVarName);
+		fprintf(file, "\t\t((mig_reply_error_t *)InP)->RetCode = %s;\n", arg->argVarName);
+		fprintf(file, "\t\t((mig_reply_error_t *)InP)->NDR = NDR_record;\n");
+		fprintf(file, "\t\tgoto ready_to_send;\n");
+		fprintf(file, "\t}\n\n");
+	}
+}
+
+/*************************************************************
+ *   Writes the logic to check for a message send timeout, and
+ *   deallocate any relocated ool data so as not to leak.
+ *************************************************************/
+static void
+WriteMsgCheckForTimeout(FILE *file, routine_t *rt)
+{
+	if (rt->rtWaitTime != argNULL) {    /* no reason to test for timeout if no timeout was specified... */
+		argument_t  *arg_ptr;
+		fputs("\n\t"    "if (msg_result == MACH_SEND_TIMED_OUT) {" "\n", file);
+    
+		// iterate over arg list
+		for (arg_ptr = rt->rtArgs; arg_ptr != NULL; arg_ptr = arg_ptr->argNext) {
+      
+			//  if argument contains ool data
+			if (akCheck(arg_ptr->argKind, akbSendKPD) && arg_ptr->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR) {
+				//    generate code to test current arg address vs. address before the msg_send call
+				//    if not at the same address, mig_deallocate the argument
+				fprintf(file, "\t\tif((vm_offset_t) InP->%s.address != (vm_offset_t) %s)\n",
+						arg_ptr->argVarName, arg_ptr->argVarName);
+				fprintf(file, "\t\t\t"   "mig_deallocate((vm_offset_t) InP->%s.address, "
+						"(vm_size_t) InP->%s.size);\n", arg_ptr->argVarName, arg_ptr->argVarName);
+			}
+		}
+    
+		fputs("\t"      "}" "\n\n", file);
+	}
+	return;
+}
+
+/*************************************************************
+ *   Writes the send call when there is to be no subsequent
+ *   receive. Called by WriteRoutine SimpleRoutines
+ *************************************************************/
+static void
+WriteMsgSend(FILE *file, routine_t *rt)
+{
+    const char *SendSize = "";
+	char string[MAX_STR_LEN];
+  
+	if (rt->rtNumRequestVar == 0)
+		SendSize = "sizeof(Request)";
+	else
+		SendSize = "msgh_size";
+  
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest) {
+		sprintf(string, "(%s) ? sizeof(mig_reply_error_t) : ", 
+				rt->rtRetCArg->argVarName);
+		SendSize = strconcat(string, SendSize);
+	}
+  
+	if (IsKernelUser) {
+		fprintf(file, "#if\t__MigKernelSpecificCode\n");
+		fprintf(file, "\tmsg_result = mach_msg_send_from_kernel(");
+		fprintf(file, "&InP->Head, %s);\n", SendSize);
+		fprintf(file, "#else\n");
+	}
+	fprintf(file, "\tmsg_result = mach_msg("
+			"&InP->Head, MACH_SEND_MSG|%s%s, %s, 0, MACH_PORT_NULL, %s, MACH_PORT_NULL);\n",
+			rt->rtWaitTime !=argNULL ? "MACH_SEND_TIMEOUT|" : "",
+			rt->rtMsgOption->argVarName,
+			SendSize,
+			rt->rtWaitTime != argNULL ? rt->rtWaitTime->argVarName:"MACH_MSG_TIMEOUT_NONE");
+  
+	if (IsKernelUser) {
+		fprintf(file, "#endif /* __MigKernelSpecificCode */\n");
+	}
+	WriteApplMacro(file, "Send", "After", rt);
+  
+	WriteMsgCheckForTimeout(file, rt);
+  
+	WriteReturn(file, rt, "\t", "msg_result", "\n");
+}
+
+/*************************************************************
+ *  Writes to code to check for error returns from receive.
+ *  Called by WriteMsgSendReceive and WriteMsgRPC
+ *************************************************************/
+static void
+WriteMsgCheckReceive(FILE *file, routine_t *rt, const char *success)
+{
+	fprintf(file, "\tif (msg_result != %s) {\n", success);
+    if (!akCheck(rt->rtReplyPort->argKind, akbUserArg) && !IsKernelUser)
+	{
+		/* If we aren't using a user-supplied reply port, then
+		   deallocate the reply port when it is invalid or
+		   for TIMED_OUT errors. */
+#ifdef DeallocOnAnyError
+		fprintf(file,
+				"\t\tmig_dealloc_reply_port(InP->Head.msgh_reply_port);\n");
+#else
+		if (rt->rtWaitTime != argNULL)
+			fprintf(file, "\t\t__MachMsgErrorWithTimeout(msg_result);\n");
+		else
+			fprintf(file, "\t\t__MachMsgErrorWithoutTimeout(msg_result);\n");
+#endif
+	}
+	WriteReturnMsgError(file, rt, TRUE, argNULL, "msg_result");
+	fprintf(file, "\t}\n");
+}
+
+/*************************************************************
+ *  Writes the send and receive calls and code to check
+ *  for errors. Normally the rpc code is generated instead
+ *  although, the subsytem can be compiled with the -R option
+ *  which will cause this code to be generated. Called by
+ *  WriteRoutine if UseMsgRPC option is false.
+ *************************************************************/
+static void
+WriteMsgSendReceive(FILE *file, routine_t *rt)
+{
+    const char *SendSize = "";
+	char string[MAX_STR_LEN];
+  
+	if (rt->rtNumRequestVar == 0)
+		SendSize = "sizeof(Request)";
+	else
+		SendSize = "msgh_size";
+  
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest) {
+		sprintf(string, "(%s) ? sizeof(mig_reply_error_t) : ", 
+				rt->rtRetCArg->argVarName);
+		SendSize = strconcat(string, SendSize);
+	}
+  
+	/* IsKernelUser to be done! */
+	fprintf(file, "\tmsg_result = mach_msg(&InP->Head, MACH_SEND_MSG|%s%s, %s, 0, ", rt->rtWaitTime != argNULL ? "MACH_SEND_TIMEOUT|" : "", rt->rtMsgOption->argVarName, SendSize);
+	fprintf(file, " MACH_PORT_NULL, %s, MACH_PORT_NULL);\n",
+#if !USE_IMMEDIATE_SEND_TIMEOUT
+			(rt->rtWaitTime != argNULL) ? rt->rtWaitTime->argVarName :
+#endif
+			"MACH_MSG_TIMEOUT_NONE");
+	fprintf(file, "\tif (msg_result != MACH_MSG_SUCCESS)\n");
+	WriteReturnMsgError(file, rt, TRUE, argNULL, "msg_result");
+	fprintf(file, "\n");
+  
+	fprintf(file, "\tmsg_result = mach_msg(&Out0P->Head, MACH_RCV_MSG|%s%s%s, 0, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_local_port, %s, MACH_PORT_NULL);\n",
+			rt->rtUserImpl != 0 ? "MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|" : "",
+			(rt->rtWaitTime != argNULL && akIdent(rt->rtWaitTime->argKind) == akeWaitTime) ? "MACH_RCV_TIMEOUT|" : "",
+			rt->rtMsgOption->argVarName,
+			(rt->rtWaitTime != argNULL && akIdent(rt->rtWaitTime->argKind) == akeWaitTime) ? rt->rtWaitTime->argVarName : "MACH_MSG_TIMEOUT_NONE");
+	WriteApplMacro(file, "Send", "After", rt);
+	WriteMsgCheckReceive(file, rt, "MACH_MSG_SUCCESS");
+	fprintf(file, "\n");
+}
+
+/*************************************************************
+ *  Writes the rpc call and the code to check for errors.
+ *  This is the default code to be generated. Called by WriteRoutine
+ *  for all routine types except SimpleRoutine.
+ *************************************************************/
+static void
+WriteMsgRPC(FILE *file, routine_t *rt)
+{
+    const char *SendSize = "";
+	char string[MAX_STR_LEN];
+  
+	if (rt->rtNumRequestVar == 0)
+		SendSize = "sizeof(Request)";
+	else
+		SendSize = "msgh_size";
+  
+	if (rt->rtRetCArg != argNULL && !rt->rtSimpleRequest) {
+		sprintf(string, "(%s) ? (mach_msg_size_t)sizeof(mig_reply_error_t) : ", rt->rtRetCArg->argVarName);
+		SendSize = strconcat(string, SendSize);
+	}
+  
+	if (IsKernelUser) {
+		fprintf(file, "#if\t(__MigKernelSpecificCode) || (_MIG_KERNELSPECIFIC_CODE_)\n");
+		fprintf(file, "\tmsg_result = mach_msg_rpc_from_kernel(&InP->Head, %s, (mach_msg_size_t)sizeof(Reply));\n", SendSize);
+		fprintf(file, "#else\n");
+	}
+	if (rt->rtOverwrite) {
+		fprintf(file, "\tmsg_result = mach_msg_overwrite(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_OVERWRITE|%s%s%s, %s, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, %s, MACH_PORT_NULL, ",
+				rt->rtUserImpl != 0 ? "MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|" : "",
+				rt->rtWaitTime != argNULL ? 
+				(akIdent(rt->rtWaitTime->argKind) == akeWaitTime ? "MACH_SEND_TIMEOUT|MACH_RCV_TIMEOUT|" : "MACH_SEND_TIMEOUT|") : "",
+				rt->rtMsgOption->argVarName,
+				SendSize,
+				rt->rtWaitTime != argNULL? rt->rtWaitTime->argVarName : "MACH_MSG_TIMEOUT_NONE");
+		fprintf(file, " &InOvTemplate->Head, (mach_msg_size_t)sizeof(OverwriteTemplate));\n");
+	}
+	else {
+		fprintf(file, "\tmsg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|%s%s%s, %s, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, %s, MACH_PORT_NULL);\n",
+				rt->rtUserImpl != 0 ? "MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|" : "",
+				rt->rtWaitTime != argNULL ?
+				(akIdent(rt->rtWaitTime->argKind) == akeWaitTime ? "MACH_SEND_TIMEOUT|MACH_RCV_TIMEOUT|" : "MACH_SEND_TIMEOUT|") : "",
+				rt->rtMsgOption->argVarName,
+				SendSize,
+				rt->rtWaitTime != argNULL? rt->rtWaitTime->argVarName : "MACH_MSG_TIMEOUT_NONE");
+	}
+	if (IsKernelUser)
+		fprintf(file,"#endif /* __MigKernelSpecificCode */\n");
+	WriteApplMacro(file, "Send", "After", rt);
+  
+	WriteMsgCheckForTimeout(file, rt);
+  
+	WriteMsgCheckReceive(file, rt, "MACH_MSG_SUCCESS");
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_Pack discipline for Port types.
+ */
+static void
+WriteKPD_port(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *subindex = "";
+    const char *recast = "";
+	char firststring[MAX_STR_LEN];
+	char string[MAX_STR_LEN];
+    const char *ref = arg->argByReferenceUser ? "*" : "";
+	ipc_type_t *real_it;
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, TRUE, FALSE, it->itVarArray, arg, TRUE);
+		(void)sprintf(firststring, "\t*ptr");
+		(void)sprintf(string, "\tptr->");
+		subindex = "[i]";
+		real_it = it->itElement;
+    } else {
+		(void)sprintf(firststring, "InP->%s", arg->argMsgField);
+		(void)sprintf(string, "InP->%s.", arg->argMsgField);
+		real_it = it;
+	}
+  
+#ifdef MIG_KERNEL_PORT_CONVERSION
+	if (IsKernelUser && streql(real_it->itUserType, "ipc_port_t"))
+		recast = "(mach_port_t)";
+#endif
+	fprintf(file, "#if\tUseStaticTemplates\n");
+    fprintf(file, "\t%s = %s;\n", firststring,
+			arg->argTTName);
+	/* ref is required also in the Request part, because of inout parameters */
+    fprintf(file, "\t%sname = %s%s%s%s;\n", string,
+			recast, ref, arg->argVarName, subindex);
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbSendSnd)) {
+		register argument_t *poly = arg->argPoly;
+    
+		fprintf(file, "\t%sdisposition = %s%s;\n", string, 
+				poly->argByReferenceUser ? "*" : "", poly->argVarName);
+	}
+	fprintf(file, "#else\t/* UseStaticTemplates */\n");
+    fprintf(file, "\t%sname = %s%s%s%s;\n", string,
+			recast, ref, arg->argVarName, subindex);
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbSendSnd)) {
+		register argument_t *poly = arg->argPoly;
+    
+        fprintf(file, "\t%sdisposition = %s%s;\n", string,
+				poly->argByReferenceUser ? "*" : "", poly->argVarName);
+    } else 
+		fprintf(file, "\t%sdisposition = %s;\n", string,
+				it->itInNameStr);
+	fprintf(file, "\t%stype = MACH_MSG_PORT_DESCRIPTOR;\n", string);
+	fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+	if (IS_MULTIPLE_KPD(it))  {
+		fprintf(file, "\t    }\n");
+		if (it->itVarArray) {
+			fprintf(file, "\t    for (i = %s; i < %d; ptr++, i++) {\n", 
+					arg->argCount->argVarName, it->itKPD_Number);
+			/* fill the rest of the statically allocated KPD entries with MACH_PORT_NULL */
+			fprintf(file, "#if\tUseStaticTemplates\n");
+    	    fprintf(file, "\t%s = %s;\n", firststring,
+					arg->argTTName);
+			fprintf(file, "#else\t/* UseStaticTemplates */\n");
+			fprintf(file, "\t%sname = MACH_PORT_NULL;\n", string);
+			fprintf(file, "\t%stype = MACH_MSG_PORT_DESCRIPTOR;\n", string);
+			fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+			fprintf(file, "\t    }\n");
+		}
+		fprintf(file, "\t}\n");
+	}
+	fprintf(file, "\n");
+}
+
+static void
+WriteKPD_ool_varsize(FILE *file, argument_t *arg, const char *who, const char *where, boolean_t iscomplex)
+{
+	register ipc_type_t *it = arg->argType;
+	register argument_t *count;
+    const char *cref;
+  
+	if (iscomplex) {
+		it = it->itElement;
+		count = arg->argSubCount;
+    } else 
+		count = arg->argCount;
+	cref = count->argByReferenceUser ? "*" : "";
+  
+	/* size has to be expressed in bytes! */
+	if (count->argMultiplier > 1 || it->itSize > 8)
+        fprintf(file, "\t%s->%s = %s%s%s * %d;\n", who, where,
+				cref, count->argVarName, 
+				(iscomplex)? "[i]" : "", 
+				count->argMultiplier * it->itSize / 8);	
+	else
+		fprintf(file, "\t%s->%s = %s%s%s;\n", who, where,
+				cref, count->argVarName,
+				(iscomplex)? "[i]" : "");
+}
+
+/*
+ * argKPD_Pack discipline for out-of-line types.
+ */
+static void
+WriteKPD_ool(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *ref = arg->argByReferenceUser ? "*" : "";
+	char firststring[MAX_STR_LEN];
+	char string[MAX_STR_LEN];
+	boolean_t VarArray;
+	u_int howmany, howbig;
+    const char *subindex;
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, TRUE, FALSE, it->itVarArray, arg, TRUE);
+		(void)sprintf(firststring, "\t*ptr");
+		(void)sprintf(string, "\tptr->");
+		VarArray = it->itElement->itVarArray;
+		howmany = it->itElement->itNumber;
+		howbig = it->itElement->itSize;
+		subindex = "[i]";
+    } else {
+		(void)sprintf(firststring, "InP->%s", arg->argMsgField);
+		(void)sprintf(string, "InP->%s.", arg->argMsgField);
+		VarArray = it->itVarArray;
+		howmany = it->itNumber;
+		howbig = it->itSize;
+		subindex = "";
+	}
+  
+	fprintf(file, "#if\tUseStaticTemplates\n");
+  
+	fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName);
+    fprintf(file, "\t%saddress = (void *)(%s%s%s);\n", 
+			string, ref, arg->argVarName, subindex);
+	if (VarArray) {
+		if (IS_MULTIPLE_KPD(it))
+			WriteKPD_ool_varsize(file, arg, "\tptr", "size", TRUE);
+		else
+			WriteKPD_ool_varsize(file, arg, "InP",
+								 strconcat(arg->argMsgField, ".size"), FALSE);
+	}
+	if (arg->argDeallocate == d_MAYBE)
+		fprintf(file, "\t%sdeallocate =  %s;\n", 
+				string, arg->argDealloc->argVarName); 
+  
+	fprintf(file, "#else\t/* UseStaticTemplates */\n");
+  
+    fprintf(file, "\t%saddress = (void *)(%s%s%s);\n", 
+			string, ref, arg->argVarName, subindex);
+	if (VarArray)
+		if (IS_MULTIPLE_KPD(it))
+			WriteKPD_ool_varsize(file, arg, "\tptr", "size", TRUE);
+		else
+			WriteKPD_ool_varsize(file, arg, "InP",
+								 strconcat(arg->argMsgField, ".size"), FALSE);
+    else
+        fprintf(file, "\t%ssize = %d;\n", string, 
+				(howmany * howbig + 7)/8);
+	if (arg->argDeallocate == d_MAYBE)
+		fprintf(file, "\t%sdeallocate =  %s;\n", string,
+				arg->argDealloc->argVarName); 
+	else
+		fprintf(file, "\t%sdeallocate =  %s;\n", string,
+				(arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
+    fprintf(file, "\t%scopy = %s;\n", string,
+			(arg->argFlags & flPhysicalCopy) ? "MACH_MSG_PHYSICAL_COPY" : "MACH_MSG_VIRTUAL_COPY");
+#ifdef ALIGNMENT
+    fprintf(file, "\t%salignment = MACH_MSG_ALIGN_%d;\n", string,
+			(it->itElement->itSize < 8) ? 1 : it->itElement->itSize / 8);
+#endif
+	fprintf(file, "\t%stype = MACH_MSG_OOL_DESCRIPTOR;\n", string);
+  
+	fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+	if (IS_MULTIPLE_KPD(it)) {
+		fprintf(file, "\t    }\n");
+		if (it->itVarArray) {
+			fprintf(file, "\t    for (i = %s; i < %d; ptr++, i++) {\n", 
+					arg->argCount->argVarName, it->itKPD_Number);
+			/* fill the rest of the statically allocated KPD entries with size NULL */
+			fprintf(file, "#if\tUseStaticTemplates\n");
+			fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName);
+			if (!VarArray)
+				fprintf(file, "\t%ssize = 0;\n", string);
+			/* otherwise the size in the template would be != 0! */
+			fprintf(file, "#else\t/* UseStaticTemplates */\n");
+			fprintf(file, "\t%ssize = 0;\n", string);
+			fprintf(file, "\t%stype = MACH_MSG_OOL_DESCRIPTOR;\n", string);
+			fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+			fprintf(file, "\t    }\n");
+		}
+		fprintf(file, "\t}\n");
+	}
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_Pack discipline for out-of-line Port types.
+ */
+static void
+WriteKPD_oolport(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *ref = arg->argByReferenceUser ? "*" : "";
+	register argument_t *count;
+	boolean_t VarArray;
+	string_t howstr;
+	u_int howmany;
+    const char *subindex;
+	char firststring[MAX_STR_LEN];
+	char string[MAX_STR_LEN];
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, TRUE, FALSE, it->itVarArray, arg, TRUE);
+		(void)sprintf(firststring, "\t*ptr");
+		(void)sprintf(string, "\tptr->");
+		VarArray = it->itElement->itVarArray;
+		howmany = it->itElement->itNumber;
+		howstr = it->itElement->itInNameStr;
+		count = arg->argSubCount;
+		subindex = "[i]";
+    } else {
+		(void)sprintf(firststring, "InP->%s", arg->argMsgField);
+		(void)sprintf(string, "InP->%s.", arg->argMsgField);
+		VarArray = it->itVarArray;
+		howmany = it->itNumber;
+		howstr = it->itInNameStr;
+		count = arg->argCount;
+		subindex = "";
+	}
+  
+	fprintf(file, "#if\tUseStaticTemplates\n");
+  
+	fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName);
+    fprintf(file, "\t%saddress = (void *)(%s%s%s);\n", string,
+			ref, arg->argVarName, subindex);
+	if (VarArray)
+        fprintf(file, "\t%scount = %s%s%s;\n", string, 
+				count->argByReferenceUser ? "*" : "",
+				count->argVarName, subindex);
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbSendSnd)) {
+		register argument_t *poly = arg->argPoly;
+        const char *pref = poly->argByReferenceUser ? "*" : "";
+    
+        fprintf(file, "\t%sdisposition = %s%s;\n", string,
+				pref, poly->argVarName);
+	}
+	if (arg->argDeallocate == d_MAYBE)
+        fprintf(file, "\t%sdeallocate =  %s;\n", string,
+				arg->argDealloc->argVarName);
+  
+	fprintf(file, "#else\t/* UseStaticTemplates */\n");
+  
+    fprintf(file, "\t%saddress = (void *)(%s%s%s);\n", 
+			string, ref, arg->argVarName, subindex);
+	if (VarArray)
+        fprintf(file, "\t%scount = %s%s%s;\n", string,
+				count->argByReferenceUser ? "*" : "",
+				count->argVarName, subindex);
+	else
+        fprintf(file, "\t%scount = %d;\n", string,
+				howmany);
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbSendSnd)) {
+		register argument_t *poly = arg->argPoly;
+        const char *pref = poly->argByReferenceUser ? "*" : "";
+    
+        fprintf(file, "\t%sdisposition = %s%s;\n", 
+				string, pref, poly->argVarName);
+    } else
+        fprintf(file, "\t%sdisposition = %s;\n", 
+				string, howstr);
+	if (arg->argDeallocate == d_MAYBE)
+        fprintf(file, "\t%sdeallocate =  %s;\n", string,
+				arg->argDealloc->argVarName);
+	else
+        fprintf(file, "\t%sdeallocate =  %s;\n", string,
+				(arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
+	fprintf(file, "\t%stype = MACH_MSG_OOL_PORTS_DESCRIPTOR;\n", string);
+  
+	fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+	fprintf(file, "\n");
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		fprintf(file, "\t    }\n");
+		if (it->itVarArray) {
+            fprintf(file, "\t    for (i = %s; i < %d; ptr++, i++) {\n",
+					arg->argCount->argVarName, it->itKPD_Number);
+			/* fill the rest of the statically allocated KPD entries with size NULL */
+			fprintf(file, "#if\tUseStaticTemplates\n");
+			fprintf(file, "\t%s = %s;\n", firststring, arg->argTTName);
+			if (!VarArray)
+				fprintf(file, "\t%scount = 0;\n", string);
+			/* otherwise the size in the template would be != 0! */
+			fprintf(file, "#else\t/* UseStaticTemplates */\n");
+			fprintf(file, "\t%scount = 0;\n", string);
+			fprintf(file, "\t%stype = MACH_MSG_OOL_PORTS_DESCRIPTOR;\n", string);
+			fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+			fprintf(file, "\t    }\n");
+		}
+		fprintf(file, "\t}\n");
+	}
+	fprintf(file, "\n");
+}
+
+static void
+WriteOverwriteTemplate(FILE *file, routine_t *rt)
+{
+	register argument_t *arg;
+	char string[MAX_STR_LEN];
+    const char *subindex = "";
+	boolean_t finish = FALSE;
+  
+	fprintf(file, "\t/* Initialize the template for overwrite */\n");
+    fprintf(file, "\tInOvTemplate->msgh_body.msgh_descriptor_count = %d;\n",
+			rt->rtOverwriteKPDs);
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)  {
+		register ipc_type_t *it = arg->argType;
+		const char *ref = arg->argByReferenceUser ? "*" : "";
+		argument_t *count;
+		const char *cref;
+		boolean_t VarIndex;
+		u_int howmany, howbig;
+    
+		if (akCheck(arg->argKind, akbOverwrite)) {
+			if (arg->argFlags & flOverwrite) {
+				if (IS_MULTIPLE_KPD(it)) {
+					WriteKPD_Iterator(file, FALSE, TRUE, it->itVarArray, arg, TRUE);
+					if (it->itVarArray)
+						finish = TRUE;
+					sprintf(string, "\tptr->");
+					subindex = "[i]";
+					count = arg->argSubCount;
+					VarIndex = it->itElement->itVarArray;
+					howmany = it->itElement->itNumber;
+					howbig = it->itElement->itSize;
+				} else {
+					sprintf(string, "InOvTemplate->%s.", arg->argMsgField);
+					subindex = "";
+					count = arg->argCount;
+					VarIndex = it->itVarArray;
+					howmany = it->itNumber;
+					howbig = it->itSize;
+				}
+        
+				fprintf(file, "\t%saddress = (void *) %s%s%s;\n", string, 
+						ref, arg->argVarName, subindex);	
+        
+				if (it->itPortType) {
+					fprintf(file, "\t%scount = ", string);
+					if (VarIndex) {
+						cref = count->argByReferenceUser ? "*" : "";
+						fprintf(file, "%s%s%s;\n", cref, count->argVarName, subindex);
+					} else
+						fprintf(file, "%d;\n", howmany);
+				} else {
+					fprintf(file, "\t%ssize = ", string);
+					if (VarIndex) {
+						cref = count->argByReferenceUser ? "*" : "";
+						if (count->argMultiplier > 1 || howbig > 8)
+							fprintf(file, "%s%s%s * %d;\n", cref, count->argVarName, subindex,
+									count->argMultiplier * howbig / 8);
+						else
+							fprintf(file, "%s%s%s;\n", cref, count->argVarName, subindex);
+					}
+					else
+						fprintf(file, "\t%ssize = %d;\n", string, (howmany * howbig + 7)/8);
+				}
+				fprintf(file, "\t%scopy = MACH_MSG_OVERWRITE;\n", string);
+				fprintf(file, "\t%stype = MACH_MSG_OOL_%sDESCRIPTOR;\n", string,
+						(it->itPortType) ? "PORTS_" : "");
+				if (IS_MULTIPLE_KPD(it))
+					fprintf(file, "\t    }\n");
+				if (finish) {
+					fprintf(file, "\t    for (i = %s%s; i < %d; ptr++, i++) {\n", 
+							(arg->argCount->argByReferenceUser) ? "*" : "", 
+							arg->argCount->argVarName, it->itKPD_Number);
+					fprintf(file, "\t\tptr->copy = MACH_MSG_ALLOCATE;\n");
+					fprintf(file, "\t\tptr->type = MACH_MSG_OOL_%sDESCRIPTOR;\n",
+							(it->itPortType) ? "PORTS_" : "");
+					fprintf(file, "\t    }\n");
+				}
+				if (IS_MULTIPLE_KPD(it))
+					fprintf(file, "\t}\n");
+			} else {
+				/* just a placeholder */
+				if (IS_MULTIPLE_KPD(it)) {
+					WriteKPD_Iterator(file, FALSE, TRUE, FALSE, arg, TRUE);
+					fprintf(file, "\t\tptr->copy = MACH_MSG_ALLOCATE;\n");
+					fprintf(file, "\t\tptr->type = MACH_MSG_OOL_%sDESCRIPTOR;\n",
+							(it->itPortType) ? "PORTS_" : "");
+					fprintf(file, "\t    }\n\t}\n");
+				}
+				else {
+					fprintf(file, "\tInOvTemplate->%s.copy = MACH_MSG_ALLOCATE;\n", arg->argMsgField);
+					/* not sure whether this is needed */
+					fprintf(file, "\tInOvTemplate->%s.type = MACH_MSG_OOL_%sDESCRIPTOR;\n", 
+							arg->argMsgField, (it->itPortType) ? "PORTS_" : "");
+				}
+			}
+		}
+	}
+	fprintf(file, "\n");
+}
+
+/*************************************************************
+ *  Writes code to copy an argument into the request message.
+ *  Called by WriteRoutine for each argument that is to placed
+ *  in the request message.
+ *************************************************************/
+
+static void
+WritePackArgValueNormal(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *ref = (arg->argByReferenceUser ||
+					   it->itNativePointer) ? "*" : "";
+  
+	if (IS_VARIABLE_SIZED_UNTYPED(it) || it->itNoOptArray) {
+		if (it->itString) {
+			/*
+			 * Copy variable-size C string with mig_strncpy.
+			 * Save the string length (+ 1 for trailing 0)
+			 * in the argument`s count field.
+			 */
+			fprintf(file,
+					"\tInP->%s = mig_strncpy(InP->%s, %s, %d);\n",
+					arg->argCount->argMsgField,
+					arg->argMsgField,
+					arg->argVarName,
+					it->itNumber);
+		} else if (it->itNoOptArray)
+			fprintf(file, "\t(void)memcpy((char *) InP->%s, (const char *) %s%s, %d);\n",
+					arg->argMsgField, ref, arg->argVarName, it->itTypeSize);
+		else {
+      
+			/*
+			 * Copy in variable-size inline array with (void)memcpy,
+			 * after checking that number of elements doesn`t
+			 * exceed declared maximum.
+			 */
+			register argument_t *count = arg->argCount;
+			const char *countRef = count->argByReferenceUser ? "*" : "";
+			register ipc_type_t *btype = it->itElement;
+      
+			/* Note btype->itNumber == count->argMultiplier */
+      
+			if (akIdent(arg->argKind) != akeSubCount) {
+				/* we skip the SubCount case, as we have already taken care of */
+				fprintf(file, "\tif (%s%s > %d) {\n",
+						countRef, count->argVarName,
+						it->itNumber/btype->itNumber);
+				WriteReturnMsgError(file, arg->argRoutine, TRUE, arg, "MIG_ARRAY_TOO_LARGE");
+				fprintf(file, "\t}\n");
+			}
+      
+			fprintf(file, "\t(void)memcpy((char *) InP->%s, (const char *) %s%s, ",
+					arg->argMsgField, ref, arg->argVarName);
+			if (btype->itTypeSize > 1)
+				fprintf(file, "%d * ", btype->itTypeSize);
+			fprintf(file, "%s%s);\n", countRef, count->argVarName);
+		}
+	}
+	else if (IS_OPTIONAL_NATIVE(it)) {
+		fprintf(file, "\tif ((InP->__Present__%s = (%s != %s))) {\n",
+				arg->argMsgField, arg->argVarName, it->itBadValue);
+		WriteCopyType(file, it, "\tInP->%s.__Real__%s", "/* %s%s */ %s%s",
+					  arg->argMsgField, arg->argMsgField, 
+					  ref, arg->argVarName);
+		fprintf(file, "\t}\n");
+	}
+	else
+		WriteCopyType(file, it, "InP->%s", "/* %s */ %s%s",
+					  arg->argMsgField, ref, arg->argVarName);
+	fprintf(file, "\n");
+}
+
+/*
+ * Calculate the size of a variable-length message field.
+ */
+static void
+WriteArgSizeVariable(FILE *file,  register argument_t *arg, ipc_type_t *ptype)
+{
+	register int bsize = ptype->itElement->itTypeSize;
+	register argument_t *count = arg->argCount;
+  
+	if (PackMsg == FALSE) {
+		fprintf(file, "%d", ptype->itTypeSize + ptype->itPadSize);
+		return;
+	}
+  
+	/* If the base type size of the data field isn`t a multiple of 4,
+	   we have to round up. */
+	if (bsize % itWordAlign != 0)
+		fprintf(file, "_WALIGN_");
+	fprintf(file, "(");
+	if (bsize > 1)
+		fprintf(file, "%d * ", bsize);
+	if (ptype->itString)
+		/* get count from descriptor in message */
+		fprintf(file, "InP->%s", count->argMsgField);
+	else
+		/* get count from argument */
+		fprintf(file, "%s%s",
+				count->argByReferenceUser ? "*" : "",
+				count->argVarName);
+	fprintf(file, ")");
+}
+
+static void
+WriteArgSizeOptional(FILE *file, argument_t *arg, ipc_type_t *ptype)
+{
+
+    fprintf(file, "(InP->__Present__%s ? _WALIGNSZ_(%s) : 0)",
+			arg->argVarName, ptype->itUserType);
+}
+
+static void
+WriteArgSize(FILE *file, argument_t *arg)
+
+{
+	ipc_type_t *ptype = arg->argType;
+  
+	if (IS_OPTIONAL_NATIVE(ptype))
+		WriteArgSizeOptional(file, arg, ptype);
+	else
+		WriteArgSizeVariable(file, arg, ptype);
+}
+
+/*
+ * Adjust message size and advance request pointer.
+ * Called after packing a variable-length argument that
+ * has more arguments following.
+ */
+static void
+WriteAdjustMsgSize(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argType;
+  
+	/* There are more In arguments.  We need to adjust msgh_size
+	   and advance InP, so we save the size of the current field
+	   in msgh_size_delta. */
+  
+	fprintf(file, "\tmsgh_size_delta = ");
+	WriteArgSize(file, arg);
+	fprintf(file, ";\n");
+  
+	if (arg->argRequestPos == 0) {
+		/* First variable-length argument.  The previous msgh_size value
+		   is the minimum request size. */
+    
+		fprintf(file, "\tmsgh_size = ");
+		rtMinRequestSize(file, arg->argRoutine, "Request");
+		fprintf(file, " + msgh_size_delta;\n");
+    } else
+		fprintf(file, "\tmsgh_size += msgh_size_delta;\n");
+  
+	if (PackMsg == TRUE) {
+		fprintf(file,
+				"\tInP = (Request *) ((pointer_t) InP + msgh_size_delta - ");
+		if (IS_OPTIONAL_NATIVE(ptype))
+			fprintf(file,
+					"_WALIGNSZ_(%s)",
+					ptype->itUserType);
+		else
+			fprintf(file,
+					"%d",
+					ptype->itTypeSize + ptype->itPadSize);
+		fprintf(file,
+				");\n\n");
+	}
+}
+
+/*
+ * Calculate the size of the message.  Called after the
+ * last argument has been packed.
+ */
+static void
+WriteFinishMsgSize(FILE *file, register argument_t *arg)
+{
+	/* No more In arguments.  If this is the only variable In
+	   argument, the previous msgh_size value is the minimum
+	   request size. */
+  
+	if (arg->argRequestPos == 0) {
+		fprintf(file, "\tmsgh_size = ");
+		rtMinRequestSize(file, arg->argRoutine, "Request");
+		fprintf(file, " + (");
+		WriteArgSize(file, arg);
+		fprintf(file, ");\n");
+	}
+	else {
+		fprintf(file, "\tmsgh_size += ");
+		WriteArgSize(file, arg);
+		fprintf(file, ";\n");
+	}
+}
+
+static void
+WriteInitializeCount(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argCInOut->argParent->argType;
+	register ipc_type_t *btype = ptype->itElement;
+  
+    fprintf(file, "\tif (%s%s < %d)\n",
+			arg->argByReferenceUser ? "*" : "",
+			arg->argVarName,
+			ptype->itNumber/btype->itNumber);
+    fprintf(file, "\t\tInP->%s = %s%s;\n",
+			arg->argMsgField,
+			arg->argByReferenceUser ? "*" : "",
+			arg->argVarName);
+	fprintf(file, "\telse\n");
+    fprintf(file, "\t\tInP->%s = %d;\n",
+			arg->argMsgField, ptype->itNumber/btype->itNumber);
+	fprintf(file, "\n");
+}
+
+/*
+ * Generate code to fill in all of the request arguments and their
+ * message types.
+ */
+static void
+WriteRequestArgs(FILE *file, register routine_t *rt)
+{
+	register argument_t *arg;
+	register argument_t *lastVarArg;
+  
+	/*
+	 * 1. The Kernel Processed Data
+	 */
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+		if (akCheckAll(arg->argKind, akbSendSnd|akbSendKPD))
+			(*arg->argKPD_Pack)(file, arg);
+  
+	/*
+	 * 2. The Data Stream
+	 */
+	lastVarArg = argNULL;
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)  {
+		/*
+		 * Adjust message size and advance message pointer if
+		 * the last request argument was variable-length and the
+		 * request position will change.
+		 */
+		if (lastVarArg != argNULL &&
+			lastVarArg->argRequestPos < arg->argRequestPos)
+		{
+			WriteAdjustMsgSize(file, lastVarArg);
+			lastVarArg = argNULL;
+		}
+    
+		if ((akIdent(arg->argKind) == akeCountInOut) &&
+			akCheck(arg->argKind, akbSendSnd))
+			WriteInitializeCount(file, arg);
+		else if (akCheckAll(arg->argKind, akbSendSnd|akbSendBody))
+			WritePackArgValueNormal(file, arg);
+		/*
+		 * Remember whether this was variable-length.
+		 */
+		if (akCheckAll(arg->argKind, akbSendSnd|akbSendBody|akbVariable))
+			lastVarArg = arg;
+	}
+	/*
+	 * Finish the message size.
+	 */
+	if (lastVarArg != argNULL)
+		WriteFinishMsgSize(file, lastVarArg);
+}
+
+/*************************************************************
+ *  Writes code to check that the return msgh_id is correct and that
+ *  the size of the return message is correct. Called by
+ *  WriteRoutine.
+ *************************************************************/
+static void
+WriteCheckIdentity(FILE *file, routine_t *rt)
+{
+    fprintf(file, "\tif (Out0P->Head.msgh_id != %d) {\n",
+			rt->rtNumber + SubsystemBase + 100);
+	fprintf(file, "\t    if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE)\n");
+	fprintf(file, "\t\t{ return MIG_SERVER_DIED; }\n");
+	fprintf(file, "\t    else\n");
+	fprintf(file, "\t\t{ return MIG_REPLY_MISMATCH; }\n");
+	fprintf(file, "\t}\n");
+	fprintf(file, "\n");
+	if (!rt->rtSimpleReply)
+		fprintf(file, "\tmsgh_simple = !(Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);\n");
+	fprintf(file, "#if\t__MigTypeCheck\n");
+  
+	if (!rt->rtNoReplyArgs)
+		fprintf(file, "\tmsgh_size = Out0P->Head.msgh_size;\n\n");
+  
+    if (rt->rtSimpleReply)
+    {
+		/* Expecting a simple message.  We can factor out the check for
+		   a simple message, since the error reply message is also simple.
+		*/
+		fprintf(file,
+				"\tif ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||\n");
+		if (rt->rtNoReplyArgs)
+			fprintf(file, "\t    (Out0P->Head.msgh_size != sizeof(__Reply)))\n");
+		else {
+			/*
+			 * We have an error iff:
+			 * 1) the message size is not the one expected AND
+			 * 2) the message size is also different from sizeof(mig_reply_error_t)
+			 *    or the RetCode == KERN_SUCCESS
+			 */
+			if (rt->rtNumReplyVar > 0)  {
+				fprintf(file, "\t    ((msgh_size > sizeof(__Reply) || msgh_size < ");
+				rtMinReplySize(file, rt, "__Reply");
+				fprintf(file, ") &&\n");
+			} else
+				fprintf(file, "\t    ((msgh_size != sizeof(__Reply)) &&\n");
+			fprintf(file, "\t     (msgh_size != sizeof(mig_reply_error_t) ||\n");
+			fprintf(file, "\t      Out0P->RetCode == KERN_SUCCESS)))\n");
+		}
+	}
+	else {
+		/* Expecting a complex message. */
+    
+		fprintf(file, "\tif ((msgh_simple || Out0P->msgh_body.msgh_descriptor_count != %d ||\n",
+				rt->rtReplyKPDs);
+		if (rt->rtNumReplyVar > 0) {
+			fprintf(file, "\t    msgh_size < ");
+			rtMinReplySize(file, rt, "__Reply");
+			fprintf(file, " || msgh_size > sizeof(__Reply)) &&\n");
+		} else
+			fprintf(file, "\t    msgh_size != sizeof(__Reply)) &&\n");
+		fprintf(file, "\t    (!msgh_simple || msgh_size != sizeof(mig_reply_error_t) ||\n");
+		fprintf(file, "\t    ((mig_reply_error_t *)Out0P)->RetCode == KERN_SUCCESS))\n");
+	}
+	fprintf(file, "\t\t{ return MIG_TYPE_ERROR ; }\n");
+	fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	fprintf(file, "\n");
+}
+
+/*************************************************************
+ *  Write code to generate error handling code if the RetCode
+ *  argument of a Routine is not KERN_SUCCESS.
+ *************************************************************/
+static void
+WriteRetCodeCheck(FILE *file, routine_t *rt)
+{
+	if (rt->rtSimpleReply)
+		fprintf(file, "\tif (Out0P->RetCode != KERN_SUCCESS) {\n");
+	else
+		fprintf(file, "\tif (msgh_simple) {\n");
+	if (CheckNDR) {
+		fprintf(file, "#ifdef\t__NDR_convert__mig_reply_error_t__defined\n");
+		fprintf(file, "\t\t__NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P);\n");
+		fprintf(file, "#endif\t/* __NDR_convert__mig_reply_error_t__defined */\n");
+	}
+	fprintf(file, "\t\treturn ((mig_reply_error_t *)Out0P)->RetCode;\n");
+	fprintf(file, "\t}\n");
+	fprintf(file, "\n");
+}
+
+/*
+ * argKPD_TypeCheck discipline for Port types.
+ */
+static void
+WriteTCheckKPD_port(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *tab = "";
+	char string[MAX_STR_LEN];
+	boolean_t close = FALSE;
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, FALSE, arg, TRUE);
+		(void)sprintf(string, "ptr->");
+		tab = "\t";
+		close = TRUE;
+    } else 
+		(void)sprintf(string, "Out%dP->%s.", arg->argReplyPos, arg->argMsgField);
+    fprintf(file, "\t%sif (%stype != MACH_MSG_PORT_DESCRIPTOR",
+			tab, string);
+	if (arg->argPoly == argNULL && !it->itVarArray)
+		/* we can't check disposition when poly or VarArray,
+		   (because some of the entries could be empty) */
+		fprintf(file, " ||\n\t%s    %sdisposition != %s", tab, string, it->itOutNameStr);
+	fprintf(file,
+			") {\n"
+			"\t\t%s" "return MIG_TYPE_ERROR;\n"
+			"\t%s" "}\n"
+			, tab, tab);
+	if (close)
+		fprintf(file, "\t    }\n\t}\n");
+}
+
+/*
+ * argKPD_TypeCheck discipline for out-of-line types.
+ */
+static void
+WriteTCheckKPD_ool(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *tab;
+	char string[MAX_STR_LEN];
+	boolean_t test;
+	u_int howmany, howbig;
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, FALSE, arg, TRUE);
+		tab = "\t";
+		sprintf(string, "ptr->");
+		howmany = it->itElement->itNumber;
+		howbig = it->itElement->itSize;
+		test = !it->itVarArray && !it->itElement->itVarArray;
+    } else {
+		tab = "";
+		sprintf(string, "Out%dP->%s.", arg->argReplyPos, arg->argMsgField);
+		howmany = it->itNumber;
+		howbig = it->itSize;
+		test = !it->itVarArray;
+	}
+  
+	fprintf(file, "\t%sif (%stype != MACH_MSG_OOL_DESCRIPTOR", tab, string);
+	if (test)
+		/* if VarArray we may use no-op; if itElement->itVarArray size might change */
+		fprintf(file, " ||\n\t%s    %ssize != %d", tab, string, (howmany * howbig + 7)/8);
+	fprintf(file,
+			") {\n"
+			"\t\t%s" "return MIG_TYPE_ERROR;\n"
+			"\t%s" "}\n"
+			, tab, tab);
+	if (IS_MULTIPLE_KPD(it))
+		fprintf(file, "\t    }\n\t}\n");
+}
+
+/*
+ * argKPD_TypeCheck discipline for out-of-line Port types.
+ */
+static void
+WriteTCheckKPD_oolport(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *tab;
+	char string[MAX_STR_LEN];
+	boolean_t test;
+	u_int howmany;
+    const char *howstr;
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, FALSE, arg, TRUE);
+		tab = "\t";
+		sprintf(string, "ptr->");
+		howmany = it->itElement->itNumber;
+		test = !it->itVarArray && !it->itElement->itVarArray;
+		howstr = it->itElement->itOutNameStr;
+    } else {
+		tab = "";
+		sprintf(string, "Out%dP->%s.", arg->argReplyPos, arg->argMsgField);
+		howmany = it->itNumber;
+		test = !it->itVarArray;
+		howstr = it->itOutNameStr;
+	}
+  
+	fprintf(file, "\t%sif (%stype != MACH_MSG_OOL_PORTS_DESCRIPTOR", tab, string);
+	if (test)
+		/* if VarArray we may use no-op; if itElement->itVarArray size might change */
+		fprintf(file, " ||\n\t%s    %scount != %d", tab, string, howmany);
+	if (arg->argPoly == argNULL)
+		fprintf(file, " ||\n\t%s    %sdisposition != %s", tab, string, howstr);
+	fprintf(file, ") {\n"
+			"\t\t%s" "return MIG_TYPE_ERROR;\n"
+			"\t%s" "}\n"
+			,tab, tab);
+	if (IS_MULTIPLE_KPD(it))
+		fprintf(file, "\t    }\n\t}\n");
+}
+
+/*************************************************************
+ *  Writes code to check that the type of each of the arguments
+ *  in the reply message is what is expected. Called by
+ *  WriteRoutine for each out && typed argument in the reply message.
+ *************************************************************/
+static void
+WriteTypeCheck(FILE *file, register argument_t *arg)
+{
+	fprintf(file, "#if\t__MigTypeCheck\n");
+	(*arg->argKPD_TypeCheck)(file, arg);
+	fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+}
+
+
+/*
+ * argKPD_Extract discipline for Port types.
+ */
+static void
+WriteExtractKPD_port(FILE *file,  register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+    const char *ref = arg->argByReferenceUser ? "*" : "";
+    const char *subindex;
+    const char *recast = "";
+	ipc_type_t *real_it;
+  
+	real_it = (IS_MULTIPLE_KPD(it)) ? it->itElement : it;
+#ifdef MIG_KERNEL_PORT_CONVERSION
+	if (IsKernelUser && streql(real_it->itUserType, "ipc_port_t"))
+		recast = "(mach_port_t)";
+#endif
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, it->itVarArray, arg, FALSE);
+    
+		fprintf(file, "\t\t%s[i] = %sptr->name;\n", 
+				arg->argVarName, recast);
+		if (it->itVarArray) {
+			register argument_t *count = arg->argCount;
+			const char *cref = count->argByReferenceUser ? "*" : "";
+      
+			fprintf(file, "\t    if (Out%dP->%s > %s%s)\n",  count->argReplyPos, 
+					count->argVarName, cref, count->argVarName);
+			WriteReturnMsgError(file, arg->argRoutine, TRUE, arg, "MIG_ARRAY_TOO_LARGE");
+		}
+		fprintf(file, "\t}\n");
+		subindex = "[0]";
+	}
+	else {
+		fprintf(file, "\t%s%s = %sOut%dP->%s.name;\n", ref, arg->argVarName, recast, arg->argReplyPos, arg->argMsgField);
+		subindex = "";
+	}
+  
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbReturnRcv)) {
+		register argument_t *poly = arg->argPoly;
+		const char *pref = poly->argByReferenceUser ? "*" : "";
+    
+		fprintf(file, "\t%s%s = Out%dP->%s%s.disposition;\n",
+				pref, poly->argVarName, arg->argReplyPos, arg->argMsgField, subindex);
+	}
+}
+
+/*
+ * argKPD_Extract discipline for out-of-line types.
+ */
+static void
+WriteExtractKPD_ool(FILE *file, register argument_t *arg)
+{
+    const char *ref = arg->argByReferenceUser ? "*" : "";
+	register ipc_type_t *it = arg->argType;
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, it->itVarArray, arg, FALSE);
+		fprintf(file, "\t\t%s[i] = ptr->address;\n", 
+				arg->argVarName);
+		fprintf(file, "\t}\n");
+    } else
+		fprintf(file, "\t%s%s = (%s)(Out%dP->%s.address);\n",
+				ref, arg->argVarName, arg->argType->itUserType, 
+				arg->argReplyPos, arg->argMsgField);
+	/*
+	 *  In case of variable sized arrays,
+	 *  the count field will be retrieved from the untyped
+	 *  section of the message
+	 */
+}
+
+/*
+ * argKPD_Extract discipline for out-of-line Port types.
+ */
+static void
+WriteExtractKPD_oolport(FILE *file, register argument_t *arg)
+{
+    const char *ref = arg->argByReferenceUser ? "*" : "";
+	register ipc_type_t *it = arg->argType;
+    const char *subindex;
+  
+	if (IS_MULTIPLE_KPD(it)) {
+		WriteKPD_Iterator(file, FALSE, FALSE, it->itVarArray, arg, FALSE);
+		fprintf(file, "\t\t%s[i] = ptr->address;\n",
+				arg->argVarName);
+		fprintf(file, "\t}\n");
+		subindex = "[0]";
+	}
+	else {
+		fprintf(file, "\t%s%s = (%s)(Out%dP->%s.address);\n", ref, arg->argVarName, arg->argType->itUserType, arg->argReplyPos, arg->argMsgField);
+		subindex = "";
+	}
+	/*
+	 *  In case of variable sized arrays,
+	 *  the count field will be retrieved from the untyped
+	 *  section of the message
+	 */
+	if (arg->argPoly != argNULL && akCheckAll(arg->argPoly->argKind, akbReturnRcv)) {
+		register argument_t *poly = arg->argPoly;
+        const char *pref = poly->argByReferenceUser ? "*" : "";
+    
+        fprintf(file, "\t%s%s = Out%dP->%s%s.disposition;\n",
+				pref, poly->argVarName, arg->argReplyPos, arg->argMsgField, subindex);
+	}
+}
+
+/*************************************************************
+ *  Write code to copy an argument from the reply message
+ *  to the parameter. Called by WriteRoutine for each argument
+ *  in the reply message.
+ *************************************************************/
+
+static void
+WriteExtractArgValueNormal(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *argType = arg->argType;
+    const char *ref = arg->argByReferenceUser ? "*" : "";
+	char who[20];
+  
+	if (akCheck(arg->argKind, akbUserImplicit))
+		sprintf(who, "TrailerP");
+	else
+		sprintf(who, "Out%dP", arg->argReplyPos);
+  
+	if (IS_VARIABLE_SIZED_UNTYPED(argType) || argType->itNoOptArray) {
+		if (argType->itString) {
+			/*
+			 * Copy out variable-size C string with mig_strncpy.
+			 */
+			fprintf(file, "\t(void) mig_strncpy(%s%s, %s->%s, %d);\n",
+					ref,
+					arg->argVarName,
+					who,
+					arg->argMsgField,
+					argType->itNumber);
+		}
+		else if (argType->itNoOptArray)
+			fprintf(file, "\t(void)memcpy((char *) %s%s, (const char *) %s->%s, %d);\n",
+					ref, arg->argVarName, who, arg->argMsgField, argType->itTypeSize);
+		else {
+      
+			/*
+			 * Copy out variable-size inline array with (void)memcpy,
+			 * after checking that number of elements doesn`t
+			 * exceed user`s maximum.
+			 */
+			register argument_t *count = arg->argCount;
+			const char *countRef = count->argByReferenceUser ? "*" : "";
+			register ipc_type_t *btype = argType->itElement;
+      
+			/* Note count->argMultiplier == btype->itNumber */
+			/* Note II: trailer logic isn't supported in this case */
+			fprintf(file, "\tif (Out%dP->%s", count->argReplyPos, count->argMsgField);
+			if (arg->argCountInOut) {
+				fprintf(file, " > %s%s) {\n", countRef, count->argVarName);
+			}
+			else {
+				fprintf(file, " > %d) {\n", argType->itNumber/btype->itNumber);
+			}
+      
+			/*
+			 * If number of elements is too many for user receiving area,
+			 * fill user`s area as much as possible.  Return the correct
+			 * number of elements.
+			 */
+			fprintf(file, "\t\t(void)memcpy((char *) %s%s, (const char *) Out%dP->%s, ",
+					ref, arg->argVarName, arg->argReplyPos, arg->argMsgField);
+			if (btype->itTypeSize > 1)
+				fprintf(file, "%d * ", btype->itTypeSize);
+			if (arg->argCountInOut) {
+				fprintf(file, " %s%s);\n", countRef, count->argVarName);
+			}
+			else {
+				fprintf(file, " %d);\n", argType->itNumber/btype->itNumber);
+			}
+			fprintf(file, "\t\t%s%s = Out%dP->%s", countRef, count->argVarName, count->argReplyPos, count->argMsgField);
+			fprintf(file, ";\n");
+			WriteReturnMsgError(file, arg->argRoutine, TRUE, arg, "MIG_ARRAY_TOO_LARGE");
+      
+			fprintf(file, "\t}\n");
+      
+			fprintf(file, "\t(void)memcpy((char *) %s%s, (const char *) Out%dP->%s, ",
+					ref, arg->argVarName, arg->argReplyPos, arg->argMsgField);
+			if (btype->itTypeSize > 1)
+				fprintf(file, "%d * ",
+						btype->itTypeSize);
+			fprintf(file, "Out%dP->%s);\n",
+					count->argReplyPos, count->argMsgField);
+		}
+	}
+	else
+		WriteCopyType(file, argType,
+					  "%s%s", "/* %s%s */ %s->%s",
+					  ref, arg->argVarName, who, arg->argMsgField);
+	fprintf(file, "\n");
+}
+
+static void
+WriteCalcArgSize(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argType;
+	register ipc_type_t *btype = ptype->itElement;
+	argument_t *count = arg->argCount;
+	int multiplier = btype->itTypeSize;
+  
+	/* If the base type size of the data field isn`t a multiple of 4,
+	   we have to round up. */
+	if (btype->itTypeSize % itWordAlign != 0)
+		fprintf(file, "_WALIGN_(");
+  
+	fprintf(file, "Out%dP->%s", count->argReplyPos, count->argMsgField);
+	if (multiplier > 1)
+		fprintf(file, " * %d", multiplier);
+
+	if (btype->itTypeSize % itWordAlign != 0)
+		fprintf(file, ")");
+}
+
+static void
+WriteCheckArgSize(FILE *file, routine_t *rt, argument_t *arg, const char *comparator)
+{
+	register ipc_type_t *ptype = arg->argType;
+	register ipc_type_t *btype = ptype->itElement;
+	argument_t *count = arg->argCount;
+	int multiplier = btype->itTypeSize;
+  
+	fprintf(file, "\tif (((msgh_size - ");
+	rtMinReplySize(file, rt, "__Reply");
+	fprintf(file, ")");
+	if (multiplier > 1)
+		fprintf(file, " / %d", multiplier);
+	fprintf(file, "< Out%dP->%s) ||\n", count->argReplyPos, count->argMsgField);
+	fprintf(file, "\t    (msgh_size %s ", comparator);
+	rtMinReplySize(file, rt, "__Reply");
+	fprintf(file, " + ");
+	WriteCalcArgSize(file, arg);
+	fprintf(file, ")");
+	fprintf(file, ")\n\t\t{ return MIG_TYPE_ERROR ; }\n");
+}
+
+
+/* NDR Conversion routines */
+
+
+static void
+WriteReplyNDRConvertIntRepArgCond(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+  
+	fprintf(file, "defined(__NDR_convert__int_rep__Reply__%s_t__%s__defined)", rt->rtName, arg->argMsgField);
+}
+
+static void
+WriteReplyNDRConvertCharRepArgCond(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+  
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) !=akeCountInOut && akIdent(arg->argKind) != akeRetCode)
+		fprintf(file, "defined(__NDR_convert__char_rep__Reply__%s_t__%s__defined)", rt->rtName, arg->argMsgField);
+	else
+		fprintf(file, "0");
+}
+
+static void
+WriteReplyNDRConvertFloatRepArgCond(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+  
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) !=akeCountInOut && akIdent(arg->argKind) != akeRetCode)
+		fprintf(file, "defined(__NDR_convert__float_rep__Reply__%s_t__%s__defined)", rt->rtName, arg->argMsgField);
+	else
+		fprintf(file, "0");
+}
+
+static void
+WriteReplyNDRConvertIntRepArgDecl(FILE *file, argument_t *arg)
+{
+	WriteNDRConvertArgDecl(file, arg, "int_rep", "Reply");
+}
+
+static void
+WriteReplyNDRConvertCharRepArgDecl(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) !=akeCountInOut && akIdent(arg->argKind) != akeRetCode)
+		WriteNDRConvertArgDecl(file, arg, "char_rep", "Reply");
+}
+
+static void
+WriteReplyNDRConvertFloatRepArgDecl(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) !=akeCountInOut && akIdent(arg->argKind) != akeRetCode)
+		WriteNDRConvertArgDecl(file, arg, "float_rep", "Reply");
+}
+
+
+
+static void
+WriteReplyNDRConvertArgUse(FILE *file, argument_t *arg, const char *convert)
+{
+	routine_t *rt = arg->argRoutine;
+	argument_t *count = arg->argCount;
+	char argname[MAX_STR_LEN];
+  
+	if ((akIdent(arg->argKind) == akeCount || akIdent(arg->argKind) == akeCountInOut) &&
+		(arg->argParent && akCheck(arg->argParent->argKind, akbReturnNdr)))
+		return;
+  
+	if (arg->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR) {
+		if (count && !arg->argSameCount && !strcmp(convert, "int_rep")) {
+			fprintf(file, "#if defined(__NDR_convert__int_rep__Reply__%s_t__%s__defined)\n", rt->rtName, count->argMsgField);
+			fprintf(file, "\t\t__NDR_convert__int_rep__Reply__%s_t__%s(&Out%dP->%s, Out%dP->NDR.int_rep);\n", rt->rtName, count->argMsgField, count->argReplyPos, count->argMsgField, count->argReplyPos);
+			fprintf(file, "#endif\t/* __NDR_convert__int_rep__Reply__%s_t__%s__defined */\n", rt->rtName, count->argMsgField);
+		}
+    
+		sprintf(argname, "(%s)(Out%dP->%s.address)", FetchServerType(arg->argType), arg->argReplyPos, arg->argMsgField);
+	}
+	else {
+		sprintf(argname, "&Out%dP->%s", arg->argReplyPos, arg->argMsgField);
+	}
+  
+	fprintf(file, "#if defined(__NDR_convert__%s__Reply__%s_t__%s__defined)\n", convert, rt->rtName, arg->argMsgField);
+	fprintf(file, "\t\t__NDR_convert__%s__Reply__%s_t__%s(%s, Out0P->NDR.%s", convert, rt->rtName, arg->argMsgField, argname, convert);
+	if (count)
+		fprintf(file, ", Out%dP->%s", count->argReplyPos, count->argMsgField);
+	fprintf(file, ");\n");
+	fprintf(file, "#endif /* __NDR_convert__%s__Reply__%s_t__%s__defined */\n", convert, rt->rtName, arg->argMsgField);
+}
+
+static void
+WriteReplyNDRConvertIntRepOneArgUse(FILE *file, argument_t *arg)
+{
+	routine_t *rt = arg->argRoutine;
+  
+	fprintf(file, "#if defined(__NDR_convert__int_rep__Reply__%s_t__%s__defined)\n", rt->rtName, arg->argMsgField);
+	fprintf(file, "\tif (Out0P->NDR.int_rep != NDR_record.int_rep)\n");
+	fprintf(file, "\t\t__NDR_convert__int_rep__Reply__%s_t__%s(&Out%dP->%s, Out%dP->NDR.int_rep);\n", rt->rtName, arg->argMsgField, arg->argReplyPos, arg->argMsgField, arg->argReplyPos);
+	fprintf(file, "#endif\t/* __NDR_convert__int_rep__Reply__%s_t__%s__defined */\n", rt->rtName, arg->argMsgField);
+}
+
+static void
+WriteReplyNDRConvertIntRepArgUse(FILE *file, argument_t *arg)
+{
+	WriteReplyNDRConvertArgUse(file, arg, "int_rep");
+}
+
+static void
+WriteReplyNDRConvertCharRepArgUse(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) !=akeCountInOut && akIdent(arg->argKind) != akeRetCode)
+		WriteReplyNDRConvertArgUse(file, arg, "char_rep");
+}
+
+static void
+WriteReplyNDRConvertFloatRepArgUse(FILE *file, argument_t *arg)
+{
+	if (akIdent(arg->argKind) != akeCount && akIdent(arg->argKind) !=akeCountInOut && akIdent(arg->argKind) != akeRetCode)
+		WriteReplyNDRConvertArgUse(file, arg, "float_rep");
+}
+
+static void
+WriteCheckMsgSize(FILE *file, register argument_t *arg)
+{
+	register routine_t *rt = arg->argRoutine;
+  
+	/* If there aren't any more Out args after this, then
+	   we can use the msgh_size_delta value directly in
+	   the TypeCheck conditional. */
+  
+	if (CheckNDR && arg->argCount && !arg->argSameCount)
+		WriteReplyNDRConvertIntRepOneArgUse(file, arg->argCount);
+  
+	if (arg->argReplyPos == rt->rtMaxReplyPos) {
+		fprintf(file, "#if\t__MigTypeCheck\n");
+
+		/*
+		 * emit code to verify that the server-code-provided count does not exceed the maximum count allowed by the type.
+		 */
+		fprintf(file, "\t" "if ( Out%dP->%s > %d )\n", arg->argCount->argReplyPos, arg->argCount->argMsgField, arg->argType->itNumber);
+		fputs("\t\t" "return MIG_TYPE_ERROR;\n", file);
+		/* ...end... */
+    
+		WriteCheckArgSize(file, rt, arg, "!=");
+
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	else {
+		/* If there aren't any more variable-sized arguments after this,
+		   then we must check for exact msg-size and we don't need
+		   to update msgh_size. */
+    
+		boolean_t LastVarArg = arg->argReplyPos+1 == rt->rtNumReplyVar;
+    
+		/* calculate the actual size in bytes of the data field.  note
+		   that this quantity must be a multiple of four.  hence, if
+		   the base type size isn't a multiple of four, we have to
+		   round up.  note also that btype->itNumber must
+		   divide btype->itTypeSize (see itCalculateSizeInfo). */
+    
+		fprintf(file, "\tmsgh_size_delta = ");
+		WriteCalcArgSize(file, arg);
+		fprintf(file, ";\n");
+		fprintf(file, "#if\t__MigTypeCheck\n");
+
+		/*
+		 * Advance message pointer if the last reply argument was
+		 * variable-length and the reply position will change.
+		 */
+		fprintf(file, "\t" "if ( Out%dP->%s > %d )\n", arg->argCount->argReplyPos, arg->argCount->argMsgField, arg->argType->itNumber);
+		fputs("\t\t" "return MIG_TYPE_ERROR;\n", file);
+		/* ...end... */
+    
+		WriteCheckArgSize(file, rt, arg, LastVarArg ? "!=" : "<");
+
+		if (!LastVarArg)
+			fprintf(file, "\tmsgh_size -= msgh_size_delta;\n");
+    
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	fprintf(file, "\n");
+}
+
+static void
+WriteAdjustReplyMsgPtr(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *ptype = arg->argType;
+  
+	fprintf(file, "\t*Out%dPP = Out%dP = (__Reply *) ((pointer_t) Out%dP + msgh_size_delta - %d);\n\n",
+			arg->argReplyPos+1, arg->argReplyPos +1, arg->argReplyPos, ptype->itTypeSize + ptype->itPadSize);
+}
+
+static void
+WriteReplyArgs(FILE *file, register routine_t *rt)
+{
+	register argument_t *arg;
+  
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		if (akCheckAll(arg->argKind, akbReturnRcv|akbReturnBody)) {
+			WriteExtractArgValueNormal(file, arg);
+		}
+		else if (akCheckAll(arg->argKind, akbReturnRcv|akbReturnKPD)) {
+			/*
+			 * KPDs have argReplyPos 0, therefore they escape the above logic
+			 */
+			(*arg->argKPD_Extract)(file, arg);
+		}
+		else if (akCheck(arg->argKind, akbUserImplicit)) {
+			WriteExtractArgValueNormal(file, arg);
+		}
+	}
+}
+
+/*************************************************************
+ *  Writes code to return the return value. Called by WriteRoutine
+ *  for routines and functions.
+ *************************************************************/
+static void
+WriteReturnValue(FILE *file, routine_t *rt)
+{
+	/* If returning RetCode, we have already checked that it is KERN_SUCCESS */
+	WriteReturn(file, rt, "\t", "KERN_SUCCESS", "\n");
+}
+
+/*************************************************************
+ *  Writes the elements of the message type declaration: the
+ *  msg_type structure, the argument itself and any padding
+ *  that is required to make the argument a multiple of 4 bytes.
+ *  Called by WriteRoutine for all the arguments in the request
+ *  message first and then the reply message.
+ *************************************************************/
+static void
+WriteFieldDecl(FILE *file, argument_t *arg)
+{
+	if (akCheck(arg->argKind, akbSendKPD) ||
+		akCheck(arg->argKind, akbReturnKPD))
+		WriteFieldDeclPrim(file, arg, FetchKPDType);
+	else
+		WriteFieldDeclPrim(file, arg, FetchUserType);
+}
+
+/* Fill in the string with an expression that refers to the size
+ * of the specified array:
+ */
+static void
+GetArraySize(register argument_t *arg, char *size)
+{
+	register ipc_type_t *it = arg->argType;
+  
+	if (it->itVarArray) {
+		if (arg->argCount->argByReferenceUser) {
+			sprintf(size, "*%s", arg->argCount->argVarName);
+		} else
+			sprintf(size, "%s", arg->argCount->argVarName);
+    } else {
+		sprintf(size, "%d", (it->itNumber * it->itSize + 7) / 8);
+	}
+}
+
+
+static void
+WriteRPCPortDisposition(FILE *file, register argument_t *arg)
+{
+	/*
+	 * According to the MIG specification, the port disposition could be different
+	 * on input and output. If we stay with this then a new bitfield will have
+	 * to be added. Right now the port disposition is the same for in and out cases.
+	 */
+    switch(arg->argType->itInName)
+    {
+
+    case  MACH_MSG_TYPE_MOVE_RECEIVE:
+		fprintf(file, " | MACH_RPC_MOVE_RECEIVE");
+		break;
+
+	case  MACH_MSG_TYPE_MOVE_SEND:
+		fprintf(file, " | MACH_RPC_MOVE_SEND");
+		break;
+
+	case  MACH_MSG_TYPE_MOVE_SEND_ONCE:
+		fprintf(file, " | MACH_RPC_MOVE_SEND_ONCE");
+		break;
+      
+    case  MACH_MSG_TYPE_COPY_SEND:
+		fprintf(file, " | MACH_RPC_COPY_SEND");
+		break;
+      
+    case  MACH_MSG_TYPE_MAKE_SEND:
+		fprintf(file, " | MACH_RPC_MAKE_SEND");
+		break;
+      
+    case  MACH_MSG_TYPE_MAKE_SEND_ONCE:
+		fprintf(file, " | MACH_RPC_MAKE_SEND_ONCE");
+		break;
+	}
+}
+
+static void
+WriteRPCArgDescriptor(FILE *file, register argument_t *arg, int offset)
+{
+	fprintf(file, "            {\n                0 ");
+    if (RPCPort(arg))
+    {
+		fprintf(file, "| MACH_RPC_PORT ");
+		if (arg->argType->itNumber > 1)
+			fprintf(file, "| MACH_RPC_ARRAY ");
+		if (arg->argType->itVarArray)
+			fprintf(file, "| MACH_RPC_VARIABLE ");
+		WriteRPCPortDisposition(file, arg);
+	}
+    else if (RPCPortArray(arg))
+    {
+		fprintf(file, "| MACH_RPC_PORT_ARRAY ");
+		if (arg->argType->itVarArray)
+			fprintf(file, "| MACH_RPC_VARIABLE ");
+		WriteRPCPortDisposition(file, arg);
+	}
+	else if (RPCFixedArray(arg))
+		fprintf(file, "| MACH_RPC_ARRAY_FIXED ");
+	else if (RPCVariableArray(arg))
+		fprintf(file, "| MACH_RPC_ARRAY_VARIABLE ");
+	if (argIsIn(arg))
+		fprintf(file, " | MACH_RPC_IN ");
+	if (argIsOut(arg))
+		fprintf(file, " | MACH_RPC_OUT ");
+	if ((! arg->argType->itInLine) && (! arg->argType->itMigInLine))
+		fprintf(file, " | MACH_RPC_POINTER ");
+	if (arg->argFlags & flDealloc)
+		fprintf(file, " | MACH_RPC_DEALLOCATE ");
+	if (arg->argFlags & flPhysicalCopy)
+		fprintf(file, " | MACH_RPC_PHYSICAL_COPY ");
+	fprintf(file, ",\n");
+	fprintf(file, "                %d,\n", (arg->argType->itSize / 8));
+	fprintf(file, "                %d,\n", arg->argType->itNumber);
+	fprintf(file, "                %d,\n            },\n", offset);
+}
+
+void
+WriteRPCRoutineDescriptor(FILE *file, routine_t *rt __unused, int arg_count,
+						  int descr_count, 
+						  string_t stub_routine, string_t sig_array)
+{
+
+    fprintf(file, "          { (mig_impl_routine_t) 0,\n\
+            (mig_stub_routine_t) %s, ",
+			stub_routine);
+    fprintf(file, "%d, %d, %s }", arg_count, descr_count, sig_array);
+}
+
+void
+WriteRPCRoutineArgDescriptor(FILE *file, register routine_t *rt)
+{
+	register argument_t *arg;
+	int offset = 0;
+	int size = 0;
+  
+    for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+    {
+		boolean_t compound = arg->argType->itStruct && arg->argType->itInLine;
+    
+		if (RPCPort(arg) || RPCPortArray(arg) ||
+			RPCFixedArray(arg) || RPCVariableArray(arg))
+		{
+			WriteRPCArgDescriptor(file, arg, offset);
+			size = 4;
+		}
+		if (! size)
+		{
+			if (compound)
+				size = arg->argType->itNumber * (arg->argType->itSize / 8);
+			else
+				size = (arg->argType->itSize / 8);
+		}
+		if (akCheck(arg->argKind, akbServerArg))
+			offset += size;
+		size = 0;
+	}
+}
+
+
+static void
+WriteRPCSignature(FILE *file, register routine_t *rt)
+{
+	int arg_count = 0;
+	int descr_count = 0;
+  
+	fprintf(file, "    kern_return_t rtn;\n");
+	descr_count = rtCountArgDescriptors(rt->rtArgs, &arg_count);
+	fprintf(file, "    const static struct\n    {\n");
+	fprintf(file, "        struct rpc_routine_descriptor rd;\n");
+	fprintf(file, "        struct rpc_routine_arg_descriptor rad[%d];\n", descr_count);
+	fprintf(file, "    } sig =\n    {\n");
+	WriteRPCRoutineDescriptor(file, rt, arg_count, descr_count, "0", "sig.rad, 0");
+	fprintf(file, ",\n");
+	fprintf(file, "        {\n");
+	WriteRPCRoutineArgDescriptor(file, rt);
+	fprintf(file, "\n        }\n");
+	fprintf(file, "\n    };\n\n");
+}
+
+static void
+WriteRPCCall(FILE *file, register routine_t *rt)
+{
+	register argument_t *arg;
+	register int i;
+  
+	i = 0;
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		if (akIdent(arg->argKind) == akeRequestPort) {
+			fprintf(file, "    rtn = (MACH_RPC(&sig, (mach_msg_size_t)sizeof(sig), %d, %s,\n", rt->rtNumber + SubsystemBase, arg->argVarName);
+			fprintf(file, "                   (%s", arg->argVarName);
+		}
+		else if (akCheck(arg->argKind, akbServerArg))
+		{
+			if (i && (i++ % 6 == 0))
+				fprintf(file, ",\n                    ");
+			else
+				fprintf(file, ", ");
+			fprintf(file, "%s", arg->argVarName);
+		}
+	}
+	fprintf(file, ")));\n");
+	fprintf(file, "\n");
+	fprintf(file, "    if (rtn != KERN_NO_ACCESS) return rtn;\n\n");
+	fprintf(file, "/* The following message rpc code is generated for the network case */\n\n");
+}
+
+static int
+CheckRPCCall(register routine_t *rt)
+{
+	register argument_t *arg;
+	register int i;
+  
+	i = 0;
+    for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+    {
+		if (akCheck(arg->argKind, akbUserArg) &&
+			((arg->argType->itOutName == (u_int)-1) || (arg->argType->itInName == (u_int)-1)))
+		{
+			return FALSE;
+		}
+		if (arg->argFlags & flMaybeDealloc)
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+static void
+WriteRPCRoutine(FILE *file, register routine_t *rt)
+{
+    if (CheckRPCCall(rt))
+    {
+		WriteRPCSignature(file, rt);
+		WriteRPCCall(file, rt);
+	}
+}
+
+/********************** End UserRPCTrap Routines*************************/
+
+/* Process an IN/INOUT arg before the short-circuited RPC */
+static void
+WriteShortCircInArgBefore(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	char size[128];
+  
+	fprintf(file, "\n\t/* IN %s: */\n", arg->argVarName);
+  
+	if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD)) {
+		switch (arg->argKPD_Type) {
+
+		case MACH_MSG_PORT_DESCRIPTOR:
+			break;
+
+		case MACH_MSG_OOL_DESCRIPTOR:
+			/* Arg is an out-of-line array: */
+			if (!(arg->argFlags & flDealloc) &&
+				(!(arg->argFlags & flAuto) || !(arg->argFlags & flConst))) {
+				/* Need to map a copy of the array: */
+				GetArraySize(arg, size);
+				fprintf(file, "\t(void)vm_read(mach_task_self(),\n");
+				fprintf(file, "\t\t      (vm_address_t) %s%s, %s, (vm_address_t *) &_%sTemp_, &_MIG_Ignore_Count_);\n",
+						(arg->argByReferenceUser ? "*" : ""),
+						arg->argVarName, size, arg->argVarName);
+				/* Point argument at the copy: */
+				fprintf(file, "\t*(char **)&%s%s = _%sTemp_;\n",
+						(arg->argByReferenceUser ? "*" : ""),
+						arg->argVarName,
+						arg->argVarName);
+			} else if ((arg->argFlags & flDealloc) &&
+					   ((arg->argFlags & flAuto) || it->itMigInLine)) {
+				/* Point the temp var at the original argument: */
+				fprintf(file, "\t_%sTemp_ = (char *) %s%s;\n",
+						arg->argVarName,
+						(arg->argByReferenceUser ? "*" : ""),
+						arg->argVarName);
+			}
+			break;
+		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+			break;
+		default:
+			printf("MiG internal error: type of kernel processed data unknown\n");
+			exit(1);
+		}   /* end of switch */
+    } else if (it->itNumber > 1) {
+		if (it->itStruct) {
+			/* Arg is a struct -- nothing to do. */
+		} else {
+			/* Arg is a C string or an in-line array: */
+			if (!argIsOut(arg) && !(arg->argFlags & flConst)) {
+				/* Have to copy it into a temp.  Use a stack var, if this would
+				 * not overflow the -maxonstack specification:
+				 */
+				if (it->itTypeSize <= sizeof(char *) ||
+					rtMessOnStack(arg->argRoutine) ||
+					arg->argRoutine->rtTempBytesOnStack +
+					it->itTypeSize <= (u_int)MaxMessSizeOnStack) {
+					fprintf(file, "\t{   char _%sTemp_[%d];\n",
+							arg->argVarName, it->itTypeSize);
+					arg->argRoutine->rtTempBytesOnStack += it->itTypeSize;
+					arg->argTempOnStack = TRUE;
+				}
+				else {
+					fprintf(file, "\t{   _%sTemp_ = (char *) %s(%d);\n", arg->argVarName, MessAllocRoutine, it->itTypeSize);
+					arg->argTempOnStack = FALSE;
+				}
+				WriteCopyArg(file, arg, "_%sTemp_", "/* %s */ (char *) %s",
+							 arg->argVarName, arg->argVarName);
+				/* Point argument at temp: */
+				fprintf(file, "\t    *(char **)&%s%s = _%sTemp_;\n",
+						(arg->argByReferenceUser ? "*" : ""),
+						arg->argVarName,
+						arg->argVarName);
+				fprintf(file, "\t}\n");
+			}
+		}
+	}
+}
+
+
+/* Process an INOUT/OUT arg before the short-circuited RPC */
+static void
+WriteShortCircOutArgBefore(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+  
+	fprintf(file, "\n\t/* OUT %s: */\n", arg->argVarName);
+  
+  
+	fprintf(file, "\n\t/* OUT %s: */\n", arg->argVarName);
+  
+	if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD)) {
+		switch (arg->argKPD_Type) {
+		case MACH_MSG_PORT_DESCRIPTOR:
+			break;
+		case MACH_MSG_OOL_DESCRIPTOR:
+			/* Arg is an out-of-line array: */
+			if (!argIsIn(arg) && (arg->argFlags & flOverwrite)) {
+				/* Point the temp var at the original argument: */
+				fprintf(file, "\t    _%sTemp_ = (char *) %s%s;\n",
+						arg->argVarName,
+						(arg->argByReferenceUser ? "*" : ""),
+						arg->argVarName);
+			}
+			break;
+		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+			break;
+		default:
+			printf("MiG internal error: type of kernel processed data unknown\n");
+			exit(1);
+		}   /* end of switch */
+    } else if (it->itNumber > 1) {
+		/* Arg is an in-line array: */
+	}
+}
+
+
+
+/* Process an IN arg after the short-circuited RPC */
+static void
+WriteShortCircInArgAfter(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	char size[128];
+  
+	fprintf(file, "\n\t/* IN %s: */\n", arg->argVarName);
+
+	if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD)) {
+		switch (arg->argKPD_Type) {
+
+		case MACH_MSG_PORT_DESCRIPTOR:
+			break;
+
+		case MACH_MSG_OOL_DESCRIPTOR:
+			/* Arg is an out-of-line array: */
+			GetArraySize(arg, size);
+			if ((!(arg->argFlags & flAuto) && it->itMigInLine) ||
+				((arg->argFlags & flAuto) &&
+				 ((arg->argFlags & flDealloc) ||
+				  !(arg->argFlags & flConst))
+					)) {
+				/* Need to dealloc the temporary: */
+				fprintf(file, "\t(void)vm_deallocate(mach_task_self(),");
+				fprintf(file, " (vm_address_t *) _%sTemp_, %s);\n",
+					    arg->argVarName, size);
+            }
+			break;
+		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+			break;
+		default:
+			printf("MiG internal error: type of kernel processed data unknown\n");
+			exit(1);
+		}   /* end of switch */
+    } else if (it->itNumber > 1) {
+		if (it->itStruct) {
+			/* Arg is a struct -- nothing to do. */
+		} else {
+			/* Arg is a C string or an in-line array: */
+			if (!argIsOut(arg) && !(arg->argFlags & flConst)) {
+				/* A temp needs to be deallocated, if not on stack: */
+				if (!arg->argTempOnStack) {
+					fprintf(file, "\t%s(_%sTemp_, %d);\n",
+							MessFreeRoutine, arg->argVarName, it->itTypeSize);
+				}
+			}
+		}
+	}
+}
+
+static void
+WriteShortCircOutArgAfter(FILE *file, register argument_t *arg)
+{
+	register ipc_type_t *it = arg->argType;
+	char size[128];
+  
+	fprintf(file, "\n\t/* OUT %s: */\n", arg->argVarName);
+  
+	if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD)) {
+		switch (arg->argKPD_Type) {
+
+		case MACH_MSG_PORT_DESCRIPTOR:
+			break;
+
+		case MACH_MSG_OOL_DESCRIPTOR:
+			/* Arg is an out-of-line array: */
+        
+			/* Calculate size of array: */
+			GetArraySize(arg, size);
+			if (!(arg->argFlags & flDealloc) || (arg->argFlags & flOverwrite)) {
+				/* Copy argument to vm_allocated Temp: */
+				fprintf(file, "\t(void)vm_read(mach_task_self(),\n");
+				fprintf(file, "\t\t      (vm_address_t) %s%s, %s, (vm_address_t *) &_%sTemp_, &_MIG_Ignore_Count_);\n",
+						(arg->argByReferenceUser ? "*" : ""),
+						arg->argVarName, size, arg->argVarName);
+				if (!argIsIn(arg) && (arg->argFlags & flDealloc) &&
+					(arg->argFlags & flOverwrite)) {
+					/* Deallocate argument returned by server */
+					fprintf(file, "\t(void)vm_deallocate(mach_task_self(),");
+					fprintf(file, " (vm_address_t *) %s%s, %s);\n",
+							(arg->argByReferenceUser ? "*" : ""),
+							arg->argVarName, size);
+				}
+				/* Point argument at new temporary: */
+				fprintf(file, "\t*(char **)&%s%s = _%sTemp_;\n",
+						(arg->argByReferenceUser ? "*" : ""),
+						arg->argVarName,
+						arg->argVarName);
+			}
+			break;
+		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+			break;
+		default:
+			printf("MiG internal error: type of kernel processed data unknown\n");
+			exit(1);
+		}   /* end of switch */
+    } else if (it->itNumber != 1) {
+		/* Arg is an in-line array: */
+	}
+}
+
+
+static void
+WriteShortCircRPC(FILE *file, register routine_t *rt)
+{
+	register argument_t *arg;
+	register int server_argc, i;
+	boolean_t ShortCircOkay = TRUE;
+	boolean_t first_OOL_arg = TRUE;
+  
+    fprintf(file, "    if (0 /* Should be: !(%s & 0x3) XXX */) {\n",
+			rt->rtRequestPort->argVarName);
+  
+	if (rt->rtOneWay) {
+		/* Do not short-circuit simple routines: */
+		ShortCircOkay = FALSE;
+    } else {
+		/* Scan for any types we can't yet handle.  If found, give up on short-
+		 * circuiting and fall back to mach_msg:
+		 */
+		for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)  {
+			if (arg->argFlags & flMaybeDealloc) {
+				ShortCircOkay = FALSE;
+				break;
+			}
+			/* Can't yet handle ports: */
+			if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD) &&
+				(arg->argKPD_Type == MACH_MSG_PORT_DESCRIPTOR ||
+				 arg->argKPD_Type == MACH_MSG_OOL_PORTS_DESCRIPTOR)) {
+				ShortCircOkay = FALSE;
+				break;
+			}
+		}
+	}
+  
+	if (ShortCircOkay) {
+    
+		fprintf(file,
+				"      rpc_subsystem_t subsystem = ((rpc_port_t)%s)->rp_subsystem;\n",
+				rt->rtRequestPort->argVarName);
+		fprintf(file, "\n");
+		fprintf(file, "      if (subsystem && subsystem->start == %d) {\n",
+				SubsystemBase);
+		fprintf(file, "\tkern_return_t rtn;\n");
+		fprintf(file, "\n");
+    
+		/* Declare temp vars for out-of-line array args, and for all array
+		 * args, if -maxonstack has forced us to allocate in-line arrays
+		 * off the stack:
+		 */
+		rt->rtTempBytesOnStack = 0;
+		for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)  {
+			arg->argTempOnStack = FALSE;
+			if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD) &&
+				arg->argKPD_Type == MACH_MSG_OOL_DESCRIPTOR) {
+				if (first_OOL_arg) {
+					/* Need a garbage temporary to hold the datacount
+					 * returned by vm_read, which we always ignore:
+					 */
+					fprintf(file,
+							"\tmach_msg_type_number_t _MIG_Ignore_Count_;\n");
+					first_OOL_arg = FALSE;
+				}
+			} else if (!rtMessOnStack(rt) &&
+					   arg->argType->itNumber > 1 && !arg->argType->itStruct) {
+			} else
+				continue;
+			fprintf(file, "\tchar *_%sTemp_;\n", arg->argVarName);
+			rt->rtTempBytesOnStack += sizeof(char *);
+		}
+    
+		/* Process the IN arguments, in order: */
+    
+		fprintf(file, "\t/* Pre-Process the IN arguments: */\n");
+		for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+			if (argIsIn(arg))
+				WriteShortCircInArgBefore(file, arg);
+			if (argIsOut(arg))
+				WriteShortCircOutArgBefore(file, arg);
+		}
+		fprintf(file, "\n");
+    
+		/* Count the number of server args: */
+		server_argc = 0;
+		for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)
+			if (akCheck(arg->argKind, akbServerArg))
+				server_argc++;
+    
+		/* Call RPC_SIMPLE to switch to server stack and function: */
+		i = 0;
+		for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)  {
+			if (akIdent(arg->argKind) == akeRequestPort) {
+				fprintf(file, "\trtn = RPC_SIMPLE(%s, %d, %d, (",
+						arg->argVarName, rt->rtNumber + SubsystemBase,
+						server_argc);
+				fprintf(file, "%s", arg->argVarName);
+			} else if (akCheck(arg->argKind, akbServerArg)) {
+				if (i++ % 6 == 0)
+					fprintf(file, ",\n\t\t");
+				else
+					fprintf(file, ", ");
+				fprintf(file, "%s", arg->argVarName);
+			}
+		}
+		fprintf(file, "));\n");
+		fprintf(file, "\n");
+    
+		/* Process the IN and OUT arguments, in order: */
+		fprintf(file, "\t/* Post-Process the IN and OUT arguments: */\n");
+		for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext)  {
+			if (argIsIn(arg))
+				WriteShortCircInArgAfter(file, arg);
+			if (argIsOut(arg))
+				WriteShortCircOutArgAfter(file, arg);
+		}
+		fprintf(file, "\n");
+    
+		fprintf(file, "\treturn rtn;\n");
+		fprintf(file, "      }\n");
+	}
+  
+	/* In latest design, the following is not necessary, because in
+	 * kernel-loaded tasks, the Mach port name is the same as the handle
+	 * used by the RPC mechanism, namely a pointer to the ipc_port, and
+	 * in user-mode tasks, the Mach port name gets renamed to be a pointer
+	 * to the user-mode rpc_port_t struct.
+	 */
+#if 0
+	if (IsKernelUser)
+	    fprintf(file, "      %s = (ipc_port_t)%s->rp_receiver_name;\n",
+				rt->rtRequestPort->argVarName,
+				rt->rtRequestPort->argVarName);
+	else
+	    fprintf(file, "      %s = ((rpc_port_t)%s)->rp_receiver_name;\n",
+				rt->rtRequestPort->argVarName,
+				rt->rtRequestPort->argVarName);
+#endif
+  
+	fprintf(file, "    }\n");
+}
+
+static void
+WriteStubDecl(FILE *file, register routine_t *rt)
+{
+	fprintf(file, "\n");
+	fprintf(file, "/* %s %s */\n", rtRoutineKindToStr(rt->rtKind), rt->rtName);
+	fprintf(file, "mig_external %s %s\n", ReturnTypeStr(rt), rt->rtUserName);
+	if (BeAnsiC) {
+		fprintf(file, "(\n");
+		WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
+		fprintf(file, ")\n");
+    } else {
+		fprintf(file, "#if\t%s\n", NewCDecl);
+		fprintf(file, "(\n");
+		WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ",\n", "\n");
+		fprintf(file, ")\n");
+		fprintf(file, "#else\n");
+		fprintf(file, "\t(");
+		WriteList(file, rt->rtArgs, WriteNameDecl, akbUserArg, ", ", "");
+		fprintf(file, ")\n");
+		WriteList(file, rt->rtArgs, WriteUserVarDecl, akbUserArg, ";\n", ";\n");
+		fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+	}
+	fprintf(file, "{\n");
+}
+
+static void
+InitKPD_Disciplines(argument_t *args)
+{
+	argument_t *arg;
+	extern void KPD_noop();
+	extern void KPD_error();
+	extern void WriteTemplateKPD_port();
+	extern void WriteTemplateKPD_ool();
+	extern void WriteTemplateKPD_oolport();
+  
+	/*
+	 * WriteKPD_port,  WriteExtractKPD_port,
+	 * WriteKPD_ool,  WriteExtractKPD_ool,
+	 * WriteKPD_oolport,  WriteExtractKPD_oolport
+	 * are local to this module (which is the reason why this initialization
+	 * takes place here rather than in utils.c).
+	 * Common routines for user and server will be established SOON, and
+	 * all of them (including the initialization) will be transfert to
+	 * utils.c
+	 * All the KPD disciplines are defaulted to be KPD_error().
+	 * Note that akbSendKPD and akbReturnKPd are not exclusive,
+	 * because of inout type of parameters.
+	 */
+	for (arg = args; arg != argNULL; arg = arg->argNext)
+		if (akCheck(arg->argKind, akbSendKPD|akbReturnKPD))
+			switch (arg->argKPD_Type) {
+
+			case MACH_MSG_PORT_DESCRIPTOR:
+				arg->argKPD_Init = KPD_noop;
+				if akCheck(arg->argKind, akbSendKPD) {
+						arg->argKPD_Template = WriteTemplateKPD_port;
+						arg->argKPD_Pack = WriteKPD_port;
+					}
+				if akCheck(arg->argKind, akbReturnKPD) {
+						arg->argKPD_Extract = WriteExtractKPD_port;
+						arg->argKPD_TypeCheck = WriteTCheckKPD_port;
+					}
+				break;
+
+			case MACH_MSG_OOL_DESCRIPTOR:
+				arg->argKPD_Init = KPD_noop;
+				if akCheck(arg->argKind, akbSendKPD) {
+						arg->argKPD_Template = WriteTemplateKPD_ool;
+						arg->argKPD_Pack = WriteKPD_ool;
+					}
+				if akCheck(arg->argKind, akbReturnKPD) {
+						arg->argKPD_TypeCheck = WriteTCheckKPD_ool;
+						arg->argKPD_Extract = WriteExtractKPD_ool;
+					}
+				break;
+
+			case MACH_MSG_OOL_PORTS_DESCRIPTOR:
+				arg->argKPD_Init = KPD_noop;
+				if akCheck(arg->argKind, akbSendKPD) {
+						arg->argKPD_Template = WriteTemplateKPD_oolport;
+						arg->argKPD_Pack = WriteKPD_oolport;
+					}
+				if akCheck(arg->argKind, akbReturnKPD) {
+						arg->argKPD_TypeCheck = WriteTCheckKPD_oolport;
+						arg->argKPD_Extract = WriteExtractKPD_oolport;
+					}
+				break;
+
+			default:
+				printf("MiG internal error: type of kernel processed data unknown\n");
+				exit(1);
+			}   /* end of switch */
+}
+
+static void
+WriteLimitCheck(FILE *file, routine_t *rt)
+{
+	if (MaxMessSizeOnStack == -1 || UserTypeLimit == -1)
+		return;
+	if (!rt->rtRequestUsedLimit && !rt->rtReplyUsedLimit)
+		return;
+	fprintf(file, "#if LimitCheck\n");
+	if (rt->rtRequestUsedLimit) {
+		if (rt->rtRequestFits) {
+			fprintf(file, "\tif ((sizeof(Request) - %d) > %d)\n",
+					rt->rtRequestSizeKnown, UserTypeLimit);
+			fprintf(file, "\t    __RequestOnStackAbort(%d, \"%s\");\n",
+					SubsystemBase + rt->rtNumber, rt->rtName);
+		} else if (rt->rtReplyFits) {
+			fprintf(file, "\tif (sizeof(Request) < %d)\n",
+					MaxMessSizeOnStack);
+			fprintf(file, "\t    __MessageOffStackNote(%d, \"%s\");\n",
+					SubsystemBase + rt->rtNumber, rt->rtName);
+		}
+	}
+	if (rt->rtReplyUsedLimit) {
+		if (rt->rtReplyFits) {
+			fprintf(file, "\tif ((sizeof(Reply) - %d) > %d)\n",
+					rt->rtReplySizeKnown, UserTypeLimit);
+			fprintf(file, "\t    __ReplyOnStackAbort(%d, \"%s\");\n",
+					SubsystemBase + rt->rtNumber, rt->rtName);
+		} else if (rt->rtRequestFits) {
+			fprintf(file, "\tif (sizeof(Reply) < %d)\n",
+					MaxMessSizeOnStack);
+			fprintf(file, "\t    __MessageOffStackNote(%d, \"%s\");\n",
+					SubsystemBase + rt->rtNumber, rt->rtName);
+		}
+	}
+	if (rt->rtRequestUsedLimit && rt->rtReplyUsedLimit &&
+		! (rt->rtRequestFits || rt->rtReplyFits)) {
+        fprintf(file, "\tif (sizeof(Request) < %d \n",
+				MaxMessSizeOnStack);
+		fprintf(file, "&& sizeof(Reply) < %d)\n",
+				MaxMessSizeOnStack);
+		fprintf(file, "\t    __MessageOffStackNote(%d, \"%s\");\n",
+				SubsystemBase + rt->rtNumber, rt->rtName);
+	}
+	fprintf(file, "#endif /* LimitCheck */\n");
+}
+
+static void
+WriteCheckReply(FILE *file, routine_t *rt)
+{
+	u_int i;
+  
+	/* initialize the disciplines for the handling of KPDs */
+	InitKPD_Disciplines(rt->rtArgs);
+  
+	if (rt->rtOneWay)
+		return;
+  
+	fprintf(file, "\n");
+	fprintf(file, "#if ( __MigTypeCheck ");
+	if (CheckNDR)
+		fprintf(file, "|| __NDR_convert__ ");
+	fprintf(file, ")\n");
+	fprintf(file, "#if __MIG_check__Reply__%s_subsystem__\n", SubsystemName);
+	fprintf(file, "#if !defined(__MIG_check__Reply__%s_t__defined)\n", rt->rtName);
+	fprintf(file, "#define __MIG_check__Reply__%s_t__defined\n", rt->rtName);
+	if (CheckNDR && akCheck(rt->rtNdrCode->argKind, akbReply)) {
+		WriteList(file, rt->rtArgs, WriteReplyNDRConvertIntRepArgDecl, akbReturnNdr, "\n", "\n");
+		WriteList(file, rt->rtArgs, WriteReplyNDRConvertCharRepArgDecl, akbReturnNdr, "\n", "\n");
+		WriteList(file, rt->rtArgs, WriteReplyNDRConvertFloatRepArgDecl, akbReturnNdr, "\n", "\n");
+	}
+	fprintf(file, "\n");
+	fprintf(file, "mig_internal kern_return_t __MIG_check__Reply__%s_t(__Reply__%s_t *Out0P", rt->rtName, rt->rtName);
+	for (i = 1; i <= rt->rtMaxReplyPos; i++)
+		fprintf(file, ", __Reply__%s_t **Out%dPP", rt->rtName, i);
+	fprintf(file, ")\n{\n");
+  
+  
+	fprintf(file, "\n\ttypedef __Reply__%s_t __Reply;\n", rt->rtName);
+	for (i = 1; i <= rt->rtMaxReplyPos; i++)
+		fprintf(file, "\t__Reply *Out%dP;\n", i);
+	if (!rt->rtSimpleReply)
+		fprintf(file, "\tboolean_t msgh_simple;\n");
+	if (!rt->rtNoReplyArgs) {
+		fprintf(file, "#if\t__MigTypeCheck\n");
+		fprintf(file, "\tunsigned int msgh_size;\n");
+		fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+	}
+	if (rt->rtMaxReplyPos > 0)
+		fprintf(file, "\tunsigned int msgh_size_delta;\n");
+	if (rt->rtNumReplyVar > 0 || rt->rtMaxReplyPos > 0)
+		fprintf(file, "\n");
+  
+	/* Check the values that are returned in the reply message */
+  
+	WriteCheckIdentity(file, rt);
+  
+	/* If the reply message has no Out parameters or return values
+	   other than the return code, we can type-check it and
+	   return it directly. */
+  
+	if (rt->rtNoReplyArgs && !rt->rtUserImpl) {
+		if (CheckNDR && akCheck(rt->rtNdrCode->argKind, akbReply) && rt->rtRetCode)
+			WriteReplyNDRConvertIntRepOneArgUse(file, rt->rtRetCode);
+		WriteReturn(file, rt, "\t", stRetCode, "\n");
+	}
+	else {
+		if (UseEventLogger)
+			WriteLogMsg(file, rt, LOG_USER, LOG_REPLY);
+    
+		WriteRetCodeCheck(file, rt);
+    
+		/* Type Checking for the Out parameters which are typed */
+		WriteList(file, rt->rtArgs, WriteTypeCheck, akbReturnKPD, "\n", "\n");
+    
+		{
+			register argument_t *arg, *lastVarArg;
+      
+			lastVarArg = argNULL;
+			for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+				/*
+				 * Advance message pointer if the last reply argument was
+				 * variable-length and the reply position will change.
+				 */
+				if (lastVarArg != argNULL &&
+					lastVarArg->argReplyPos < arg->argReplyPos) {
+					WriteAdjustReplyMsgPtr(file, lastVarArg);
+					lastVarArg = argNULL;
+				}
+        
+				if (akCheckAll(arg->argKind, akbReturnRcv|akbReturnBody)) {
+					if (akCheck(arg->argKind, akbVariable)) {
+						WriteCheckMsgSize(file, arg);
+						lastVarArg = arg;
+					}
+				}
+			}
+		}
+    
+		if (CheckNDR && akCheck(rt->rtNdrCode->argKind, akbReply)) {
+			fprintf(file, "#if\t");
+			WriteList(file, rt->rtArgs, WriteReplyNDRConvertIntRepArgCond, akbReturnNdr, " || \\\n\t", "\n");
+			fprintf(file, "\tif (Out0P->NDR.int_rep != NDR_record.int_rep) {\n");
+			WriteList(file, rt->rtArgs, WriteReplyNDRConvertIntRepArgUse, akbReturnNdr, "", "");
+			fprintf(file, "\t}\n#endif\t/* defined(__NDR_convert__int_rep...) */\n\n");
+      
+			fprintf(file, "#if\t");
+			WriteList(file, rt->rtArgs, WriteReplyNDRConvertCharRepArgCond, akbReturnNdr, " || \\\n\t", "\n");
+			fprintf(file, "\tif (Out0P->NDR.char_rep != NDR_record.char_rep) {\n");
+			WriteList(file, rt->rtArgs, WriteReplyNDRConvertCharRepArgUse, akbReturnNdr, "", "");
+			fprintf(file, "\t}\n#endif\t/* defined(__NDR_convert__char_rep...) */\n\n");
+      
+			fprintf(file, "#if\t");
+			WriteList(file, rt->rtArgs, WriteReplyNDRConvertFloatRepArgCond, akbReturnNdr, " || \\\n\t", "\n");
+			fprintf(file, "\tif (Out0P->NDR.float_rep != NDR_record.float_rep) {\n");
+			WriteList(file, rt->rtArgs, WriteReplyNDRConvertFloatRepArgUse, akbReturnNdr, "", "");
+			fprintf(file, "\t}\n#endif\t/* defined(__NDR_convert__float_rep...) */\n\n");
+		}
+		fprintf(file, "\treturn MACH_MSG_SUCCESS;\n");
+	}
+	fprintf(file, "}\n");
+	fprintf(file, "#endif /* !defined(__MIG_check__Reply__%s_t__defined) */\n", rt->rtName);
+	fprintf(file, "#endif /* __MIG_check__Reply__%s_subsystem__ */\n", SubsystemName);
+	fprintf(file, "#endif /* ( __MigTypeCheck ");
+	if (CheckNDR)
+		fprintf(file, "|| __NDR_convert__ ");
+	fprintf(file, ") */\n\n");
+}
+
+static void
+WriteCheckReplyCall(FILE *file, routine_t *rt)
+{
+	u_int i;
+  
+	fprintf(file, "\n");
+	fprintf(file, "#if\tdefined(__MIG_check__Reply__%s_t__defined)\n", rt->rtName);
+	fprintf(file, "\tcheck_result = __MIG_check__Reply__%s_t((__Reply__%s_t *)Out0P", rt->rtName, rt->rtName);
+	for (i = 1; i <= rt->rtMaxReplyPos; i++)
+		fprintf(file, ", (__Reply__%s_t **)&Out%dP", rt->rtName, i);
+	fprintf(file, ");\n");
+	fprintf(file, "\tif (check_result != MACH_MSG_SUCCESS)\n");
+	WriteReturnMsgError(file, rt, TRUE, argNULL, "check_result");
+	fprintf(file, "#endif\t/* defined(__MIG_check__Reply__%s_t__defined) */\n", rt->rtName);
+	fprintf(file, "\n");
+}
+
+void
+WriteCheckReplies(FILE *file, statement_t *stats)
+{
+	statement_t *stat;
+  
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine)
+			WriteCheckReply(file, stat->stRoutine);
+}
+
+static void
+WriteCheckReplyTrailerArgs(FILE *file, routine_t *rt)
+{
+	register argument_t *arg;
+  
+	if (rt->rtUserImpl)
+		WriteCheckTrailerHead(file, rt, TRUE);
+  
+	for (arg = rt->rtArgs; arg != argNULL; arg = arg->argNext) {
+		if (akCheck(arg->argKind, akbUserImplicit))
+			WriteCheckTrailerSize(file, TRUE, arg);
+	}
+	if (rt->rtUserImpl)
+		fprintf(file, "\n");
+}
+
+
+/*************************************************************
+ *  Writes all the code comprising a routine body. Called by
+ *  WriteUser for each routine.
+ *************************************************************/
+static void
+WriteRoutine(FILE *file, register routine_t *rt)
+{
+	/* write the stub's declaration */
+	WriteStubDecl(file, rt);
+  
+	/* Use the RPC trap for user-user and user-kernel RPC */
+	if (UseRPCTrap)
+		WriteRPCRoutine(file, rt);
+  
+	/* write the code for doing a short-circuited RPC: */
+	if (ShortCircuit)
+		WriteShortCircRPC(file, rt);
+  
+	/* typedef of structure for Request and Reply messages */
+    WriteStructDecl(file, rt->rtArgs, WriteFieldDecl, akbRequest, 
+					"Request", rt->rtSimpleRequest, FALSE, FALSE, FALSE);
+	if (!rt->rtOneWay) {
+		WriteStructDecl(file, rt->rtArgs, WriteFieldDecl, akbReply, 
+						"Reply", rt->rtSimpleReply, TRUE, rt->rtUserImpl, FALSE);
+		WriteStructDecl(file, rt->rtArgs, WriteFieldDecl, akbReply, 
+						"__Reply", rt->rtSimpleReply, FALSE, FALSE, FALSE);
+	}
+	if (rt->rtOverwrite)
+		WriteStructDecl(file, rt->rtArgs, WriteFieldDecl, akbReply|akbOverwrite,
+						"OverwriteTemplate", FALSE, TRUE, FALSE, TRUE);
+	/*
+	 * Define a Minimal Reply structure to be used in case of errors
+	 */
+	fprintf(file, "\t/*\n");
+	fprintf(file, "\t * typedef struct {\n");
+	fprintf(file, "\t * \tmach_msg_header_t Head;\n");
+	fprintf(file, "\t * \tNDR_record_t NDR;\n");
+	fprintf(file, "\t * \tkern_return_t RetCode;\n");
+	fprintf(file, "\t * } mig_reply_error_t;\n");
+	fprintf(file, "\t */\n");
+	fprintf(file, "\n");
+  
+  
+	/* declarations for local vars: Union of Request and Reply messages,
+	   InP, OutP and return value */
+  
+	WriteVarDecls(file, rt);
+  
+	/* declarations and initializations of the mach_msg_type_descriptor_t variables
+	   for each argument that is a Kernel Processed Data */
+  
+	WriteList(file, rt->rtArgs, WriteTemplateDeclIn, akbRequest | akbSendKPD, "\n", "\n");
+  
+	WriteLimitCheck(file, rt);
+	WriteRetCodeArg(file, rt);
+  
+	/* fill in the fields that are non related to parameters */
+  
+	if (!rt->rtSimpleRequest)
+		fprintf(file, "\tInP->msgh_body.msgh_descriptor_count = %d;\n",
+				rt->rtRequestKPDs);
+  
+	/* fill in all the request message types and then arguments */
+  
+	WriteRequestArgs(file, rt);
+  
+	/* fill in request message head */
+  
+	WriteRequestHead(file, rt);
+	fprintf(file, "\n");
+  
+	/* give the application a chance to do some stuff. */
+	WriteApplMacro(file, "Send", "Before", rt);
+  
+	/* Write the send/receive or rpc call */
+  
+	if (UseEventLogger)
+		WriteLogMsg(file, rt, LOG_USER, LOG_REQUEST);
+  
+	if (rt->rtOneWay) {
+		WriteMsgSend(file, rt);
+	}
+	else {
+		if (UseMsgRPC
+#if USE_IMMEDIATE_SEND_TIMEOUT
+			&& (rt->rtWaitTime == argNULL)
+#endif
+			) {
+			/* overwrite mode meaningful only when UseMsgRPC is enabled */
+			if (rt->rtOverwrite)
+				WriteOverwriteTemplate(file, rt);
+			WriteMsgRPC(file, rt);
+		} else
+			WriteMsgSendReceive(file, rt);
+    
+		WriteCheckReplyCall(file, rt);
+		WriteCheckReplyTrailerArgs(file, rt);
+    
+		if (UseEventLogger)
+			WriteLogMsg(file, rt, LOG_USER, LOG_REPLY);
+    
+		WriteReplyArgs(file, rt);
+	}
+	/* return the return value, if any */
+	if (!rt->rtOneWay)  // WriteMsgSend() already wrote the 'return'
+		WriteReturnValue(file, rt);
+	fprintf(file, "}\n");
+}
+
+static void
+WriteRPCClientFunctions(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+    const char *fname;
+    const char *argfmt = "(mach_port_t, char *, mach_msg_type_number_t)";
+  
+	fprintf(file, "#ifdef AUTOTEST\n");
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		if (stat->stKind == skRoutine) {
+			fname = stat->stRoutine->rtName;
+			fprintf(file, "extern void client_%s%s;\n", fname, argfmt);
+		}
+	fprintf(file, "function_table_entry %s_client_functions[] =\n", SubsystemName);
+	fprintf(file, "{\n");
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+        if (stat->stKind == skRoutine)
+		{
+			fname = stat->stRoutine->rtName;
+			fprintf(file, "    { \"%s\", client_%s },\n", fname, fname);
+		}
+	fprintf(file, "    { (char *) 0, (function_ptr_t) 0 }\n");
+	fprintf(file, "};\n");
+	fprintf(file, "#endif /* AUTOTEST */\n");
+}
+
+/*************************************************************
+ *  Writes out the xxxUser.c file. Called by mig.c
+ *************************************************************/
+void
+WriteUser(FILE *file, statement_t *stats)
+{
+	register statement_t *stat;
+  
+	WriteProlog(file, stats);
+	if (TestRPCTrap)
+		WriteRPCClientFunctions(file, stats);
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		switch (stat->stKind)
+		{
+		case skRoutine:
+			WriteCheckReply(file, stat->stRoutine);
+			WriteRoutine(file, stat->stRoutine);
+			break;
+		case skImport:
+		case skUImport:
+		case skSImport:
+		case skDImport:
+		case skIImport:
+			break;
+		default:
+			fatal("WriteUser(): bad statement_kind_t (%d)",
+				  (int) stat->stKind);
+		}
+	WriteEpilog(file);
+}
+
+/*************************************************************
+ *  Writes out individual .c user files for each routine.  Called by mig.c
+ *************************************************************/
+void
+WriteUserIndividual(statement_t *stats)
+{
+	register statement_t *stat;
+  
+	for (stat = stats; stat != stNULL; stat = stat->stNext)
+		switch (stat->stKind)
+		{
+		case skRoutine:
+	    {
+			FILE *file;
+			char *filename;
+        
+			filename = (char *)(uintptr_t)strconcat(UserFilePrefix,
+										 strconcat(stat->stRoutine->rtName, ".c"));
+			file = fopen(filename, "w");
+			if (file == NULL)
+				fatal("fopen(%s): %s", filename,
+					  strerror(errno));
+			WriteProlog(file, stats);
+			WriteRoutine(file, stat->stRoutine);
+			WriteEpilog(file);
+			fclose(file);
+			strfree(filename);
+		}
+		case skUImport:
+		case skSImport:
+		case skDImport:
+		case skIImport:
+			break;
+		default:
+			fatal("WriteUserIndividual(): bad statement_kind_t (%d)",
+				  (int) stat->stKind);
+		}
+}


Property changes on: trunk/usr.bin/migcom/user.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/utils.c
===================================================================
--- trunk/usr.bin/migcom/utils.c	                        (rev 0)
+++ trunk/usr.bin/migcom/utils.c	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,1103 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014, Matthew Macy <kmacy at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 at 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.
+ */
+/*
+ * 92/03/03  16:25:39  jeffreyh
+ * 	Changes from TRUNK
+ * 	[92/02/26  12:33:02  jeffreyh]
+ * 
+ * 92/01/14  16:47:08  rpd
+ * 	Modified WriteTypeDeclIn and WriteTypeDeclOut to disable
+ * 	the deallocate flag on Indefinite arguments.
+ * 	[92/01/09            rpd]
+ * 
+ * 92/01/03  20:30:51  dbg
+ * 	Change argByReferenceUser and argByReferenceServer to fields in
+ * 	argument_t.
+ * 	[91/08/29            dbg]
+ * 
+ * 91/07/31  18:11:45  dbg
+ * 	Accept new dealloc_t argument type in WriteStaticDecl,
+ * 	WritePackMsgType.
+ * 
+ * 	Don't need to zero last character of C string.  Mig_strncpy does
+ * 	the proper work.
+ * 
+ * 	Add SkipVFPrintf, so that WriteCopyType doesn't print fields in
+ * 	comments.
+ * 	[91/07/17            dbg]
+ * 
+ * 91/06/25  10:32:36  rpd
+ * 	Changed WriteVarDecl to WriteUserVarDecl.
+ * 	Added WriteServerVarDecl.
+ * 	[91/05/23            rpd]
+ * 
+ * 91/02/05  17:56:28  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:56:39  mrt]
+ * 
+ * 90/06/02  15:06:11  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:14:54  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 21-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Added deallocflag to the WritePackMsg routines.
+ *
+ * 29-Jul-87  Mary Thompson (mrt) at Carnegie-Mellon University
+ *	Changed WriteVarDecl to not automatically write
+ *	semi-colons between items, so that it can be
+ *	used to write C++ argument lists.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "type.h"
+
+#include <mach/message.h>
+#include "routine.h"
+#include "write.h"
+#include "global.h"
+#include "routine.h"
+#include "utils.h"
+#include "alloc.h"
+
+
+void
+WriteIdentificationString(FILE *file)
+{
+  
+  fprintf(file, "/*\n");
+  fprintf(file, " * IDENTIFICATION:\n");
+  fprintf(file, " * stub generated %s", GenerationDate);
+    fprintf(file, " * with a MiG generated %s by %s\n", MigGenerationDate, MigMoreData);
+  fprintf(file, " * OPTIONS: \n");
+  if (IsKernelUser)
+    fprintf(file, " *\tKernelUser\n");
+  if (IsKernelServer)
+    fprintf(file, " *\tKernelServer\n");
+  if (!UseMsgRPC)
+    fprintf(file, " *\t-R (no RPC calls)\n");
+  fprintf(file, " */\n");
+}
+
+void
+WriteMigExternal(FILE *file)
+{
+  fprintf(file, "#ifdef\tmig_external\n");
+  fprintf(file, "mig_external\n");
+  fprintf(file, "#else\n");
+  fprintf(file, "extern\n");
+  fprintf(file, "#endif\t/* mig_external */\n");
+}
+
+void
+WriteMigInternal(FILE *file)
+{
+  fprintf(file, "#ifdef\tmig_internal\n");
+  fprintf(file, "mig_internal\n");
+  fprintf(file, "#else\n");
+  fprintf(file, "static\n");
+  fprintf(file, "#endif\t/* mig_internal */\n");
+}
+
+void
+WriteImport(FILE *file, string_t filename)
+{
+  fprintf(file, "#include %s\n", filename);
+}
+
+void
+WriteImplImports(FILE *file, statement_t *stats, boolean_t isuser)
+{
+  register statement_t *stat;
+  
+  for (stat = stats; stat != stNULL; stat = stat->stNext)
+	switch (stat->stKind)
+	{
+      case skImport:
+      case skIImport:
+        WriteImport(file, stat->stFileName);
+        break;
+      case skSImport:
+        if (!isuser)
+          WriteImport(file, stat->stFileName);
+        break;
+      case skUImport:
+        if (isuser)
+          WriteImport(file, stat->stFileName);
+        break;
+      case skRoutine:
+      case skDImport:
+        break;
+      default:
+	    printf("WriteImplImport(): bad statement_kind_t (%d)",
+			   (int) stat->stKind);
+		abort();
+    }
+}
+
+void
+WriteRCSDecl(FILE *file, identifier_t name, string_t rcs)
+{
+  fprintf(file, "#ifndef\tlint\n");
+  fprintf(file, "#if\tUseExternRCSId\n");
+  fprintf(file, "%s char %s_rcsid[] = %s;\n", (BeAnsiC) ? "const" : "", name, rcs);
+  fprintf(file, "#else\t/* UseExternRCSId */\n");
+  fprintf(file, "static %s char rcsid[] = %s;\n", (BeAnsiC) ? "const" : "", rcs);
+  fprintf(file, "#endif\t/* UseExternRCSId */\n");
+  fprintf(file, "#endif\t/* lint */\n");
+  fprintf(file, "\n");
+}
+
+static void
+WriteOneApplDefault(FILE *file, const char *word1, const char *word2, const char *word3)
+{
+  char buf[50];
+  
+  sprintf(buf, "__%s%s%s", word1, word2, word3);
+  fprintf(file, "#ifndef\t%s\n", buf);
+  fprintf(file, "#define\t%s(_NUM_, _NAME_)\n", buf);
+  fprintf(file, "#endif\t/* %s */\n", buf);
+  fprintf(file, "\n");
+}
+
+void
+WriteApplDefaults(FILE *file, const char *dir)
+{
+  WriteOneApplDefault(file, "Declare", dir, "Rpc");
+  WriteOneApplDefault(file, "Before", dir, "Rpc");
+  WriteOneApplDefault(file, "After", dir, "Rpc");
+  WriteOneApplDefault(file, "Declare", dir, "Simple");
+  WriteOneApplDefault(file, "Before", dir, "Simple");
+  WriteOneApplDefault(file, "After", dir, "Simple");
+}
+
+void
+WriteApplMacro(FILE *file, const char *dir, const char *when, routine_t *rt)
+{
+    const char *what = (rt->rtOneWay) ? "Simple" : "Rpc";
+  
+    fprintf(file, "\t__%s%s%s(%d, \"%s\")\n", 
+	    when, dir, what, SubsystemBase + rt->rtNumber, rt->rtName);
+}
+
+void
+WriteBogusDefines(FILE *file)
+{
+  fprintf(file, "#ifndef\tmig_internal\n");
+  fprintf(file, "#define\tmig_internal\tstatic __inline__\n");
+  fprintf(file, "#endif\t/* mig_internal */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#ifndef\tmig_external\n");
+  fprintf(file, "#define mig_external\n");
+  fprintf(file, "#endif\t/* mig_external */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#if\t!defined(__MigTypeCheck) && defined(TypeCheck)\n");
+  fprintf(file, "#define\t__MigTypeCheck\t\tTypeCheck\t/* Legacy setting */\n");
+  fprintf(file, "#endif\t/* !defined(__MigTypeCheck) */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#if\t!defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_)\n");
+  fprintf(file, "#define\t__MigKernelSpecificCode\t_MIG_KERNEL_SPECIFIC_CODE_\t/* Legacy setting */\n");
+  fprintf(file, "#endif\t/* !defined(__MigKernelSpecificCode) */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#ifndef\tLimitCheck\n");
+  fprintf(file, "#define\tLimitCheck 0\n");
+  fprintf(file, "#endif\t/* LimitCheck */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#ifndef\tmin\n");
+  fprintf(file, "#define\tmin(a,b)  ( ((a) < (b))? (a): (b) )\n");
+  fprintf(file, "#endif\t/* min */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#if !defined(_WALIGN_)\n");
+  fprintf(file, "#define _WALIGN_(x) (((x) + %d) & ~%d)\n", (int)(itWordAlign - 1), (int)(itWordAlign - 1));
+  fprintf(file, "#endif /* !defined(_WALIGN_) */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#if !defined(_WALIGNSZ_)\n");
+  fprintf(file, "#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))\n");
+  fprintf(file, "#endif /* !defined(_WALIGNSZ_) */\n");
+  fprintf(file, "\n");
+  
+  fprintf(file, "#ifndef\tUseStaticTemplates\n");
+  if (BeAnsiC) {
+        fprintf(file, "#define\tUseStaticTemplates\t1\n");
+    } else {
+    fprintf(file, "#if\t%s\n", NewCDecl);
+        fprintf(file, "#define\tUseStaticTemplates\t1\n");
+    fprintf(file, "#endif\t/* %s */\n", NewCDecl);
+  }
+  fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+  fprintf(file, "\n");
+  
+    fprintf(file, "#define _WALIGN_(x) (((x) + %ld) & ~%ld)\n",
+	    itWordAlign - 1, itWordAlign - 1);
+    fprintf(file, "#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))\n");
+}
+
+void
+WriteList(FILE *file, argument_t *args, void (*func)(), u_int mask, const char *between, const char *after)
+{
+	argument_t *arg;
+	boolean_t sawone = FALSE;
+
+	for (arg = args; arg != argNULL; arg = arg->argNext) {
+		if (akCheckAll(arg->argKind, mask)) {
+			if (sawone)
+				fprintf(file, "%s", between);
+			sawone = TRUE;
+      
+			(*func)(file, arg);
+		}
+	}
+	if (sawone)
+		fprintf(file, "%s", after);
+}
+
+static boolean_t
+WriteReverseListPrim(FILE *file, argument_t *arg, void (*func)(), u_int mask, const char *between)
+{
+  boolean_t sawone = FALSE;
+  
+    if (arg != argNULL)
+    {
+    sawone = WriteReverseListPrim(file, arg->argNext, func, mask, between);
+    
+	if (akCheckAll(arg->argKind, mask))
+	{
+      if (sawone)
+        fprintf(file, "%s", between);
+      sawone = TRUE;
+      
+      (*func)(file, arg);
+    }
+  }
+  
+  return sawone;
+}
+
+void
+WriteReverseList(FILE *file, argument_t *args, void (*func)(), u_int mask, const char *between, const char *after)
+{
+  boolean_t sawone;
+  
+  sawone = WriteReverseListPrim(file, args, func, mask, between);
+  
+  if (sawone)
+    fprintf(file, "%s", after);
+}
+
+void
+WriteNameDecl(FILE *file, argument_t *arg)
+{
+  fprintf(file, "%s", arg->argVarName);
+}
+
+void
+WriteUserVarDecl(FILE *file, argument_t *arg)
+{
+  boolean_t pointer = (arg->argByReferenceUser ||arg->argType->itNativePointer);
+  const char *ref = (pointer) ? "*" : "";
+  const char *cnst = ((arg->argFlags & flConst) &&
+                (IS_VARIABLE_SIZED_UNTYPED(arg->argType) ||
+                 arg->argType->itNoOptArray || arg->argType->itString)) ? "const " : "";
+  
+  fprintf(file, "\t%s%s %s%s", cnst, arg->argType->itUserType, ref, arg->argVarName);
+}
+
+void
+WriteServerVarDecl(FILE *file, argument_t *arg)
+{
+    const char *ref = (arg->argByReferenceServer ||
+               arg->argType->itNativePointer) ? "*" : "";
+	const char *cnst = ((arg->argFlags & flConst) &&
+                (IS_VARIABLE_SIZED_UNTYPED(arg->argType) ||
+                 arg->argType->itNoOptArray || arg->argType->itString)) ? "const " : "";
+  
+  fprintf(file, "\t%s%s %s%s", cnst, arg->argType->itTransType, ref, arg->argVarName);
+}
+
+const char *
+ReturnTypeStr(routine_t *rt)
+{
+  return rt->rtRetCode->argType->itUserType;
+}
+
+const char *
+FetchUserType(ipc_type_t *it)
+{
+  return it->itUserType;
+}
+
+const char *
+FetchServerType(ipc_type_t *it)
+{
+  return it->itServerType;
+}
+
+const char *
+FetchKPDType(ipc_type_t *it)
+{
+  return it->itKPDType;
+}
+
+static void
+WriteTrailerDecl(FILE *file, boolean_t trailer)
+{
+  if (trailer)
+    fprintf(file, "\t\tmach_msg_max_trailer_t trailer;\n");
+  else
+    fprintf(file, "\t\tmach_msg_trailer_t trailer;\n");
+}
+
+void
+WriteFieldDeclPrim(FILE *file, argument_t *arg, const char *(*tfunc)(ipc_type_t *))
+{
+  register ipc_type_t *it = arg->argType;
+  
+  if (IS_VARIABLE_SIZED_UNTYPED(it) || it->itNoOptArray) {
+    register argument_t *count = arg->argCount;
+    register ipc_type_t *btype = it->itElement;
+    
+    /*
+     * Build our own declaration for a varying array:
+     * use the element type and maximum size specified.
+     * Note arg->argCount->argMultiplier == btype->itNumber.
+     */
+    /*
+     * NDR encoded VarStrings requires the offset field.
+     * Since it is not used, it wasn't worthwhile to create an extra
+     * parameter
+     */
+    if (it->itString)
+		fprintf(file, "\t\t%s %sOffset; /* MiG doesn't use it */\n",
+				(*tfunc)(count->argType), arg->argName);
+
+    if (!(arg->argFlags & flSameCount) && !it->itNoOptArray)
+    /* in these cases we would have a count, which we don't want */
+		fprintf(file, "\t\t%s %s;\n", (*tfunc)(count->argType), 
+		    count->argMsgField);
+	fprintf(file, "\t\t%s %s[%d];",
+			(*tfunc)(btype),
+			arg->argMsgField,
+			it->itNumber/btype->itNumber);
+  }
+  else if (IS_MULTIPLE_KPD(it))
+	fprintf(file, "\t\t%s %s[%d];", (*tfunc)(it), arg->argMsgField,
+			it->itKPD_Number);
+  else if (IS_OPTIONAL_NATIVE(it)) {
+    fprintf(file, "\t\tboolean_t __Present__%s;\n",  arg->argMsgField);
+    fprintf(file, "\t\tunion {\n");
+	fprintf(file, "\t\t    %s __Real__%s;\n",
+		(*tfunc)(it), arg->argMsgField);
+	fprintf(file, "\t\t    char __Phony__%s[_WALIGNSZ_(%s)];\n",
+		arg->argMsgField, (*tfunc)(it));
+    fprintf(file, "\t\t} %s;", arg->argMsgField);
+  }
+  else  {
+    /* either simple KPD or simple in-line */
+    fprintf(file, "\t\t%s %s;", (*tfunc)(it), arg->argMsgField);
+  }
+  
+  /* Kernel Processed Data has always PadSize = 0 */
+  if (it->itPadSize != 0)
+    fprintf(file, "\n\t\tchar %s[%d];", arg->argPadName, it->itPadSize);
+}
+
+void
+WriteKPDFieldDecl(FILE *file, argument_t *arg)
+{
+  if (akCheck(arg->argKind, akbSendKPD) ||
+      akCheck(arg->argKind, akbReturnKPD))
+    WriteFieldDeclPrim(file, arg, FetchKPDType);
+  else
+    WriteFieldDeclPrim(file, arg, FetchServerType);
+}
+
+void
+WriteStructDecl(FILE *file, argument_t *args, void (*func)(), u_int mask,
+				const char *name, boolean_t simple, boolean_t trailer,
+				boolean_t trailer_t, boolean_t template_only)
+{
+  fprintf(file, "\n#ifdef  __MigPackStructs\n#pragma pack(%lu)\n#endif\n",sizeof(natural_t));
+  fprintf(file, "\ttypedef struct {\n");
+  fprintf(file, "\t\tmach_msg_header_t Head;\n");
+  if (simple == FALSE) {
+    fprintf(file, "\t\t/* start of the kernel processed data */\n");
+    fprintf(file, "\t\tmach_msg_body_t msgh_body;\n");
+    if (mask == akbRequest)
+      WriteList(file, args, func, mask | akbSendKPD, "\n", "\n");
+    else
+      WriteList(file, args, func, mask | akbReturnKPD, "\n", "\n");
+    fprintf(file, "\t\t/* end of the kernel processed data */\n");
+  }
+  if (!template_only) {
+    if (mask == akbRequest)
+      WriteList(file, args, func, mask | akbSendBody, "\n", "\n");
+    
+    else
+      WriteList(file, args, func, mask | akbReturnBody, "\n", "\n");
+    if (trailer)
+      WriteTrailerDecl(file, trailer_t);
+  }
+  fprintf(file, "\t} %s;\n", name);
+  fprintf(file, "#ifdef  __MigPackStructs\n#pragma pack()\n#endif\n");
+}
+
+void
+WriteTemplateDeclIn(FILE *file, register argument_t *arg)
+{
+  (*arg->argKPD_Template)(file, arg, TRUE);
+}
+
+void
+WriteTemplateDeclOut(FILE *file, register argument_t *arg)
+{
+  (*arg->argKPD_Template)(file, arg, FALSE);
+}
+
+void
+WriteTemplateKPD_port(FILE *file, argument_t *arg, boolean_t in)
+{
+  register ipc_type_t *it = arg->argType;
+  
+  fprintf(file, "#if\tUseStaticTemplates\n");
+  fprintf(file, "\tconst static %s %s = {\n", it->itKPDType, arg->argTTName);
+  
+  fprintf(file, "\t\t.name = MACH_PORT_NULL,\n");
+  fprintf(file, "\t\t.disposition = %s,\n", in ? it->itInNameStr: it->itOutNameStr);
+  fprintf(file, "\t\t.type = MACH_MSG_PORT_DESCRIPTOR,\n");
+  
+  fprintf(file, "\t};\n");
+  fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+}
+
+void
+WriteTemplateKPD_ool(FILE *file, argument_t *arg, boolean_t in __unused)
+{
+  register ipc_type_t *it = arg->argType;
+  
+  fprintf(file, "#if\tUseStaticTemplates\n");
+  fprintf(file, "\tconst static %s %s = {\n", it->itKPDType, arg->argTTName);
+  
+  if (IS_MULTIPLE_KPD(it))
+    it = it->itElement;
+  
+  fprintf(file, "\t\t.address = (void *)0,\n");
+  if (it->itVarArray)
+    fprintf(file, "\t\t.size = 0,\n");
+  else
+	fprintf(file, "\t\t.size = %d,\n",
+	    (it->itNumber * it->itSize + 7)/8);
+    fprintf(file, "\t\t.deallocate = %s,\n",
+	(arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
+  /* the d_MAYBE case will be fixed runtime */
+    fprintf(file, "\t\t.copy = %s,\n",
+	(arg->argFlags & flPhysicalCopy) ? "MACH_MSG_PHYSICAL_COPY" : "MACH_MSG_VIRTUAL_COPY");
+  /* the PHYSICAL COPY flag has not been established yet */
+  fprintf(file, "\t\t.type = MACH_MSG_OOL_DESCRIPTOR,\n");
+  
+  fprintf(file, "\t};\n");
+  fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+}
+
+void
+WriteTemplateKPD_oolport(FILE *file, argument_t *arg, boolean_t in)
+{
+  register ipc_type_t *it = arg->argType;
+  
+  fprintf(file, "#if\tUseStaticTemplates\n");
+  fprintf(file, "\tconst static %s %s = {\n", it->itKPDType, arg->argTTName);
+  
+  if (IS_MULTIPLE_KPD(it))
+    it = it->itElement;
+  
+  fprintf(file, "\t\t.address = (void *)0,\n");
+  if (!it->itVarArray)
+	fprintf(file, "\t\t.count = %d,\n",
+	    it->itNumber);
+  else
+    fprintf(file, "\t\t.count = 0,\n");
+    fprintf(file, "\t\t.deallocate = %s,\n",
+        (arg->argDeallocate == d_YES) ? "TRUE" : "FALSE");
+  fprintf(file, "\t\t/* copy is meaningful only in overwrite mode */\n");
+  fprintf(file, "\t\t.copy = MACH_MSG_PHYSICAL_COPY,\n");
+    fprintf(file, "\t\t.disposition = %s,\n",
+	in ? it->itInNameStr: it->itOutNameStr);
+  fprintf(file, "\t\t.type = MACH_MSG_OOL_PORTS_DESCRIPTOR,\n");
+  
+  fprintf(file, "\t};\n");
+  fprintf(file, "#endif\t/* UseStaticTemplates */\n");
+}
+
+void
+WriteReplyTypes(FILE *file, statement_t *stats)
+{
+  register statement_t *stat;
+  
+  fprintf(file, "/* typedefs for all replies */\n\n");
+  fprintf(file, "#ifndef __Reply__%s_subsystem__defined\n", SubsystemName);
+  fprintf(file, "#define __Reply__%s_subsystem__defined\n", SubsystemName);
+  for (stat = stats; stat != stNULL; stat = stat->stNext) {
+    if (stat->stKind == skRoutine) {
+      register routine_t *rt;
+      char str[MAX_STR_LEN];
+      
+      rt = stat->stRoutine;
+      sprintf(str, "__Reply__%s_t", rt->rtName);
+      WriteStructDecl(file, rt->rtArgs, WriteKPDFieldDecl, akbReply, str, rt->rtSimpleReply, FALSE, FALSE, FALSE);
+    }
+  }
+  fprintf(file, "#endif /* !__Reply__%s_subsystem__defined */\n", SubsystemName);
+  fprintf(file, "\n");
+}
+
+void
+WriteRequestTypes(FILE *file, statement_t *stats)
+{
+  register statement_t *stat;
+  
+  fprintf(file, "/* typedefs for all requests */\n\n");
+  fprintf(file, "#ifndef __Request__%s_subsystem__defined\n", SubsystemName);
+  fprintf(file, "#define __Request__%s_subsystem__defined\n", SubsystemName);
+  for (stat = stats; stat != stNULL; stat = stat->stNext) {
+    if (stat->stKind == skRoutine) {
+      register routine_t *rt;
+      char str[MAX_STR_LEN];
+      
+      rt = stat->stRoutine;
+      sprintf(str, "__Request__%s_t", rt->rtName);
+      WriteStructDecl(file, rt->rtArgs, WriteKPDFieldDecl, akbRequest, str, rt->rtSimpleRequest, FALSE, FALSE, FALSE);
+    }
+  }
+  fprintf(file, "#endif /* !__Request__%s_subsystem__defined */\n", SubsystemName);
+  fprintf(file, "\n");
+}
+
+void
+WriteNDRConvertArgDecl(FILE *file, argument_t *arg, const char *convert, const char *dir)
+{
+  argument_t *count = arg->argCount;
+  argument_t *parent = arg->argParent;
+  const char *carg = (count) ? ", c" : "";
+  routine_t *rt = arg->argRoutine;
+  ipc_type_t *ptype = arg->argType;
+  ipc_type_t *btype;
+  int multi, array;
+  char domain[MAX_STR_LEN];
+  
+  fprintf(file, "#ifndef __NDR_convert__%s__%s__%s_t__%s__defined\n#", convert, dir, rt->rtName, arg->argMsgField);
+  
+  for (btype = ptype, multi = (!parent) ? arg->argMultiplier : 1, array = 0;
+       btype;
+       ptype = btype, array += ptype->itVarArray, btype = btype->itElement) {
+	  const char *bttype;
+    
+    if (btype->itNumber < ptype->itNumber && !ptype->itVarArray && !parent) {
+      multi *= ptype->itNumber / btype->itNumber;
+      if (!btype->itString)
+        continue;
+    }
+    else if (array && ptype->itVarArray)
+      continue;
+    if (btype != ptype)
+      fprintf(file, "#el");
+    
+    bttype = (multi > 1 && btype->itString) ? "string" : FetchServerType(btype);
+    sprintf(domain, "__%s", SubsystemName);
+    do {
+      fprintf(file, "if\tdefined(__NDR_convert__%s%s__%s__defined)\n", convert, domain, bttype);
+      fprintf(file, "#define\t__NDR_convert__%s__%s__%s_t__%s__defined\n", convert, dir, rt->rtName, arg->argMsgField);
+      fprintf(file, "#define\t__NDR_convert__%s__%s__%s_t__%s(a, f%s) \\\n\t", convert, dir, rt->rtName, arg->argMsgField, carg);
+      if (multi > 1) {
+        if (array) {
+          if (btype->itString)
+            fprintf(file, "__NDR_convert__2DARRAY((%s *)(a), f, %d, c, ", bttype, multi);
+          else
+            fprintf(file, "__NDR_convert__ARRAY((%s *)(a), f, %d * (c), ", bttype, multi);
+        }
+        else if (!btype->itString)
+          fprintf(file, "__NDR_convert__ARRAY((%s *)(a), f, %d, ", bttype, multi);
+      }
+      else if (array)
+        fprintf(file, "__NDR_convert__ARRAY((%s *)(a), f, c, ", bttype);
+      fprintf(file, "__NDR_convert__%s%s__%s", convert, domain, bttype);
+      if (multi > 1) {
+        if (!array && btype->itString)
+          fprintf(file, "(a, f, %d", multi);
+      }
+      else if (!array)
+        fprintf(file, "((%s *)(a), f%s", bttype, carg);
+      fprintf(file, ")\n");
+    } while (strcmp(domain, "") && (domain[0] = '\0', fprintf(file, "#el")));
+  }
+  fprintf(file, "#endif /* defined(__NDR_convert__*__defined) */\n");
+  fprintf(file, "#endif /* __NDR_convert__%s__%s__%s_t__%s__defined */\n\n", convert, dir, rt->rtName, arg->argMsgField);
+}
+
+/*
+ * Like vfprintf, but omits a leading comment in the format string
+ * and skips the items that would be printed by it.  Only %s, %d,
+ * and %f are recognized.
+ */
+static void
+SkipVFPrintf(FILE *file, const char *fmt, va_list pvar)
+{
+  if (*fmt == 0)
+    return; /* degenerate case */
+  
+  if (fmt[0] == '/' && fmt[1] == '*') {
+    /* Format string begins with C comment.  Scan format
+       string until end-comment delimiter, skipping the
+       items in pvar that the enclosed format items would
+       print. */
+    
+    register int c;
+    
+    fmt += 2;
+    for (;;) {
+      c = *fmt++;
+      if (c == 0)
+        return; /* nothing to format */
+      if (c == '*') {
+        if (*fmt == '/') {
+          break;
+        }
+      }
+      else if (c == '%') {
+        /* Field to skip */
+        c = *fmt++;
+        switch (c) {
+
+          case 's':
+            (void) va_arg(pvar, char *);
+            break;
+
+          case 'd':
+            (void) va_arg(pvar, int);
+            break;
+
+          case 'f':
+            (void) va_arg(pvar, double);
+            break;
+
+          case '\0':
+            return; /* error - fmt ends with '%' */
+
+          default:
+            break;
+        }
+      }
+    }
+    /* End of comment.  To be pretty, skip
+     the space that follows. */
+    fmt++;
+    if (*fmt == ' ')
+      fmt++;
+  }
+  
+  /* Now format the string. */
+  (void) vfprintf(file, fmt, pvar);
+}
+
+static void
+vWriteCopyType(FILE *file, ipc_type_t *it, const char *left, const char *right, va_list pvar)
+{
+  va_list pv2;
+  __va_copy(pv2,pvar);
+    if (it->itStruct)
+    {
+    fprintf(file, "\t");
+    (void) SkipVFPrintf(file, left, pvar);
+    fprintf(file, " = ");
+	(void) SkipVFPrintf(file, right, pv2);
+    fprintf(file, ";\n");
+  }
+    else if (it->itString)
+    {
+    fprintf(file, "\t(void) mig_strncpy(");
+    (void) SkipVFPrintf(file, left, pvar);
+    fprintf(file, ", ");
+	(void) SkipVFPrintf(file, right, pv2);
+    fprintf(file, ", %d);\n", it->itTypeSize);
+  }
+    else
+    {
+	fprintf(file, "\t{   typedef struct { char data[%d]; } *sp;\n",
+		it->itTypeSize);
+    fprintf(file, "\t    * (sp) ");
+    (void) SkipVFPrintf(file, left, pvar);
+    fprintf(file, " = * (sp) ");
+	(void) SkipVFPrintf(file, right, pv2);
+    fprintf(file, ";\n\t}\n");
+  }
+
+  va_end(pv2);
+}
+
+
+/*ARGSUSED*/
+/*VARARGS4*/
+void
+WriteCopyType(FILE *file, ipc_type_t *it, const char *left, const char *right, ...)
+{
+  va_list pvar;
+  va_start(pvar, right);
+  
+  vWriteCopyType(file, it, left, right, pvar);
+  
+  va_end(pvar);
+}
+
+
+/*ARGSUSED*/
+/*VARARGS4*/
+void
+WriteCopyArg(FILE *file, argument_t *arg, const char *left, const char *right, ...)
+{
+  va_list pvar;
+  va_start(pvar, right);
+  
+  {
+    ipc_type_t *it = arg->argType;
+    if (it->itVarArray && !it->itString) {
+      fprintf(file, "\t    (void)memcpy(");
+      (void) SkipVFPrintf(file, left, pvar);
+	  va_end(pvar);
+      fprintf(file, ", ");
+	  va_start(pvar, right);
+	  (void) SkipVFPrintf(file, right, pvar);
+      fprintf(file, ", %s);\n", arg->argCount->argVarName);
+	} else
+      vWriteCopyType(file, it, left, right, pvar);
+  }
+  
+  va_end(pvar);
+}
+
+
+/*
+ * Global KPD disciplines
+ */
+void
+KPD_error(FILE *file __unused, argument_t *arg)
+{
+  printf("MiG internal error: argument is %s\n", arg->argVarName);
+  exit(1);
+}
+
+void
+KPD_noop(FILE *file __unused, argument_t *arg __unused)
+{
+}
+
+static void
+WriteStringDynArgs(args, mask, InPOutP, str_oolports, str_ool)
+    argument_t *args;
+    u_int	mask;
+    string_t 	InPOutP;
+    string_t 	*str_oolports, *str_ool;
+{
+  argument_t *arg;
+  char loc[100], sub[20];
+  string_t tmp_str1 = "";
+  string_t tmp_str2 = "";
+  int cnt, multiplier = 1;
+  boolean_t test, complex = FALSE;
+  
+  for (arg = args; arg != argNULL; arg = arg->argNext) {
+    ipc_type_t *it = arg->argType;
+    
+    if (IS_MULTIPLE_KPD(it)) {
+      test = it->itVarArray || it->itElement->itVarArray;
+      if (test) {
+        multiplier = it->itKPD_Number;
+        it = it->itElement;
+        complex = TRUE;
+      }
+	} else
+      test = it->itVarArray;
+    
+    cnt = multiplier;
+    while (cnt) {
+      if (complex)
+        sprintf(sub, "[%d]", multiplier - cnt);
+      if (akCheck(arg->argKind, mask) &&
+          it->itPortType && !it->itInLine && test) {
+		    sprintf(loc, " + %s->%s%s.count", InPOutP, arg->argMsgField,
+		        complex ? sub : "");
+        tmp_str1 = strconcat(tmp_str1, loc);
+      }
+      if (akCheck(arg->argKind, mask) &&
+          !it->itInLine && !it->itPortType && test) {
+	 	    sprintf(loc, " + %s->%s%s.size", InPOutP, arg->argMsgField,
+		        complex ? sub : "");
+        tmp_str2 = strconcat(tmp_str2, loc);
+      }
+      cnt--;
+    }
+  }
+  *str_oolports = tmp_str1;
+  *str_ool = tmp_str2;
+}
+
+/*
+ * Utilities for Logging Events that happen at the stub level
+ */
+void
+WriteLogMsg(FILE *file, routine_t *rt, boolean_t where, boolean_t what)
+{
+  string_t ptr_str;
+  string_t StringOolPorts = strNULL;
+  string_t StringOOL = strNULL;
+  u_int ports, oolports, ool;
+  string_t event;
+  
+  fprintf(file, "\n#if  MIG_DEBUG\n");
+  if (where == LOG_USER)
+    fprintf(file, "\tLOG_TRACE(MACH_MSG_LOG_USER,\n");
+  else
+    fprintf(file, "\tLOG_TRACE(MACH_MSG_LOG_SERVER,\n");
+  if (where == LOG_USER && what == LOG_REQUEST) {
+    ptr_str = "InP";
+    event = "MACH_MSG_REQUEST_BEING_SENT";
+    } else if (where == LOG_USER && what == LOG_REPLY) {
+    ptr_str = "Out0P";
+    event = "MACH_MSG_REPLY_BEING_RCVD";
+    } else if (where == LOG_SERVER && what == LOG_REQUEST) {
+    ptr_str = "In0P";
+    event = "MACH_MSG_REQUEST_BEING_RCVD";
+    } else {
+    ptr_str = "OutP";
+    event = "MACH_MSG_REPLY_BEING_SENT";
+  }
+    WriteStringDynArgs(rt->rtArgs, 
+	(what == LOG_REQUEST) ? akbSendKPD : akbReturnKPD, 
+	ptr_str, &StringOolPorts, &StringOOL);
+  fprintf(file, "\t\t%s,\n", event);
+  fprintf(file, "\t\t%s->Head.msgh_id,\n", ptr_str);
+  if (where == LOG_USER && what == LOG_REQUEST) {
+    if (rt->rtNumRequestVar)
+      fprintf(file, "\t\tmsgh_size,\n");
+    else
+	    fprintf(file, "\t\tsizeof(Request),\n");
+    } else 
+    fprintf(file, "\t\t%s->Head.msgh_size,\n", ptr_str);
+  if ((what == LOG_REQUEST && rt->rtSimpleRequest == FALSE) ||
+      (what == LOG_REPLY && rt->rtSimpleReply == FALSE))
+    fprintf(file, "\t\t%s->msgh_body.msgh_descriptor_count,\n", ptr_str);
+  else
+    fprintf(file, "\t\t0, /* Kernel Proc. Data entries */\n");
+  if (what == LOG_REQUEST) {
+    fprintf(file, "\t\t0, /* RetCode */\n");
+    ports = rt->rtCountPortsIn;
+    oolports = rt->rtCountOolPortsIn;
+    ool = rt->rtCountOolIn;
+    } else {
+    if (akCheck(rt->rtRetCode->argKind, akbReply))
+      fprintf(file, "\t\t%s->RetCode,\n", ptr_str);
+    else
+      fprintf(file, "\t\t0, /* RetCode */\n");
+    ports = rt->rtCountPortsOut;
+    oolports = rt->rtCountOolPortsOut;
+    ool = rt->rtCountOolOut;
+  }
+  fprintf(file, "\t\t/* Ports */\n");
+  fprintf(file, "\t\t%d,\n", ports);
+  fprintf(file, "\t\t/* Out-of-Line Ports */\n");
+  fprintf(file, "\t\t%d", oolports);
+  if (StringOolPorts != strNULL)
+    fprintf(file, "%s,\n", StringOolPorts);
+  else
+    fprintf(file, ",\n");
+  fprintf(file, "\t\t/* Out-of-Line Bytes */\n");
+  fprintf(file, "\t\t%d", ool);
+  if (StringOOL != strNULL)
+    fprintf(file, "%s,\n", StringOOL);
+  else
+    fprintf(file, ",\n");
+  fprintf(file, "\t\t__FILE__, __LINE__);\n");
+  fprintf(file, "#endif /* MIG_DEBUG */\n\n");
+}
+
+void
+WriteLogDefines(FILE *file, string_t who)
+{
+  fprintf(file, "#if  MIG_DEBUG\n");
+  fprintf(file, "#define LOG_W_E(X)\tLOG_ERRORS(%s, \\\n", who);
+  fprintf(file, "\t\t\tMACH_MSG_ERROR_WHILE_PARSING, (void *)(X), __FILE__, __LINE__)\n");
+  fprintf(file, "#else  /* MIG_DEBUG */\n");
+  fprintf(file, "#define LOG_W_E(X)\n");
+  fprintf(file, "#endif /* MIG_DEBUG */\n");
+  fprintf(file, "\n");
+}
+
+/* common utility to report errors */
+void
+WriteReturnMsgError(FILE *file, routine_t *rt, boolean_t isuser, argument_t *arg, string_t error)
+{
+  char space[MAX_STR_LEN];
+  char * string = &space[0];
+  
+  if (UseEventLogger && arg != argNULL)
+    sprintf(string, "LOG_W_E(\"%s\"); ", arg->argVarName);
+  else
+	  string = __DECONST(char *, "");
+  
+  fprintf(file, "\t\t{ ");
+  
+  if (isuser) {
+    if (! rtMessOnStack(rt))
+		fprintf(file, "%s((char *) Mess, sizeof(*Mess)); ", MessFreeRoutine);
+    
+    fprintf(file, "%sreturn %s; }\n", string, error);
+  }
+  else
+    fprintf(file, "%sMIG_RETURN_ERROR(OutP, %s); }\n", string, error);
+}
+
+/* executed iff elements are defined */
+void
+WriteCheckTrailerHead(FILE *file, routine_t *rt __unused, boolean_t isuser)
+{
+  string_t who = (isuser) ? "Out0P" : "In0P";
+  
+  fprintf(file, "\tTrailerP = (mach_msg_max_trailer_t *)((vm_offset_t)%s +\n", who);
+  fprintf(file, "\t\tround_msg(%s->Head.msgh_size));\n", who);
+  fprintf(file, "\tif (TrailerP->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0)\n");
+  if (isuser)
+    fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
+  else
+    fprintf(file, "\t\t{ MIG_RETURN_ERROR(%s, MIG_TRAILER_ERROR); }\n", who);
+  
+  fprintf(file, "#if\t__MigTypeCheck\n");
+  fprintf(file, "\ttrailer_size = TrailerP->msgh_trailer_size -\n");
+  fprintf(file, "\t\t(mach_msg_size_t)(sizeof(mach_msg_trailer_type_t) - sizeof(mach_msg_trailer_size_t));\n");
+  fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+}
+
+/* executed iff elements are defined */
+void
+WriteCheckTrailerSize(FILE *file, boolean_t isuser, register argument_t *arg)
+{
+  fprintf(file, "#if\t__MigTypeCheck\n");
+  if (akIdent(arg->argKind) == akeMsgSeqno) {
+    fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(mach_port_seqno_t))\n");
+    if (isuser)
+      fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
+    else
+      fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
+    fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(mach_port_seqno_t);\n");
+  }
+  else if (akIdent(arg->argKind) == akeSecToken) {
+    fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(security_token_t))\n");
+    if (isuser)
+      fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
+    else
+      fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
+    fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(security_token_t);\n");
+  }
+  else if (akIdent(arg->argKind) == akeAuditToken) {
+    fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(audit_token_t))\n");
+    if (isuser)
+      fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
+    else
+      fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
+    fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(audit_token_t);\n");
+  }
+  else if (akIdent(arg->argKind) == akeContextToken) {
+    fprintf(file, "\tif (trailer_size < (mach_msg_size_t)sizeof(mach_vm_address_t))\n");
+    if (isuser)
+      fprintf(file, "\t\t{ return MIG_TRAILER_ERROR ; }\n");
+    else
+      fprintf(file, "\t\t{ MIG_RETURN_ERROR(OutP, MIG_TRAILER_ERROR); }\n");
+    fprintf(file, "\ttrailer_size -= (mach_msg_size_t)sizeof(mach_vm_address_t);\n");
+  }
+  fprintf(file, "#endif\t/* __MigTypeCheck */\n");
+}
+


Property changes on: trunk/usr.bin/migcom/utils.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/utils.h
===================================================================
--- trunk/usr.bin/migcom/utils.h	                        (rev 0)
+++ trunk/usr.bin/migcom/utils.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,165 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ * 
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ * 
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ * 
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/06/25  10:32:47  rpd
+ * 	Changed WriteVarDecl to WriteUserVarDecl.
+ * 	Added WriteServerVarDecl.
+ * 	[91/05/23            rpd]
+ * 
+ * 91/02/05  17:56:33  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:56:48  mrt]
+ * 
+ * 90/06/02  15:06:16  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:15:06  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ * Extensive revamping.  Added polymorphic arguments.
+ * Allow multiple variable-sized inline arguments in messages.
+ *
+ * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ * Created.
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include "type.h"
+
+/* definitions used by the Event Logger */
+
+#define LOG_USER 0
+#define LOG_SERVER 1
+
+#define LOG_REQUEST 0
+#define LOG_REPLY 1
+
+/* stuff used by more than one of header.c, user.c, server.c */
+
+extern void WriteMigExternal(FILE *file);
+extern void WriteMigInternal(FILE *file);
+
+extern void WriteImport(FILE *file, string_t filename);
+extern void WriteRCSDecl(FILE *file, identifier_t name, string_t rcs);
+extern void WriteBogusDefines(FILE *file);
+
+extern void WriteList(FILE *file, argument_t *args,
+  void (*func)(FILE *file, argument_t *arg),
+			 u_int mask, const char *between, const char *after);
+
+extern void WriteReverseList(FILE *file, argument_t *args,
+ void (*func)(FILE *file, argument_t *arg),
+				u_int mask, const char *between, const char *after);
+
+/* good as arguments to WriteList */
+extern void WriteNameDecl(FILE *file, argument_t *arg);
+extern void WriteUserVarDecl(FILE *file, argument_t *arg);
+extern void WriteServerVarDecl(FILE *file, argument_t *arg);
+extern void WriteTemplateDeclIn(FILE *file, argument_t *arg);
+extern void WriteTemplateDeclOut(FILE *file, argument_t *arg);
+extern void WriteTemplateKPD_port(FILE *file, argument_t *arg, boolean_t in);
+extern void WriteTemplateKPD_ool(FILE *file, argument_t *arg, boolean_t in __unused);
+extern void WriteTemplateKPD_oolport(FILE *file, argument_t *arg, boolean_t in __unused);
+extern void WriteLogDefines(FILE *file, string_t who);
+extern void WriteCheckDecl(FILE *file, argument_t *arg);
+
+extern const char *ReturnTypeStr( routine_t *rt );
+
+extern const char *FetchUserType( ipc_type_t *it );
+extern const char *FetchServerType( ipc_type_t *it );
+extern const char *FetchKPDType( ipc_type_t *it );
+extern void WriteKPDFieldDecl(FILE *file, argument_t *arg);
+
+extern void WriteFieldDeclPrim( FILE *file, argument_t *arg, const char *(*tfunc)(ipc_type_t *it) );
+
+extern void WriteStructDecl(FILE *file, argument_t *args,
+        void (*func)(FILE *file, argument_t *arg),
+			       u_int mask, const char *name,
+        boolean_t simple, boolean_t trailer,
+        boolean_t isuser,
+        boolean_t template_only );
+
+extern void WriteStaticDecl( FILE *file, argument_t *arg );
+
+extern void WriteCopyType(FILE *file, ipc_type_t *it, const char *left, const char *right, ...);
+
+extern void WriteCopyArg(FILE *file, argument_t *arg, const char *left, const char *right, ...);
+
+extern void WriteLogMsg( FILE *file, routine_t *rt, int where, int what );
+
+extern void WriteCheckTrailerHead( FILE *file, routine_t *rt, boolean_t isuser );
+
+extern void WriteCheckTrailerSize( FILE *file, boolean_t isuser, argument_t *arg );
+
+extern void WriteReturnMsgError( FILE *file, routine_t *rt, boolean_t isuser, argument_t *arg, string_t error );
+
+extern void  WriteRPCRoutineDescriptor( FILE *file, routine_t *rt,  int arg_count, int descr_count, string_t stub_routine, string_t sig_array );
+
+extern void WriteRPCRoutineArgDescriptor( FILE *file, routine_t *rt );
+
+extern void WriteRequestTypes( FILE *file, statement_t *stats);
+extern void WriteCheckRequests( FILE *file, statement_t *stats);
+extern void WriteUserRequestUnion( FILE *file, statement_t *stats );
+extern void WriteServerRequestUnion( FILE *file, statement_t *stats );
+
+extern void WriteReplyTypes( FILE *file, statement_t *stats);
+extern void WriteCheckReplies( FILE *file, statement_t *stats);
+extern void WriteUserReplyUnion( FILE *file, statement_t *stats );
+extern void WriteServerReplyUnion( FILE *file, statement_t *stats );
+
+extern void WriteNDRConvertArgDecl( FILE *file, argument_t *arg, const char *convert, const char *dir);
+extern void WriteIdentificationString(FILE *file);
+
+extern void KPD_error(FILE *file,argument_t *arg);
+extern void KPD_noop(FILE *file,argument_t *arg);
+
+
+#endif /* _UTILS_H */


Property changes on: trunk/usr.bin/migcom/utils.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.bin/migcom/write.h
===================================================================
--- trunk/usr.bin/migcom/write.h	                        (rev 0)
+++ trunk/usr.bin/migcom/write.h	2016-01-03 17:31:36 UTC (rev 7395)
@@ -0,0 +1,98 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 1991-1998 by Open Software Foundation, Inc. 
+ *              All Rights Reserved 
+ *  
+ * Permission to use, copy, modify, and distribute this software and 
+ * its documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appears in all copies and 
+ * that both the copyright notice and this permission notice appear in 
+ * supporting documentation. 
+ *  
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE. 
+ *  
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
+ */
+/*
+ * cmk1.1
+ */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 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 
+ * 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 at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * 91/08/28  11:17:39  jsb
+ * 	Removed TrapRoutine support.
+ * 	[91/08/12            rpd]
+ * 
+ * 91/06/25  10:32:55  rpd
+ * 	Changed WriteHeader to WriteUserHeader.
+ * 	Added WriteServerHeader.
+ * 	[91/05/23            rpd]
+ * 
+ * 91/02/05  17:56:38  mrt
+ * 	Changed to new Mach copyright
+ * 	[91/02/01  17:56:55  mrt]
+ * 
+ * 90/06/02  15:06:20  rpd
+ * 	Created for new IPC.
+ * 	[90/03/26  21:15:16  rpd]
+ * 
+ * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Extensive revamping.  Added polymorphic arguments.
+ *	Allow multiple variable-sized inline arguments in messages.
+ *
+ * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
+ *	Created.
+ */
+
+#ifndef	_WRITE_H
+#define	_WRITE_H
+
+#include <stdio.h>
+#include "statement.h"
+
+extern void WriteUserHeader(FILE *file, statement_t *stats);
+extern void WriteServerHeader(FILE *file, statement_t *stats);
+extern void WriteServerRoutine(FILE *file, routine_t *rt);
+extern void WriteInternalHeader(FILE *file, statement_t *stats);
+extern void WriteDefinesHeader( FILE *file, statement_t *stats);
+extern void WriteUser( FILE *file, statement_t *stats );
+extern void WriteUserIndividual( statement_t *stats );
+extern void WriteServer( FILE *file, statement_t *stats );
+extern void WriteIncludes( FILE *file, boolean_t isuser, 
+			     boolean_t is_def );
+extern void WriteImplImports( FILE *file, statement_t *stats, 
+				boolean_t isuser );
+extern void WriteApplDefaults(FILE *file, const char *dir);
+extern void WriteApplMacro(FILE *file, const char *dir, const char *when, 
+			      routine_t *rt);
+
+#endif	/* _WRITE_H */


Property changes on: trunk/usr.bin/migcom/write.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list