📄 msg_parser.awk
字号:
#! /usr/bin/env awk## This script recreates C files containing header-specific boilerplate stuff# using the given list of headers (usually obtained from the master structure).## It can also create a parser table.## --------------------------------------------------------------------## This file is part of the Sofia-SIP package## Copyright (C) 2005 Nokia Corporation.## Contact: Pekka Pessi <pekka.pessi@nokia.com>## This library is free software; you can redistribute it and/or# modify it under the terms of the GNU Lesser General Public License# as published by the Free Software Foundation; either version 2.1 of# the License, or (at your option) any later version.## This library is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public# License along with this library; if not, write to the Free Software# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA# 02110-1301 USA## --------------------------------------------------------------------## Contributor(s): Pekka.Pessi@nokia.com.## Created: Fri Apr 6 12:59:59 2001 ppessi#BEGIN { "date '+%a %b %e %H:%M:%S %Y'" | getline date; ascii = \ " " \ " !\"#$%&'()*+,-./0123456789:;<=>?" \ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" \ "`abcdefghijklmnopqrstuvwxyz{|}~"; lower_case = "abcdefghijklmnopqrstuvwxyz"; N=0; # Initialize these as arrays split("", symbols); split("", names); split("", comments); split("", hashes); split("", NAMES); split("", Comments); split("", COMMENTS); # indexed by the C name of the header split("", Since); # Non-NUL if extra split("", Extra); # Offset in extra headers total = 0; ordinary = 0; basic = 0; extra = 0; without_experimental = 0; template=""; template1=""; template2=""; template3=""; prefix=""; tprefix=""; failed=0; success=0; ERRNO="error";}function name_hash (name){ hash = 0; len = length(name); for (i = 1; i <= len; i++) { c = tolower(substr(name, i, 1)); hash = (38501 * (hash + index(ascii, c))) % 65536; } if (hash == 0) { print "*** msg_parser.awk: calculating hash failed\n"; exit(5); } if (0) { # Test that hash algorithm above agrees with the C version pipe = ("../msg/msg_name_hash " name); pipe | getline; close(pipe); if (hash != $0) { print name ": " hash " != " $0 > "/dev/stderr"; } } return hash "";}## Replace magic patterns in template p with header-specific values#function protos (name, comment, hash, since){ NAME=toupper(name); sub(/.*[\/][*][*][<][ ]*/, "", comment); sub(/[ ]*[*][\/].*/, "", comment); sub(/[ ]+/, " ", comment); short = match(comment, /[(][a-z][)]/); if (short) { short = substr(comment, short + 1, 1); sub(/ *[(][a-z][)]/, "", comment); shorts[index(lower_case, short)] = name; } do_hash = hash == 0; if (do_hash) { split(comment, parts, " "); name2 = tolower(parts[1]); gsub(/-/, "_", name2); if (name2 != name && name2 != tprefix "_" name) { print name " mismatch with " comment " (" real ")" > "/dev/stderr"; } hash = name_hash(parts[1]); hashed[name] = hash; if (comment !~ /header/) { comment = comment " header"; } } Comment = comment; if (!do_hash) { comment = tolower(comment); } COMMENT = toupper(comment); # Store the various forms into an array for the footer processing N++; hashes[N] = hash; names[N] = name; NAMES[N] = NAME; comments[N] = comment; Comments[N] = comment; COMMENTS[N] = COMMENT; symbols[name] = comment; if (since) { Since[name] = since; } expr = (without_experimental > 0 && do_hash); if (expr) { printf "%s is experimental\n", Comment; } experimental[N] = expr; if (PR) { if (expr) { print "#if SU_HAVE_EXPERIMENTAL" > PR; } replace(template, hash, name, NAME, comment, Comment, COMMENT, since); replace(template1, hash, name, NAME, comment, Comment, COMMENT, since); replace(template2, hash, name, NAME, comment, Comment, COMMENT, since); replace(template3, hash, name, NAME, comment, Comment, COMMENT, since); if (expr) { print "#endif /* SU_HAVE_EXPERIMENTAL */" > PR; } }}function replace (p, hash, name, NAME, comment, Comment, COMMENT, since){ # # Replace various forms of header name in template, print it out # if (p) { gsub(/#hash#/, hash, p); gsub(/#xxxxxx#/, name, p); gsub(/#XXXXXX#/, NAME, p); gsub(/#xxxxxxx_xxxxxxx#/, comment, p); gsub(/#Xxxxxxx_Xxxxxxx#/, Comment, p); gsub(/#XXXXXXX_XXXXXXX#/, COMMENT, p); if (since) { gsub(/#version#/, since, p); } else { # Remove line with #version# gsub(/\n[^#\n]*#version#[^\n]*/, "", p); } print p > PR; }}# # Repeat each line in the footer containing the magic replacement# pattern with an instance of all headers#function process_footer (text){ if (!match(tolower(text), /#(xxxxxx(x_xxxxxxx)?|hash)#/)) { n = length(text); while (substr(text, n) == "\n") { n = n - 1; text = substr(text, 1, n); } if (n > 0) print text > PR; return; } n = split(text, lines, RS); for (i = 1; i <= n; i++) { l = lines[i]; if (match(tolower(l), /#(xxxxxx(x_xxxxxxx)?|hash)#/)) { expr = 0; for (j = 1; j <= N; j++) { l = lines[i]; if (expr != experimental[j]) { expr = experimental[j]; if (expr) { print "#if SU_HAVE_EXPERIMENTAL" > PR; } else { print "#endif /* SU_HAVE_EXPERIMENTAL */" > PR; } } gsub(/#hash#/, hashes[j], l); gsub(/#xxxxxxx_xxxxxxx#/, comments[j], l); gsub(/#Xxxxxxx_Xxxxxxx#/, Comments[j], l); gsub(/#XXXXXXX_XXXXXXX#/, COMMENTS[j], l); gsub(/#xxxxxx#/, names[j], l); gsub(/#XXXXXX#/, NAMES[j], l); print l > PR; } if (expr) { print "#endif /* SU_HAVE_EXPERIMENTAL */" > PR; } } else { print l > PR; } }}## Read flags used with headers#function read_header_flags (flagfile, line, tokens, name, value){ while ((getline line < flagfile) > 0) { sub(/^[ \t]+/, "", line); sub(/[ \t]+$/, "", line); if (line ~ /^#/ || line ~ /^$/) continue; split(line, tokens, /[ \t]*=[ \t]*/); name = tolower(tokens[1]); gsub(/-/, "_", name); gsub(/,/, " ", name); # print "FLAG: " name " = " tokens[2] if (header_flags[name]) { print flagfile ": already defined " tokens[1]; } else if (!symbols[name]) { print flagfile ": unknown header \"" tokens[1] "\""; } else { header_flags[name] = tokens[2]; } } close(flagfile);}## Read in templates#function templates (){ if (!auto) { auto = FILENAME; if (!prefix) { prefix = module; } if (!tprefix) { tprefix = prefix; } sub(/.*\//, "", auto); auto = "This file is automatically generated from <" auto "> by msg_parser.awk."; if (PR) { if (TEMPLATE == "") { TEMPLATE = PR ".in"; } RS0=RS; RS="\f\n"; if ((getline theader < TEMPLATE) < 0) { print ( TEMPLATE ": " ERRNO ); failed=1; exit(1); } getline header < TEMPLATE; getline template < TEMPLATE; getline footer < TEMPLATE; if (TEMPLATE1) { if ((getline dummy < TEMPLATE1) < 0) { print(TEMPLATE1 ": " ERRNO); failed=1; exit(1); } getline dummy < TEMPLATE1; getline template1 < TEMPLATE1; getline dummy < TEMPLATE1; } if (TEMPLATE2) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -