1use phf::phf_map;
7
8pub static BUILTIN_SIGS: phf::Map<&'static str, &'static [&'static str]> = phf_map! {
11 "print" => &["FILEHANDLE", "LIST"],
13 "printf" => &["FILEHANDLE", "FORMAT", "LIST"],
14 "say" => &["FILEHANDLE", "LIST"],
15 "open" => &["FILEHANDLE", "MODE", "FILENAME"],
16 "sysopen" => &["FILEHANDLE", "FILENAME", "MODE", "PERMS"],
17 "close" => &["FILEHANDLE"],
18 "read" => &["FILEHANDLE", "SCALAR", "LENGTH", "OFFSET"],
19 "readpipe" => &["EXPR"],
20 "sysread" => &["FILEHANDLE", "SCALAR", "LENGTH", "OFFSET"],
21 "write" => &["FILEHANDLE"],
22 "syswrite" => &["FILEHANDLE", "SCALAR", "LENGTH", "OFFSET"],
23 "binmode" => &["FILEHANDLE", "LAYER"],
24 "seek" => &["FILEHANDLE", "POSITION", "WHENCE"],
25 "tell" => &["FILEHANDLE"],
26 "truncate" => &["FILEHANDLE", "LENGTH"],
27 "eof" => &["FILEHANDLE"],
28 "fileno" => &["FILEHANDLE"],
29 "flock" => &["FILEHANDLE", "OPERATION"],
30 "fcntl" => &["FILEHANDLE", "FUNCTION", "SCALAR"],
31 "ioctl" => &["FILEHANDLE", "FUNCTION", "SCALAR"],
32 "getc" => &["FILEHANDLE"],
33 "readline" => &["FILEHANDLE"],
34 "select" => &["FILEHANDLE"],
35 "sysseek" => &["FILEHANDLE", "POSITION", "WHENCE"],
36
37 "chomp" => &["VARIABLE"],
39 "chop" => &["VARIABLE"],
40 "chr" => &["NUMBER"],
41 "crypt" => &["PLAINTEXT", "SALT"],
42 "fc" => &["EXPR"],
43 "index" => &["STR", "SUBSTR", "POSITION"],
44 "lc" => &["EXPR"],
45 "lcfirst" => &["EXPR"],
46 "length" => &["EXPR"],
47 "ord" => &["EXPR"],
48 "pack" => &["TEMPLATE", "LIST"],
49 "reverse" => &["LIST"],
50 "rindex" => &["STR", "SUBSTR", "POSITION"],
51 "sprintf" => &["FORMAT", "LIST"],
52 "substr" => &["EXPR", "OFFSET", "LENGTH", "REPLACEMENT"],
53 "uc" => &["EXPR"],
54 "ucfirst" => &["EXPR"],
55 "unpack" => &["TEMPLATE", "EXPR"],
56 "quotemeta" => &["EXPR"],
57
58 "push" => &["ARRAY", "LIST"],
60 "pop" => &["ARRAY"],
61 "shift" => &["ARRAY"],
62 "unshift" => &["ARRAY", "LIST"],
63 "splice" => &["ARRAY", "OFFSET", "LENGTH", "LIST"],
64 "grep" => &["BLOCK", "LIST"],
65 "map" => &["BLOCK", "LIST"],
66 "sort" => &["BLOCK", "LIST"],
67 "join" => &["EXPR", "LIST"],
68 "split" => &["PATTERN", "EXPR", "LIMIT"],
69
70 "each" => &["HASH"],
72 "keys" => &["HASH"],
73 "values" => &["HASH"],
74 "delete" => &["EXPR"],
75 "exists" => &["EXPR"],
76
77 "abs" => &["VALUE"],
79 "atan2" => &["Y", "X"],
80 "cos" => &["EXPR"],
81 "exp" => &["EXPR"],
82 "hex" => &["EXPR"],
83 "int" => &["EXPR"],
84 "log" => &["EXPR"],
85 "oct" => &["EXPR"],
86 "rand" => &["EXPR"],
87 "sin" => &["EXPR"],
88 "sqrt" => &["EXPR"],
89 "srand" => &["EXPR"],
90
91 "chdir" => &["EXPR"],
93 "chroot" => &["FILENAME"],
94 "chmod" => &["MODE", "LIST"],
95 "chown" => &["UID", "GID", "LIST"],
96 "link" => &["OLDFILE", "NEWFILE"],
97 "lstat" => &["FILEHANDLE"],
98 "mkdir" => &["FILENAME", "MODE"],
99 "opendir" => &["DIRHANDLE", "EXPR"],
100 "readdir" => &["DIRHANDLE"],
101 "readlink" => &["EXPR"],
102 "glob" => &["EXPR"],
103 "rename" => &["OLDNAME", "NEWNAME"],
104 "rmdir" => &["FILENAME"],
105 "stat" => &["FILEHANDLE"],
106 "symlink" => &["OLDFILE", "NEWFILE"],
107 "umask" => &["EXPR"],
108 "unlink" => &["LIST"],
109 "utime" => &["ATIME", "MTIME", "LIST"],
110 "closedir" => &["DIRHANDLE"],
111 "rewinddir" => &["DIRHANDLE"],
112 "seekdir" => &["DIRHANDLE", "POS"],
113 "telldir" => &["DIRHANDLE"],
114
115 "-e" => &["FILE"],
117 "-f" => &["FILE"],
118 "-d" => &["FILE"],
119 "-r" => &["FILE"],
120 "-w" => &["FILE"],
121 "-x" => &["FILE"],
122 "-o" => &["FILE"],
123 "-R" => &["FILE"],
124 "-W" => &["FILE"],
125 "-X" => &["FILE"],
126 "-O" => &["FILE"],
127 "-z" => &["FILE"],
128 "-s" => &["FILE"],
129 "-l" => &["FILE"],
130 "-p" => &["FILE"],
131 "-S" => &["FILE"],
132 "-b" => &["FILE"],
133 "-c" => &["FILE"],
134 "-t" => &["FILE"],
135 "-u" => &["FILE"],
136 "-g" => &["FILE"],
137 "-k" => &["FILE"],
138 "-T" => &["FILE"],
139 "-B" => &["FILE"],
140 "-M" => &["FILE"],
141 "-A" => &["FILE"],
142 "-C" => &["FILE"],
143
144 "alarm" => &["SECONDS"],
146 "exec" => &["PROGRAM", "LIST"],
147 "fork" => &[],
148 "getpgrp" => &["PID"],
149 "getppid" => &[],
150 "getpriority" => &["WHICH", "WHO"],
151 "kill" => &["SIGNAL", "LIST"],
152 "pipe" => &["READHANDLE", "WRITEHANDLE"],
153 "setpgrp" => &["PID", "PGRP"],
154 "setpriority" => &["WHICH", "WHO", "PRIORITY"],
155 "syscall" => &["NUMBER", "LIST"],
156 "sleep" => &["EXPR"],
157 "system" => &["PROGRAM", "LIST"],
158 "times" => &[],
159 "wait" => &[],
160 "waitpid" => &["PID", "FLAGS"],
161
162 "gmtime" => &["EXPR"],
164 "localtime" => &["EXPR"],
165 "time" => &[],
166
167 "accept" => &["NEWSOCKET", "GENERICSOCKET"],
169 "bind" => &["SOCKET", "NAME"],
170 "connect" => &["SOCKET", "NAME"],
171 "getpeername" => &["SOCKET"],
172 "getsockname" => &["SOCKET"],
173 "getsockopt" => &["SOCKET", "LEVEL", "OPTNAME"],
174 "listen" => &["SOCKET", "QUEUESIZE"],
175 "recv" => &["SOCKET", "SCALAR", "LENGTH", "FLAGS"],
176 "send" => &["SOCKET", "MSG", "FLAGS", "TO"],
177 "setsockopt" => &["SOCKET", "LEVEL", "OPTNAME", "OPTVAL"],
178 "shutdown" => &["SOCKET", "HOW"],
179 "socket" => &["SOCKET", "DOMAIN", "TYPE", "PROTOCOL"],
180 "socketpair" => &["SOCKET1", "SOCKET2", "DOMAIN", "TYPE", "PROTOCOL"],
181 "sockatmark" => &["SOCKET"],
182
183 "gethostbyaddr" => &["ADDR", "ADDRTYPE"],
185 "gethostbyname" => &["NAME"],
186 "gethostent" => &[],
187 "getnetbyaddr" => &["ADDR", "ADDRTYPE"],
188 "getnetbyname" => &["NAME"],
189 "getnetent" => &[],
190 "getprotobyname" => &["NAME"],
191 "getprotobynumber" => &["NUMBER"],
192 "getprotoent" => &[],
193 "getservbyname" => &["NAME", "PROTO"],
194 "getservbyport" => &["PORT", "PROTO"],
195 "getservent" => &[],
196 "sethostent" => &["STAYOPEN"],
197 "setnetent" => &["STAYOPEN"],
198 "setprotoent" => &["STAYOPEN"],
199 "setservent" => &["STAYOPEN"],
200 "endhostent" => &[],
201 "endnetent" => &[],
202 "endprotoent" => &[],
203 "endservent" => &[],
204
205 "getgrent" => &[],
207 "getgrgid" => &["GID"],
208 "getgrnam" => &["NAME"],
209 "getlogin" => &[],
210 "getuid" => &[],
211 "geteuid" => &[],
212 "getgid" => &[],
213 "getegid" => &[],
214 "getgroups" => &[],
215 "setuid" => &["UID"],
216 "seteuid" => &["UID"],
217 "setgid" => &["GID"],
218 "setegid" => &["GID"],
219 "setgroups" => &["LIST"],
220 "getpwent" => &[],
221 "getpwnam" => &["NAME"],
222 "getpwuid" => &["UID"],
223 "setgrent" => &[],
224 "setpwent" => &[],
225 "endgrent" => &[],
226 "endpwent" => &[],
227
228 "msgctl" => &["ID", "CMD", "ARG"],
230 "msgget" => &["KEY", "FLAGS"],
231 "msgrcv" => &["ID", "VAR", "SIZE", "TYPE", "FLAGS"],
232 "msgsnd" => &["ID", "MSG", "FLAGS"],
233 "semctl" => &["ID", "SEMNUM", "CMD", "ARG"],
234 "semget" => &["KEY", "NSEMS", "FLAGS"],
235 "semop" => &["ID", "OPSTRING"],
236 "shmctl" => &["ID", "CMD", "ARG"],
237 "shmget" => &["KEY", "SIZE", "FLAGS"],
238 "shmread" => &["ID", "VAR", "POS", "SIZE"],
239 "shmwrite" => &["ID", "STRING", "POS", "SIZE"],
240
241 "dbmclose" => &["HASH"],
243 "dbmopen" => &["HASH", "DBNAME", "MODE"],
244 "tie" => &["VARIABLE", "CLASSNAME", "LIST"],
245 "tied" => &["VARIABLE"],
246 "untie" => &["VARIABLE"],
247
248 "bless" => &["REF", "CLASSNAME"],
250 "caller" => &["EXPR"],
251 "die" => &["LIST"],
252 "do" => &["BLOCK"],
253 "eval" => &["EXPR"],
254 "exit" => &["EXPR"],
255 "goto" => &["LABEL"],
256 "last" => &["LABEL"],
257 "next" => &["LABEL"],
258 "redo" => &["LABEL"],
259 "ref" => &["EXPR"],
260 "require" => &["VERSION"],
261 "return" => &["LIST"],
262 "scalar" => &["EXPR"],
263 "undef" => &["EXPR"],
264 "wantarray" => &[],
265 "warn" => &["LIST"],
266 "defined" => &["EXPR"],
267 "dump" => &["LABEL"],
268 "formline" => &["PICTURE", "LIST"],
269 "local" => &["EXPR"],
270 "my" => &["VARLIST"],
271 "our" => &["VARLIST"],
272 "state" => &["VARLIST"],
273 "reset" => &["EXPR"],
274 "study" => &["SCALAR"],
275 "pos" => &["SCALAR"],
276 "use" => &["MODULE", "VERSION", "LIST"],
277 "vec" => &["EXPR", "OFFSET", "BITS"],
278 "lock" => &["THING"],
279 "prototype" => &["FUNCTION"],
280};
281
282pub static BUILTIN_FULL_SIGS: phf::Map<&'static str, &'static [&'static str]> = phf_map! {
284 "print" => &["print FILEHANDLE LIST", "print FILEHANDLE", "print LIST", "print"],
285 "printf" => &["printf FILEHANDLE FORMAT, LIST", "printf FORMAT, LIST"],
286 "say" => &["say FILEHANDLE LIST", "say FILEHANDLE", "say LIST", "say"],
287 "open" => &["open FILEHANDLE, MODE, FILENAME", "open FILEHANDLE, EXPR", "open FILEHANDLE"],
288 "close" => &["close FILEHANDLE", "close"],
289 "substr" => &["substr EXPR, OFFSET, LENGTH, REPLACEMENT", "substr EXPR, OFFSET, LENGTH", "substr EXPR, OFFSET"],
290 "splice" => &["splice ARRAY, OFFSET, LENGTH, LIST", "splice ARRAY, OFFSET, LENGTH", "splice ARRAY, OFFSET", "splice ARRAY"],
291 "split" => &["split PATTERN, EXPR, LIMIT", "split PATTERN, EXPR", "split PATTERN", "split"],
292 };
294
295pub fn get_param_names(function_name: &str) -> &'static [&'static str] {
297 BUILTIN_SIGS.get(function_name).copied().unwrap_or(&[])
298}
299
300pub fn is_builtin(function_name: &str) -> bool {
302 BUILTIN_SIGS.contains_key(function_name)
303}
304
305pub fn builtin_count() -> usize {
307 BUILTIN_SIGS.len()
308}
309
310#[cfg(test)]
311mod tests {
312 use super::{builtin_count, get_param_names, is_builtin};
313
314 #[test]
315 fn exposes_common_builtins() {
316 assert!(is_builtin("print"));
317 assert!(!is_builtin("not_a_builtin"));
318 }
319
320 #[test]
321 fn returns_open_param_names() {
322 assert_eq!(get_param_names("open"), ["FILEHANDLE", "MODE", "FILENAME"]);
323 assert!(builtin_count() > 150);
324 }
325}