Home | History | Annotate | Line # | Download | only in kern
      1  1.1  thorpej #! /usr/bin/awk -f
      2  1.2   andvar #	$NetBSD: gendevcalls.awk,v 1.2 2024/02/09 22:08:37 andvar Exp $
      3  1.1  thorpej #
      4  1.1  thorpej # Copyright (c) 2021 The NetBSD Foundation, Inc.
      5  1.1  thorpej # All rights reserved.
      6  1.1  thorpej #
      7  1.1  thorpej # This code is derived from software contributed to The NetBSD Foundation
      8  1.1  thorpej # by Jason R. Thorpe.
      9  1.1  thorpej #
     10  1.1  thorpej # Redistribution and use in source and binary forms, with or without
     11  1.1  thorpej # modification, are permitted provided that the following conditions
     12  1.1  thorpej # are met:
     13  1.1  thorpej # 1. Redistributions of source code must retain the above copyright
     14  1.1  thorpej #    notice, this list of conditions and the following disclaimer.
     15  1.1  thorpej # 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  thorpej #    notice, this list of conditions and the following disclaimer in the
     17  1.1  thorpej #    documentation and/or other materials provided with the distribution.
     18  1.1  thorpej #
     19  1.1  thorpej # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  1.1  thorpej # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  1.1  thorpej # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  1.1  thorpej # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  1.1  thorpej # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  1.1  thorpej # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  1.1  thorpej # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  1.1  thorpej # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  1.1  thorpej # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  1.1  thorpej # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1  thorpej # POSSIBILITY OF SUCH DAMAGE.
     30  1.1  thorpej #
     31  1.1  thorpej 
     32  1.1  thorpej #
     33  1.1  thorpej # Parses a device call definition file and produces argument and
     34  1.1  thorpej # binding structures.
     35  1.1  thorpej #
     36  1.1  thorpej 
     37  1.1  thorpej function emit_binding(field) {
     38  1.1  thorpej 	printf("union %s_binding {\n", call_name_ub)
     39  1.1  thorpej 	printf("\tstruct device_call_generic generic;\n")
     40  1.1  thorpej 	if (field != "") {
     41  1.1  thorpej 		printf("\tstruct {\n")
     42  1.1  thorpej 		printf("\t\tconst char *name;\n")
     43  1.1  thorpej 		printf("\t\tstruct %s_args *args;\n", call_name_ub)
     44  1.1  thorpej 		printf("\t} %s;\n", field);
     45  1.1  thorpej 	}
     46  1.1  thorpej 	printf("};\n")
     47  1.1  thorpej }
     48  1.1  thorpej 
     49  1.1  thorpej function emit_name_macro() {
     50  1.1  thorpej 	printf("\n")
     51  1.1  thorpej 	printf("#define %s_STR \"%s\"\n", call_name_ub_uc, call_name)
     52  1.1  thorpej }
     53  1.1  thorpej 
     54  1.1  thorpej function emit_invoke_macro(field, marg, carg) {
     55  1.1  thorpej 	printf("\n")
     56  1.1  thorpej 	printf("#define %s%s \\\n", call_name_ub_uc, marg)
     57  1.1  thorpej 	printf("\t&((const union %s_binding){ \\\n", call_name_ub)
     58  1.1  thorpej 	printf("\t\t.%s.name = \"%s\", \\\n", field, call_name)
     59  1.1  thorpej 	printf("\t\t.%s.args = %s, \\\n", field, carg)
     60  1.1  thorpej 	printf("\t})\n")
     61  1.1  thorpej }
     62  1.1  thorpej 
     63  1.1  thorpej function start_decl(arg) {
     64  1.1  thorpej 	if (state == "expecting-subsystem") {
     65  1.1  thorpej 		print "must declare a subsystem before declaring a call " \
     66  1.1  thorpej 		    "at line " NR \
     67  1.1  thorpej 		    > "/dev/stderr"
     68  1.1  thorpej 		exit 1
     69  1.1  thorpej 	}
     70  1.1  thorpej 
     71  1.1  thorpej 	if (state != "expecting-decl-start") {
     72  1.1  thorpej 		print "unexpected start of declaration at line " NR \
     73  1.1  thorpej 		    > "/dev/stderr"
     74  1.1  thorpej 		exit 1
     75  1.1  thorpej 	}
     76  1.1  thorpej 
     77  1.1  thorpej 	call_name = arg
     78  1.1  thorpej 
     79  1.1  thorpej 	if (index(call_name, call_name_prefix) != 1) {
     80  1.1  thorpej 		printf("method name '%s' at line %d must begin with '%s'\n", \
     81  1.1  thorpej 		    call_name, NR, call_name_prefix) \
     82  1.1  thorpej 		    > "/dev/stderr"
     83  1.1  thorpej 		exit 1
     84  1.1  thorpej 	}
     85  1.1  thorpej 
     86  1.1  thorpej 	call_name_ub = arg
     87  1.1  thorpej 	gsub("\-", "_", call_name_ub)
     88  1.1  thorpej 	call_name_ub_uc = toupper(call_name_ub)
     89  1.1  thorpej }
     90  1.1  thorpej 
     91  1.1  thorpej NR == 1 {
     92  1.1  thorpej 	VERSION = $0
     93  1.1  thorpej 	gsub("\\$", "", VERSION)
     94  1.1  thorpej 	gsub(/ $/, "", VERSION)
     95  1.1  thorpej 
     96  1.1  thorpej 	printf("/*\t$NetBSD" "$\t*/\n\n")
     97  1.1  thorpej 	printf("/*\n")
     98  1.1  thorpej 	printf(" * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.\n")
     99  1.1  thorpej 	printf(" *\n")
    100  1.1  thorpej 	printf(" * generated from:\n")
    101  1.1  thorpej 	printf(" *\t%s\n", VERSION)
    102  1.1  thorpej 	printf(" */\n")
    103  1.1  thorpej 
    104  1.1  thorpej 	subsystem = ""
    105  1.1  thorpej 	state = "expecting-subsystem"
    106  1.1  thorpej 
    107  1.1  thorpej 	next
    108  1.1  thorpej }
    109  1.1  thorpej #
    110  1.2   andvar # Subsystem declaration.  We use this to generate header file guards,
    111  1.1  thorpej # as well as to sanity-check the method names when they are declared.
    112  1.1  thorpej #
    113  1.1  thorpej state == "expecting-subsystem" && \
    114  1.1  thorpej /^subsystem[ \t]+[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]*;[ \t]*$/ {
    115  1.1  thorpej 	subsystem = $2
    116  1.1  thorpej 
    117  1.1  thorpej 	# strip the trailing ;
    118  1.1  thorpej 	gsub(";$", "", subsystem)
    119  1.1  thorpej 
    120  1.1  thorpej 	subsystem_ub = subsystem
    121  1.1  thorpej 	gsub("\-", "_", subsystem_ub)
    122  1.1  thorpej 	subsystem_ub_uc = toupper(subsystem_ub)
    123  1.1  thorpej 
    124  1.1  thorpej 	# now tack on a trailing - for sanity checking method
    125  1.1  thorpej 	# names later.
    126  1.1  thorpej 	call_name_prefix = subsystem "-"
    127  1.1  thorpej 
    128  1.1  thorpej 	# Emit the leading header guard.
    129  1.1  thorpej 	printf("#ifndef _%s_CALLS_H_\n", subsystem_ub_uc)
    130  1.1  thorpej 	printf("#define _%s_CALLS_H_\n", subsystem_ub_uc)
    131  1.1  thorpej 
    132  1.1  thorpej 	# Pull in <sys/device.h> for 'struct device_call_generic'.
    133  1.1  thorpej 	printf("\n#include <sys/device.h>\n")
    134  1.1  thorpej 
    135  1.1  thorpej 	state = "expecting-decl-start"
    136  1.1  thorpej 
    137  1.1  thorpej 	next
    138  1.1  thorpej }
    139  1.1  thorpej #
    140  1.1  thorpej # Beginning of a call-with-arguments declaration.  Gather up the various
    141  1.1  thorpej # forms of the method name and emit the beginning of the structure declaration.
    142  1.1  thorpej #
    143  1.1  thorpej /^[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]+{[ \t]*$/ {
    144  1.1  thorpej 	start_decl($1)
    145  1.1  thorpej 
    146  1.1  thorpej 	# Emit the args structure declaration.
    147  1.1  thorpej 	printf("struct %s_args {\n", call_name_ub)
    148  1.1  thorpej 
    149  1.1  thorpej 	state = "expecting-decl-end"
    150  1.1  thorpej 
    151  1.1  thorpej 	next
    152  1.1  thorpej }
    153  1.1  thorpej #
    154  1.1  thorpej # A call-without-arguments declaration.
    155  1.1  thorpej #
    156  1.1  thorpej /^[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]*;[ \t]*$/ {
    157  1.1  thorpej 	# strip the trailing ;
    158  1.1  thorpej 	call_name = $1
    159  1.1  thorpej 	gsub(";$", "", call_name)
    160  1.1  thorpej 
    161  1.1  thorpej 	start_decl(call_name)
    162  1.1  thorpej 
    163  1.1  thorpej 	emit_binding("")
    164  1.1  thorpej 	emit_name_macro()
    165  1.1  thorpej 	emit_invoke_macro("generic", "", "NULL")
    166  1.1  thorpej 
    167  1.1  thorpej 	next
    168  1.1  thorpej }
    169  1.1  thorpej #
    170  1.1  thorpej # End of a declaration.  Wrap up the structure declaration and emit
    171  1.1  thorpej # the binding information.
    172  1.1  thorpej #
    173  1.1  thorpej /^}[ \t]*;[ \t]*$/ {
    174  1.1  thorpej 	if (state != "expecting-decl-end") {
    175  1.1  thorpej 		print "unexpected end of declaration at line " NR \
    176  1.1  thorpej 		    > "/dev/stderr"
    177  1.1  thorpej 		exit 1
    178  1.1  thorpej 	}
    179  1.1  thorpej 
    180  1.1  thorpej 	# Terminate the args structure declaration.
    181  1.1  thorpej 	printf("};\n")
    182  1.1  thorpej 
    183  1.1  thorpej 	printf("\n")
    184  1.1  thorpej 	emit_binding("binding")
    185  1.1  thorpej 	emit_name_macro()
    186  1.1  thorpej 	emit_invoke_macro("binding", "(_args_)", "(_args_)")
    187  1.1  thorpej 
    188  1.1  thorpej 	state = "expecting-decl-start"
    189  1.1  thorpej 
    190  1.1  thorpej 	next
    191  1.1  thorpej }
    192  1.1  thorpej #
    193  1.1  thorpej # Default action is to simply emit the line as it exists in the source
    194  1.1  thorpej # file.
    195  1.1  thorpej #
    196  1.1  thorpej {
    197  1.1  thorpej 	print $0
    198  1.1  thorpej }
    199  1.1  thorpej END {
    200  1.1  thorpej 	if (state != "expecting-decl-start") {
    201  1.1  thorpej 		print "unexpected end of file at line " NR \
    202  1.1  thorpej 		    > "/dev/stderr"
    203  1.1  thorpej 		exit 1
    204  1.1  thorpej 	}
    205  1.1  thorpej 
    206  1.1  thorpej 	# Emit the trailing header guard.
    207  1.1  thorpej 	printf("\n#endif /* _%s_CALLS_H_ */\n", subsystem_ub_uc)
    208  1.1  thorpej }
    209