Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Add an awk program that reads in a device call inte...



details:   https://anonhg.NetBSD.org/src/rev/d02b5302dd5c
branches:  trunk
changeset: 1023570:d02b5302dd5c
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Sep 15 17:25:14 2021 +0000

description:
Add an awk program that reads in a device call interface description
file and emits a header file containing the argument and call binding
structures for those calls.

diffstat:

 sys/kern/gendevcalls.awk |  208 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 208 insertions(+), 0 deletions(-)

diffs (212 lines):

diff -r b62b8d8e8a98 -r d02b5302dd5c sys/kern/gendevcalls.awk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/kern/gendevcalls.awk  Wed Sep 15 17:25:14 2021 +0000
@@ -0,0 +1,208 @@
+#! /usr/bin/awk -f
+#      $NetBSD: gendevcalls.awk,v 1.1 2021/09/15 17:25:14 thorpej Exp $
+#
+# Copyright (c) 2021 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Jason R. Thorpe.
+#
+# 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, 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+#
+# Parses a device call definition file and produces argument and
+# binding structures.
+#
+
+function emit_binding(field) {
+       printf("union %s_binding {\n", call_name_ub)
+       printf("\tstruct device_call_generic generic;\n")
+       if (field != "") {
+               printf("\tstruct {\n")
+               printf("\t\tconst char *name;\n")
+               printf("\t\tstruct %s_args *args;\n", call_name_ub)
+               printf("\t} %s;\n", field);
+       }
+       printf("};\n")
+}
+
+function emit_name_macro() {
+       printf("\n")
+       printf("#define %s_STR \"%s\"\n", call_name_ub_uc, call_name)
+}
+
+function emit_invoke_macro(field, marg, carg) {
+       printf("\n")
+       printf("#define %s%s \\\n", call_name_ub_uc, marg)
+       printf("\t&((const union %s_binding){ \\\n", call_name_ub)
+       printf("\t\t.%s.name = \"%s\", \\\n", field, call_name)
+       printf("\t\t.%s.args = %s, \\\n", field, carg)
+       printf("\t})\n")
+}
+
+function start_decl(arg) {
+       if (state == "expecting-subsystem") {
+               print "must declare a subsystem before declaring a call " \
+                   "at line " NR \
+                   > "/dev/stderr"
+               exit 1
+       }
+
+       if (state != "expecting-decl-start") {
+               print "unexpected start of declaration at line " NR \
+                   > "/dev/stderr"
+               exit 1
+       }
+
+       call_name = arg
+
+       if (index(call_name, call_name_prefix) != 1) {
+               printf("method name '%s' at line %d must begin with '%s'\n", \
+                   call_name, NR, call_name_prefix) \
+                   > "/dev/stderr"
+               exit 1
+       }
+
+       call_name_ub = arg
+       gsub("\-", "_", call_name_ub)
+       call_name_ub_uc = toupper(call_name_ub)
+}
+
+NR == 1 {
+       VERSION = $0
+       gsub("\\$", "", VERSION)
+       gsub(/ $/, "", VERSION)
+
+       printf("/*\t$NetBSD" "$\t*/\n\n")
+       printf("/*\n")
+       printf(" * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.\n")
+       printf(" *\n")
+       printf(" * generated from:\n")
+       printf(" *\t%s\n", VERSION)
+       printf(" */\n")
+
+       subsystem = ""
+       state = "expecting-subsystem"
+
+       next
+}
+#
+# Subystem declaration.  We use this to generate header file guards,
+# as well as to sanity-check the method names when they are declared.
+#
+state == "expecting-subsystem" && \
+/^subsystem[ \t]+[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]*;[ \t]*$/ {
+       subsystem = $2
+
+       # strip the trailing ;
+       gsub(";$", "", subsystem)
+
+       subsystem_ub = subsystem
+       gsub("\-", "_", subsystem_ub)
+       subsystem_ub_uc = toupper(subsystem_ub)
+
+       # now tack on a trailing - for sanity checking method
+       # names later.
+       call_name_prefix = subsystem "-"
+
+       # Emit the leading header guard.
+       printf("#ifndef _%s_CALLS_H_\n", subsystem_ub_uc)
+       printf("#define _%s_CALLS_H_\n", subsystem_ub_uc)
+
+       # Pull in <sys/device.h> for 'struct device_call_generic'.
+       printf("\n#include <sys/device.h>\n")
+
+       state = "expecting-decl-start"
+
+       next
+}
+#
+# Beginning of a call-with-arguments declaration.  Gather up the various
+# forms of the method name and emit the beginning of the structure declaration.
+#
+/^[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]+{[ \t]*$/ {
+       start_decl($1)
+
+       # Emit the args structure declaration.
+       printf("struct %s_args {\n", call_name_ub)
+
+       state = "expecting-decl-end"
+
+       next
+}
+#
+# A call-without-arguments declaration.
+#
+/^[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]*;[ \t]*$/ {
+       # strip the trailing ;
+       call_name = $1
+       gsub(";$", "", call_name)
+
+       start_decl(call_name)
+
+       emit_binding("")
+       emit_name_macro()
+       emit_invoke_macro("generic", "", "NULL")
+
+       next
+}
+#
+# End of a declaration.  Wrap up the structure declaration and emit
+# the binding information.
+#
+/^}[ \t]*;[ \t]*$/ {
+       if (state != "expecting-decl-end") {
+               print "unexpected end of declaration at line " NR \
+                   > "/dev/stderr"
+               exit 1
+       }
+
+       # Terminate the args structure declaration.
+       printf("};\n")
+
+       printf("\n")
+       emit_binding("binding")
+       emit_name_macro()
+       emit_invoke_macro("binding", "(_args_)", "(_args_)")
+
+       state = "expecting-decl-start"
+
+       next
+}
+#
+# Default action is to simply emit the line as it exists in the source
+# file.
+#
+{
+       print $0
+}
+END {
+       if (state != "expecting-decl-start") {
+               print "unexpected end of file at line " NR \
+                   > "/dev/stderr"
+               exit 1
+       }
+
+       # Emit the trailing header guard.
+       printf("\n#endif /* _%s_CALLS_H_ */\n", subsystem_ub_uc)
+}



Home | Main Index | Thread Index | Old Index