我经常发现自己不得不拿一个POSIX规范页面(errno.h是一个很好的例子)复制粘贴它们,然后填充所有的定义。我如何将另一个文件的匹配定义剥离到POSIX页面,以便填充POSIX规范页面上缺失的数字字段并将其转换为库:
(源自http://pubs.opengroup.org/onlinepubs/009695399/basedefs/errno.h.html)errno的POSIX规范页面如下所示:
[E2BIG]
Argument list too long.
[EACCES]
Permission denied.
[EADDRINUSE]
Address in use.
[EADDRNOTAVAIL]
Address not available.
[EAFNOSUPPORT]
Address family not supported.
[EAGAIN]
Resource unavailable, try again (may be the same value as [EWOULDBLOCK]).
[EALREADY]
Connection already in progress.
[EBADF]
Bad file descriptor.
[EBADMSG]
Bad message.
然后假设你可能需要从一个已知的库中填充这些值(我的,这个已经完成了),并使其看起来像这样:
#define E2BIG 7 /* Argument list too long. */
#define EACCES 13 /* Permission denied. */
#define EADDRINUSE 98 /* Address in use. */
#define EADDRNOTAVAIL 99 /* Address not available. */
#define EAFNOSUPPORT 97 /* Address family not supported. */
#define EAGAIN 11 /* Resource unavailable, try again .... */
#define EALREADY 114 /* Connection already in progress. */
我的awk
和sed
是一般的,所以它最终花了我大约一个小时做这些简单的图书馆页面,然后我仍然要检查它的眼睛。
澄清这个问题:
-
[E2BIG]
变为#define E2BIG
-
#define E2BIG
变为#define E2BIG 7
'E2BIG
'匹配,其值从已知库页面填充 -
#define E2BIG
变为#define E2BIG /* Argument list too long. */
下面一行的句子被转换成/* C注释*/,并与上面一行相连接,这是它所对应的#define。
我在这里假设spec文件严格地在spec字符串和注释之间交替,每个注释只有一行,如示例所示。
首先,我们用values文件中的spec字符串和值加载一个数组。然后从spec文件中检查数组中是否有spec字符串,如果有,则打印出信息(否则忽略它)。
($1 = $1
赋值只是为了从注释中删除额外的空格。)
最后,Mark Setchell在上面的评论中提出了一个很好的观点,所以要小心。
$ cat none.awk
# reading values:
NR == FNR && $1 == "#define" && $3 ~ /[0-9]+/ { val[$2] = $3 }
NR == FNR { next }
# reading spec:
NF == 1 && /^[.*]$/ { gsub(/[|]/,"",$0); s = $0; next }
s in val { $1 = $1; printf "#define %st%dt/* %s */n", s, val[s], $0 }
$ cat values.txt
/*
* Error codes
*/
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* Input/output error */
#define ENXIO 6 /* Device not configured */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file descriptor */
#define ECHILD 10 /* No child processes */
#define EDEADLK 11 /* Resource deadlock avoided */
/* 11 was EAGAIN */
#define ENOMEM 12 /* Cannot allocate memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
$ cat spec.txt
[E2BIG]
Argument list too long.
[EACCES]
Permission denied.
[EADDRINUSE]
Address in use.
[EADDRNOTAVAIL]
Address not available.
[EAFNOSUPPORT]
Address family not supported.
[EAGAIN]
Resource unavailable, try again (may be the same value as [EWOULDBLOCK]).
[EALREADY]
Connection already in progress.
[EBADF]
Bad file descriptor.
[EBADMSG]
Bad message.
$ awk -f none.awk values.txt spec.txt
#define E2BIG 7 /* Argument list too long. */
#define EACCES 13 /* Permission denied. */
#define EBADF 9 /* Bad file descriptor. */