1# Copyright (C) 1991-2022 Free Software Foundation, Inc. 2# This file is part of the GNU C Library. 3 4# The GNU C Library is free software; you can redistribute it and/or 5# modify it under the terms of the GNU Lesser General Public 6# License as published by the Free Software Foundation; either 7# version 2.1 of the License, or (at your option) any later version. 8 9# The GNU C Library is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12# Lesser General Public License for more details. 13 14# You should have received a copy of the GNU Lesser General Public 15# License along with the GNU C Library; if not, see 16# <https://www.gnu.org/licenses/>. 17 18# errno.texinfo contains lines like: 19# @errno{ENOSYS, 123, Function not implemented} 20 21BEGIN { 22 print "/* This file generated by errnos.awk from"; 23 for (i = 1; i < ARGC; i++) 24 { 25 arg = ARGV[i]; 26 sub(/.*(manual|include)\//, "", arg); 27 if (arg ~ /.*errnos.d/) continue; 28 print " " arg; 29 } 30 print " Do not edit this file; edit errnos.awk and regenerate it. */"; 31 print ""; 32 print "#ifndef _BITS_ERRNO_H"; 33 print "#define _BITS_ERRNO_H 1"; 34 print ""; 35 print "#if !defined _ERRNO_H"; 36 print "# error \"Never include <bits/errno.h> directly; use <errno.h> instead.\""; 37 print "#endif"; 38 39 maxerrno = 0; 40 maxerrlen = 0; 41 in_mach_errors = ""; 42 seq = 0; 43 } 44 45/^@errno\{/ \ 46 { 47 e = substr($1, 8, length($1)-8) 48 if (length(e) > maxerrlen) 49 maxerrlen = length(e); 50 if (e == "EWOULDBLOCK") 51 { 52 econsts[seq] = e; 53 errnos[seq] = "EAGAIN"; 54 seq++; 55 next; 56 } 57 58 errno = substr($2, 1, length($2)-1) + 0; 59 if (errno == 0) 60 next; 61 if (errno > 0x3ffff) 62 { 63 printf("%s:%d: errno value %d too large for the Hurd\n", 64 FILENAME, NR, errno) >> "/dev/stderr"; 65 exit 1; 66 } 67 if (errno > maxerrno) 68 maxerrno = errno; 69 70 etext = ""; 71 for (i = 3; i <= NF; ++i) 72 etext = etext " " $i; 73 etext = substr(etext, 2, length(etext)-2); 74 75 econsts[seq] = e; 76 errnos[seq] = sprintf("0x%08x", 0x40000000 + errno); 77 etexts[seq] = etext; 78 seq++; 79 next; 80 } 81 82NF == 3 && $1 == "#define" && $2 == "MACH_SEND_IN_PROGRESS" \ 83 { 84 in_mach_errors = FILENAME; 85 annot[seq++] = "\n/* Errors from <mach/message.h>. */"; 86 } 87NF == 3 && $1 == "#define" && $2 == "KERN_SUCCESS" \ 88 { 89 in_mach_errors = FILENAME; 90 annot[seq++] = "\n/* Errors from <mach/kern_return.h>. */"; 91 next; 92 } 93 94in_mach_errors != "" && $2 == "MACH_IPC_COMPAT" \ 95 { 96 in_mach_errors = ""; 97 } 98 99# FIXME: mach/message.h and mach/kern_return.h do include error 100# descriptions which we could slurp, but some of them are very long, 101# we would need to word-wrap them. 102in_mach_errors == FILENAME && NF == 3 && $1 == "#define" \ 103 { 104 e = "E" $2; 105 if (length(e) > maxerrlen) 106 maxerrlen = length(e); 107 econsts[seq] = e; 108 errnos[seq] = $3; 109 etexts[seq] = ""; 110 seq++; 111 } 112 113$1 == "#define" && $2 == "_MACH_MIG_ERRORS_H_" \ 114 { 115 in_mig_errors = 1; 116 annot[seq++] = "\n/* Errors from <mach/mig_errors.h>. */"; 117 next; 118 } 119in_mig_errors && $1 == "#endif" && $3 == "_MACH_MIG_ERRORS_H_" \ 120 { 121 in_mig_errors = 0; 122 } 123 124(in_mig_errors && $1 == "#define" && $3 <= -300) || \ 125(in_device_errors && $1 == "#define" && /D_/ && NF > 3) \ 126 { 127 etext = ""; 128 for (i = 5; i < NF; ++i) 129 etext = etext " " $i; 130 131 e = "E" $2; 132 if (length(e) > maxerrlen) 133 maxerrlen = length(e); 134 econsts[seq] = e; 135 errnos[seq] = $3; 136 etexts[seq] = substr(etext, 2, length(etext)-1); 137 seq++; 138 } 139 140$1 == "#define" && $2 == "D_SUCCESS" \ 141 { 142 in_device_errors = 1; 143 annot[seq++] = "\n/* Errors from <device/device_types.h>. */"; 144 next; 145 } 146in_device_errors && $1 == "#endif" \ 147 { 148 in_device_errors = 0; 149 } 150 151function print_errno_enum(maxseq) 152{ 153 print ""; 154 print "#ifndef __ASSEMBLER__"; 155 print ""; 156 print "enum __error_t_codes"; 157 print "{"; 158 print " /* The value zero always means success and it is perfectly fine"; 159 print " for code to use 0 explicitly (or implicitly, e.g. via Boolean"; 160 print " coercion.) Having an enum entry for zero both makes the"; 161 print " debugger print the name for error_t-typed zero values, and"; 162 print " prevents the compiler from issuing warnings about 'case 0:'"; 163 print " in a switch on an error_t-typed value. */"; 164 printf(" %-*s = 0,\n", maxerrlen, "ESUCCESS"); 165 166 print ""; 167 print " /* The Hurd uses Mach error system 0x10, subsystem 0. */"; 168 for (i = 0; i < maxseq; i++) 169 { 170 if (i in annot) 171 print annot[i]; 172 else if (i in etexts && etexts[i] != "") 173 printf(" %-*s = %s,\t/* %s */\n", 174 maxerrlen, econsts[i], errnos[i], etexts[i]); 175 else if (errnos[i] != "EAGAIN") 176 printf(" %-*s = %s,\n", maxerrlen, econsts[i], errnos[i]); 177 } 178 179 print ""; 180 print " /* Because the C standard requires that errno have type 'int'," 181 print " this enumeration must be a signed type. */"; 182 print " __FORCE_ERROR_T_CODES_SIGNED = -1"; 183 print "};"; 184 print ""; 185 print "#endif /* not __ASSEMBLER__ */"; 186} 187 188function print_errno_defines(maxseq) 189{ 190 print ""; 191 print "/* The C standard requires that all of the E-constants be" 192 print " defined as macros. */" 193 print ""; 194 for (i = 0; i < maxseq; i++) 195 { 196 if (i in annot) 197 print annot[i]; 198 else 199 printf("#define %-*s %s\n", maxerrlen, econsts[i], errnos[i]); 200 } 201 print ""; 202 printf("#define _HURD_ERRNOS %d\n", maxerrno+1); 203} 204 205END \ 206 { 207 print_errno_enum(seq); 208 print_errno_defines(seq); 209 210 print ""; 211 print "#endif /* bits/errno.h. */"; 212 } 213