33# See the LICENSE file in the project root for more information.
44
55from generate import generate
6+ from collections import OrderedDict
67
7- num_systems = 3
8- linux_idx , darwin_idx , windows_idx = range (num_systems )
8+ systems = [ 'linux' , 'macos' , 'windows' ]
9+ linux_idx , darwin_idx , windows_idx = range (len ( systems ) )
910
1011# python3 -c 'import errno;print(dict(sorted(errno.errorcode.items())))'
1112errorcode_linux = {1 : 'EPERM' , 2 : 'ENOENT' , 3 : 'ESRCH' , 4 : 'EINTR' , 5 : 'EIO' , 6 : 'ENXIO' , 7 : 'E2BIG' , 8 : 'ENOEXEC' , 9 : 'EBADF' , 10 : 'ECHILD' , 11 : 'EAGAIN' , 12 : 'ENOMEM' , 13 : 'EACCES' , 14 : 'EFAULT' , 15 : 'ENOTBLK' , 16 : 'EBUSY' , 17 : 'EEXIST' , 18 : 'EXDEV' , 19 : 'ENODEV' , 20 : 'ENOTDIR' , 21 : 'EISDIR' , 22 : 'EINVAL' , 23 : 'ENFILE' , 24 : 'EMFILE' , 25 : 'ENOTTY' , 26 : 'ETXTBSY' , 27 : 'EFBIG' , 28 : 'ENOSPC' , 29 : 'ESPIPE' , 30 : 'EROFS' , 31 : 'EMLINK' , 32 : 'EPIPE' , 33 : 'EDOM' , 34 : 'ERANGE' , 35 : 'EDEADLOCK' , 36 : 'ENAMETOOLONG' , 37 : 'ENOLCK' , 38 : 'ENOSYS' , 39 : 'ENOTEMPTY' , 40 : 'ELOOP' , 42 : 'ENOMSG' , 43 : 'EIDRM' , 44 : 'ECHRNG' , 45 : 'EL2NSYNC' , 46 : 'EL3HLT' , 47 : 'EL3RST' , 48 : 'ELNRNG' , 49 : 'EUNATCH' , 50 : 'ENOCSI' , 51 : 'EL2HLT' , 52 : 'EBADE' , 53 : 'EBADR' , 54 : 'EXFULL' , 55 : 'ENOANO' , 56 : 'EBADRQC' , 57 : 'EBADSLT' , 59 : 'EBFONT' , 60 : 'ENOSTR' , 61 : 'ENODATA' , 62 : 'ETIME' , 63 : 'ENOSR' , 64 : 'ENONET' , 65 : 'ENOPKG' , 66 : 'EREMOTE' , 67 : 'ENOLINK' , 68 : 'EADV' , 69 : 'ESRMNT' , 70 : 'ECOMM' , 71 : 'EPROTO' , 72 : 'EMULTIHOP' , 73 : 'EDOTDOT' , 74 : 'EBADMSG' , 75 : 'EOVERFLOW' , 76 : 'ENOTUNIQ' , 77 : 'EBADFD' , 78 : 'EREMCHG' , 79 : 'ELIBACC' , 80 : 'ELIBBAD' , 81 : 'ELIBSCN' , 82 : 'ELIBMAX' , 83 : 'ELIBEXEC' , 84 : 'EILSEQ' , 85 : 'ERESTART' , 86 : 'ESTRPIPE' , 87 : 'EUSERS' , 88 : 'ENOTSOCK' , 89 : 'EDESTADDRREQ' , 90 : 'EMSGSIZE' , 91 : 'EPROTOTYPE' , 92 : 'ENOPROTOOPT' , 93 : 'EPROTONOSUPPORT' , 94 : 'ESOCKTNOSUPPORT' , 95 : 'ENOTSUP' , 96 : 'EPFNOSUPPORT' , 97 : 'EAFNOSUPPORT' , 98 : 'EADDRINUSE' , 99 : 'EADDRNOTAVAIL' , 100 : 'ENETDOWN' , 101 : 'ENETUNREACH' , 102 : 'ENETRESET' , 103 : 'ECONNABORTED' , 104 : 'ECONNRESET' , 105 : 'ENOBUFS' , 106 : 'EISCONN' , 107 : 'ENOTCONN' , 108 : 'ESHUTDOWN' , 109 : 'ETOOMANYREFS' , 110 : 'ETIMEDOUT' , 111 : 'ECONNREFUSED' , 112 : 'EHOSTDOWN' , 113 : 'EHOSTUNREACH' , 114 : 'EALREADY' , 115 : 'EINPROGRESS' , 116 : 'ESTALE' , 117 : 'EUCLEAN' , 118 : 'ENOTNAM' , 119 : 'ENAVAIL' , 120 : 'EISNAM' , 121 : 'EREMOTEIO' , 122 : 'EDQUOT' , 123 : 'ENOMEDIUM' , 124 : 'EMEDIUMTYPE' , 125 : 'ECANCELED' , 126 : 'ENOKEY' , 127 : 'EKEYEXPIRED' , 128 : 'EKEYREVOKED' , 129 : 'EKEYREJECTED' , 130 : 'EOWNERDEAD' , 131 : 'ENOTRECOVERABLE' , 132 : 'ERFKILL' }
1516darwin_aliases = {'EWOULDBLOCK' : 'EAGAIN' }
1617aliases = {** linux_aliases , ** darwin_aliases }
1718
18- def set_value (errorval , name , value , index ):
19- if name not in errorval :
20- errorval [name ] = [None ] * num_systems
21- errorval [name ][index ] = value
19+ def set_value (codeval , name , value , index ):
20+ if name not in codeval :
21+ codeval [name ] = [None ] * len ( systems )
22+ codeval [name ][index ] = value
2223
2324def collect_errornames ():
2425 errorval = {}
@@ -38,7 +39,7 @@ def collect_errornames():
3839
3940 # set aliases
4041 for alias , target in aliases .items ():
41- for idx in range (num_systems ):
42+ for idx in range (len ( systems ) ):
4243 if errorval [target ][idx ] and not errorval [alias ][idx ]:
4344 errorval [alias ][idx ] = errorval [target ][idx ]
4445
@@ -57,7 +58,7 @@ def priority(error):
5758 for code in codes :
5859 res *= 100000
5960 res += code if code else 0
60- return res + shifts * 100000 ** (num_systems - 1 ) // 10
61+ return res + shifts * 100000 ** (len ( systems ) - 1 ) // 10
6162
6263 names = sorted (errorvalues , key = priority )
6364 for name in names :
@@ -77,29 +78,29 @@ def priority(error):
7778 if hidden_on :
7879 cw .write (f"[PythonHidden({ ', ' .join (hidden_on )} )]" )
7980
80- value = windows_code_expr (codes )
81+ value = windows_code_expr (codes , str )
8182 cw .write (f"public static int { name } => { value } ;" )
8283
83- def windows_code_expr (codes ):
84- if codes [windows_idx ]:
85- if not any ( codes [:windows_idx ]) or all (map ( lambda x : x == codes [windows_idx ], codes [:windows_idx ]) ):
86- return str (codes [windows_idx ])
84+ def windows_code_expr (codes , fmt ):
85+ if codes [windows_idx ] is not None :
86+ if all ( c is None for c in codes [:windows_idx ]) or all (x == codes [windows_idx ] for x in codes [:windows_idx ]):
87+ return fmt (codes [windows_idx ])
8788 else :
88- return f"RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? { codes [windows_idx ]} : { darwin_code_expr (codes )} "
89+ return f"RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? { fmt ( codes [windows_idx ]) } : { darwin_code_expr (codes , fmt )} "
8990 else :
90- return darwin_code_expr (codes )
91+ return darwin_code_expr (codes , fmt )
9192
92- def darwin_code_expr (codes ):
93- if codes [darwin_idx ]:
94- if not any ( codes [:darwin_idx ]) or all (map ( lambda x : x == codes [darwin_idx ], codes [:darwin_idx ]) ):
95- return str (codes [darwin_idx ])
93+ def darwin_code_expr (codes , fmt ):
94+ if codes [darwin_idx ] is not None :
95+ if all ( c is None for c in codes [:darwin_idx ]) or all (x == codes [darwin_idx ] for x in codes [:darwin_idx ]):
96+ return fmt (codes [darwin_idx ])
9697 else :
97- return f"RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? { codes [darwin_idx ]} : { linux_code_expr (codes )} "
98+ return f"RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? { fmt ( codes [darwin_idx ]) } : { linux_code_expr (codes , fmt )} "
9899 else :
99- return linux_code_expr (codes )
100+ return linux_code_expr (codes , fmt )
100101
101- def linux_code_expr (codes ):
102- return str (codes [linux_idx ])
102+ def linux_code_expr (codes , fmt ):
103+ return fmt (codes [linux_idx ])
103104
104105def generate_errno_names (cw ):
105106 def is_windows_alias (name ):
@@ -142,10 +143,74 @@ def is_windows_alias(name):
142143 cw .write (f'errorcode[{ name } ] = "{ name } ";' )
143144 cw .exit_block ()
144145
146+
147+ # python3 -c 'import os;print(dict(sorted((s, getattr(os, s)) for s in dir(os) if s.startswith("O_"))))'
148+ O_flags_linux = {'O_ACCMODE' : 3 , 'O_APPEND' : 1024 , 'O_ASYNC' : 8192 , 'O_CLOEXEC' : 524288 , 'O_CREAT' : 64 , 'O_DIRECT' : 16384 , 'O_DIRECTORY' : 65536 , 'O_DSYNC' : 4096 , 'O_EXCL' : 128 , 'O_FSYNC' : 1052672 , 'O_LARGEFILE' : 0 , 'O_NDELAY' : 2048 , 'O_NOATIME' : 262144 , 'O_NOCTTY' : 256 , 'O_NOFOLLOW' : 131072 , 'O_NONBLOCK' : 2048 , 'O_PATH' : 2097152 , 'O_RDONLY' : 0 , 'O_RDWR' : 2 , 'O_RSYNC' : 1052672 , 'O_SYNC' : 1052672 , 'O_TMPFILE' : 4259840 , 'O_TRUNC' : 512 , 'O_WRONLY' : 1 }
149+ O_flags_darwin = {'O_ACCMODE' : 3 , 'O_APPEND' : 8 , 'O_ASYNC' : 64 , 'O_CLOEXEC' : 16777216 , 'O_CREAT' : 512 , 'O_DIRECTORY' : 1048576 , 'O_DSYNC' : 4194304 , 'O_EXCL' : 2048 , 'O_EXEC' : 1073741824 , 'O_EXLOCK' : 32 , 'O_NDELAY' : 4 , 'O_NOCTTY' : 131072 , 'O_NOFOLLOW' : 256 , 'O_NONBLOCK' : 4 , 'O_RDONLY' : 0 , 'O_RDWR' : 2 , 'O_SEARCH' : 1074790400 , 'O_SHLOCK' : 16 , 'O_SYNC' : 128 , 'O_TRUNC' : 1024 , 'O_WRONLY' : 1 }
150+ O_flags_windows = {'O_APPEND' : 8 , 'O_BINARY' : 32768 , 'O_CREAT' : 256 , 'O_EXCL' : 1024 , 'O_NOINHERIT' : 128 , 'O_RANDOM' : 16 , 'O_RDONLY' : 0 , 'O_RDWR' : 2 , 'O_SEQUENTIAL' : 32 , 'O_SHORT_LIVED' : 4096 , 'O_TEMPORARY' : 64 , 'O_TEXT' : 16384 , 'O_TRUNC' : 512 , 'O_WRONLY' : 1 }
151+
152+ O_flags_optional = {'O_ASYNC' , 'O_DIRECT' , 'O_DIRECTORY' , 'O_NOFOLLOW' , 'O_NOATIME' , 'O_PATH' , 'O_TMPFILE' , 'O_SHLOCK' , 'O_EXLOCK' }
153+ O_flags_python3_10 = {'O_EVTONLY' , 'O_FSYNC' , 'O_SYMLINK' , 'O_NOFOLLOW_ANY' }
154+
155+ def collect_codes ():
156+ codeval = {}
157+ for name in O_flags_linux :
158+ set_value (codeval , name , O_flags_linux [name ], linux_idx )
159+ for name in O_flags_darwin :
160+ set_value (codeval , name , O_flags_darwin [name ], darwin_idx )
161+ for name in O_flags_windows :
162+ set_value (codeval , name , O_flags_windows [name ], windows_idx )
163+ for name in O_flags_optional | O_flags_python3_10 :
164+ codeval .pop (name , None )
165+ return OrderedDict (sorted (codeval .items ()))
166+
167+ O_flagvalues = collect_codes ()
168+
169+ def generate_O_flags (cw , flagvalues , access ):
170+ for name in flagvalues .keys ():
171+ codes = flagvalues [name ]
172+ hidden_on = []
173+ supported_on = set (systems )
174+ cw .writeline ()
175+ if codes [windows_idx ] is None :
176+ hidden_on = ["PlatformsAttribute.PlatformFamily.Windows" ]
177+ supported_on .discard (systems [windows_idx ])
178+ if codes [linux_idx ] is None and codes [darwin_idx ] is None :
179+ assert not hidden_on , "Cannot hide on both Unix and Windows"
180+ hidden_on = ["PlatformsAttribute.PlatformFamily.Unix" ]
181+ supported_on .discard (systems [linux_idx ])
182+ supported_on .discard (systems [darwin_idx ])
183+ else :
184+ if codes [linux_idx ] is None :
185+ hidden_on += ["PlatformID.Unix" ]
186+ supported_on .discard (systems [linux_idx ])
187+ if codes [darwin_idx ] is None :
188+ hidden_on += ["PlatformID.MacOSX" ]
189+ supported_on .discard (systems [darwin_idx ])
190+ if hidden_on :
191+ cw .write (f"[PythonHidden({ ', ' .join (hidden_on )} )]" )
192+ if len (supported_on ) != len (systems ):
193+ for s in sorted (supported_on ):
194+ cw .write (f'[SupportedOSPlatform("{ s } ")]' )
195+
196+ value = windows_code_expr (codes , fmt = hex )
197+ cw .write (f"{ access } static int { name } => { value } ;" )
198+
199+ def generate_all_O_flags (cw ):
200+ generate_O_flags (cw , O_flagvalues , 'public' )
201+
202+ common_O_flags = ['O_RDONLY' , 'O_WRONLY' , 'O_RDWR' , 'O_APPEND' , 'O_CREAT' , 'O_TRUNC' , 'O_EXCL' ]
203+
204+ def generate_common_O_flags (cw ):
205+ generate_O_flags (cw , OrderedDict ((f , O_flagvalues [f ]) for f in common_O_flags ), 'private' )
206+
207+
145208def main ():
146209 return generate (
147210 ("Errno Codes" , generate_errno_codes ),
148211 ("Errno Names" , generate_errno_names ),
212+ ("O_Flags" , generate_all_O_flags ),
213+ ("Common O_Flags" , generate_common_O_flags ),
149214 )
150215
151216if __name__ == "__main__" :
0 commit comments