Sed、awk或POSIX shell来填充来自规范页面的空定义系列



我经常发现自己不得不拿一个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.      */

我的awksed是一般的,所以它最终花了我大约一个小时做这些简单的图书馆页面,然后我仍然要检查它的眼睛。

澄清这个问题:

  1. [E2BIG]变为#define E2BIG
  2. #define E2BIG变为#define E2BIG 7
    ' E2BIG '匹配,其值从已知库页面填充
  3. #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. */

最新更新