Michael Jerris 5e81b98eba Sync to current darcs tree:
Mon Sep 17 14:50:04 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/sip_util.h: updated documentation

Mon Sep 17 14:50:18 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/tport_tag.h: updated documentation

Mon Sep 17 14:50:28 EDT 2007  Pekka.Pessi@nokia.com
  * soa_tag.c: updated documentation

Wed Sep 19 12:50:01 EDT 2007  Pekka.Pessi@nokia.com
  * msg: updated documentation

Wed Sep 19 13:29:50 EDT 2007  Pekka.Pessi@nokia.com
  * url: updated documentation

Wed Sep 19 13:32:14 EDT 2007  Pekka.Pessi@nokia.com
  * nth: updated documentation

Wed Sep 19 13:32:27 EDT 2007  Pekka.Pessi@nokia.com
  * nea: updated documentation

Wed Sep 19 13:33:36 EDT 2007  Pekka.Pessi@nokia.com
  * http: updated documentation

Wed Sep 19 13:36:58 EDT 2007  Pekka.Pessi@nokia.com
  * bnf: updated documentation

Wed Sep 19 13:38:58 EDT 2007  Pekka.Pessi@nokia.com
  * nua: updated nua_stack_init_handle() prototype

Wed Sep 19 18:45:56 EDT 2007  Pekka.Pessi@nokia.com
  * sip: added sip_name_addr_xtra(), sip_name_addr_dup()

Wed Sep 19 19:00:19 EDT 2007  Pekka.Pessi@nokia.com
  * sip_basic.c: cleaned old crud

Thu Sep 20 13:34:04 EDT 2007  Pekka.Pessi@nokia.com
  * iptsec: updated documentation

Thu Sep 20 13:36:22 EDT 2007  Pekka.Pessi@nokia.com
  * tport: updated documentation

Thu Sep 20 13:36:56 EDT 2007  Pekka.Pessi@nokia.com
  * su: updated documentation
  Removed internal files from doxygen-generated documentation.

Thu Sep 20 13:38:29 EDT 2007  Pekka.Pessi@nokia.com
  * soa: fixed documentation

Thu Sep 20 13:39:56 EDT 2007  Pekka.Pessi@nokia.com
  * sdp: updated documentation

Thu Sep 20 13:40:16 EDT 2007  Pekka.Pessi@nokia.com
  * ipt: updated documentation

Thu Sep 20 14:24:20 EDT 2007  Pekka.Pessi@nokia.com
  * nta: updated documentation

Thu Sep 20 14:41:04 EDT 2007  Pekka.Pessi@nokia.com
  * nua: updated documentation

  Updated tag documentation.

  Moved doxygen doc entries from sofia-sip/nua_tag.h to nua_tag.c.

  Removed internal datatypes and files from the generated documents.

Wed Sep 19 13:34:20 EDT 2007  Pekka.Pessi@nokia.com
  * docs: updated the generation of documentation. Updated links to header files.

Thu Sep 20 08:45:32 EDT 2007  Pekka.Pessi@nokia.com
  * sip/Makefile.am: added tags to <sofia-sip/sip_extra.h>

  Added check for extra tags in torture_sip.c.

Thu Sep 20 14:45:22 EDT 2007  Pekka.Pessi@nokia.com
  * stun: updated documentation

Wed Jul  4 18:55:20 EDT 2007  Pekka.Pessi@nokia.com
  * torture_heap.c: added tests for ##sort() and su_smoothsort()

Wed Jul  4 18:56:59 EDT 2007  Pekka.Pessi@nokia.com
  * Makefile.am: added smoothsort.c

Fri Jul 13 12:38:44 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/heap.h: heap_remove() now set()s index to 0 on removed item

Mon Jul 23 11:14:22 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/heap.h: fixed bug in heap##remove()

  If left kid was in heap but right was not, left kid was ignored.

Wed Jul  4 18:51:08 EDT 2007  Pekka.Pessi@nokia.com
  * smoothsort.c: added

Wed Jul  4 18:51:34 EDT 2007  Pekka.Pessi@nokia.com
  * heap.h: using su_smoothsort()

Fri Jul  6 10:20:27 EDT 2007  Pekka.Pessi@nokia.com
  * smoothsort.c: added

Wed Sep 19 17:40:30 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: generate two parser tables, default and extended

Wed Sep 19 18:39:45 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: just generate list of extra headers

  Allocate extended parser dynamically.

Wed Sep 19 18:59:59 EDT 2007  Pekka.Pessi@nokia.com
  * sip: added Remote-Party-ID, P-Asserted-Identity, P-Preferred-Identity

  Added functions sip_update_default_mclass() and sip_extend_mclass()
  for handling the extended parser. Note that Reply-To and Alert-Info are only
  available with the extended parser.

Wed Sep 19 19:05:44 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated

Thu Sep 20 13:38:59 EDT 2007  Pekka.Pessi@nokia.com
  * sip: updated documentation

Thu Sep 20 14:17:28 EDT 2007  Pekka.Pessi@nokia.com
  * docs/conformance.docs: updated

Mon Oct  1 10:11:14 EDT 2007  Pekka.Pessi@nokia.com
  * tport_tag.c: re-enabled tptag_trusted

Thu Oct  4 09:21:07 EDT 2007  Pekka.Pessi@nokia.com
  * su_osx_runloop.c: moved virtual function table after struct definition

  Preparing for su_port_vtable_t refactoring.

Thu Oct  4 10:22:03 EDT 2007  Pekka.Pessi@nokia.com
  * su_source.c: refactored initialization/deinitialization

Fri Oct  5 04:58:18 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * sip_extra.c: fixed prototypes with isize_t

Fri Oct  5 04:58:45 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_nta_api.c: removed warnings about signedness

Fri Oct  5 04:59:02 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_nua_params.c: removed warnings about constness

Fri Oct  5 07:20:26 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su_port.h, su_root.c: cleaned argument checking

  The su_root_*() and su_port_*() functions now check their arguments once
  and do not assert() with NULL arguments. The sur_task->sut_port should
  always be valid while su_root_t is alive.

Fri Oct  5 07:22:09 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su: added su_root_obtain(), su_root_release() and su_root_has_thread()

  When root is created with su_root_create() or cloned with su_clone_start(),
  the resulting root is obtained by the calling or created thread,
  respectively.

  The root can be released with su_root_release() and another thread can
  obtain it.

  The function su_root_has_thread() can be used to check if a thread has
  obtained or released the root.

  Implementation upgraded the su_port_own_thread() method as su_port_thread().

Fri Oct  5 07:28:10 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su_port.h: removed su_port_threadsafe() and su_port_yield() methods

  su_port_wait_events() replaces su_port_yield().

Fri Oct  5 13:26:04 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * msg_parser.awk: not extending header structure unless needed.

  Removed gawk-ish /* comments */.

Fri Oct  5 14:32:25 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * run_test_su: removed GNUisms

Fri Oct  5 14:32:47 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * Makefile.am: removed implicit check target test_urlmap

Fri Oct  5 14:22:32 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * torture_sresolv.c: use CLOCK_REALTIME if no CLOCK_PROCESS_CPUTIME_ID available

  Casting timespec tv_sec to unsigned long.

Fri Oct * nua_s added handling nua_prack()

  Thanks to Fabio Margarido for the patch.

Mon Oct  8 10:24:35 EDT 2007  Pekka.Pessi@nokia.com
  * test_nua: added test for sf.net bug #1803686

Mon Oct  8 08:15:23 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated.

Mon Oct  8 09:30:36 EDT 2007  Pekka.Pessi@nokia.com
  * nua_stack: added handling nua_prack()

  Thanks to Fabio Margarido for the patch.

Mon Oct  8 10:24:35 EDT 2007  Pekka.Pessi@nokia.com
  * test_nua: added test for sf.net bug #1803686

Mon Oct  8 10:26:31 EDT 2007  Pekka.Pessi@nokia.com
  * nua: added test for nua_prack() (sf.net bug #1804248)

  Avoid sending nua_i_state after nua_prack() if no SDP O/A is happening, too.

Mon Oct  8 10:32:04 EDT 2007  Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
  * su_source.c: don t leak the wait arrays

Mon Oct  8 10:37:11 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated

Wed Oct 10 11:55:21 EDT 2007  Pekka.Pessi@nokia.com
  * sip_parser.c: silenced warning about extra const in sip_extend_mclass()

Wed Oct 10 11:57:08 EDT 2007  Pekka.Pessi@nokia.com
  * nta_tag.c: updated tag documentation

Wed Oct 10 13:16:40 EDT 2007  Pekka.Pessi@nokia.com
  * nua: fix logging crash if outbound used with application contact

  Silenced warnings.

Wed Oct 10 13:30:45 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: removed extra "const"

Wed Oct 10 13:31:45 EDT 2007  Pekka.Pessi@nokia.com
  * Makefile.am's: fixed distclean of documentation



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5840 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 14:16:59 +00:00

661 lines
16 KiB
Awk
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#! /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) {
if ((getline dummy < TEMPLATE2) < 0) {
print( TEMPLATE2 ": " ERRNO );
failed=1;
exit(1);
}
getline dummy < TEMPLATE2;
getline template2 < TEMPLATE2;
getline dummy < TEMPLATE2;
}
if (TEMPLATE3) {
if ((getline dummy < TEMPLATE3) < 0) {
print( TEMPLATE3 ": " ERRNO );
failed=1;
exit(1);
}
getline dummy < TEMPLATE3;
getline template3 < TEMPLATE3;
getline dummy < TEMPLATE3;
}
sub(/.*[\/]/, "", TEMPLATE);
gsub(/#AUTO#/, auto, header);
gsub(/#DATE#/, "@date Generated: " date, header);
if (PACKAGE_NAME) gsub(/#PACKAGE_NAME#/, PACKAGE_NAME, header);
if (PACKAGE_VERSION) gsub(/#PACKAGE_VERSION#/, PACKAGE_VERSION, header);
print header > PR;
RS=RS0;
}
if (!NO_FIRST) {
protos("request", "/**< Request line */", -1);
protos("status", "/**< Status line */", -2);
}
}
}
/^#### EXTRA HEADER LIST STARTS HERE ####$/ { HLIST=1; templates(); }
HLIST && /^#### DEFAULT HEADER LIST ENDS HERE ####$/ { basic=total; }
HLIST && /^#### EXPERIMENTAL HEADER LIST STARTS HERE ####$/ {
without_experimental = total; }
HLIST && /^[a-z]/ { protos($1, $0, 0, $2);
headers[total++] = $1;
Extra[$1] = extra++;
}
/^#### EXTRA HEADER LIST ENDS HERE ####$/ { HLIST=0; }
/^ *\/\* === Headers start here \*\// { in_header_list=1; templates(); }
/^ *\/\* === Headers end here \*\// { in_header_list=0; }
PT && /^ *\/\* === Hash headers end here \*\// { in_header_list=0;}
in_header_list && /^ (sip|rtsp|http|msg|mp)_[a-z_0-9]+_t/ {
n=$0
sub(/;.*$/, "", n);
sub(/^ *(sip|rtsp|http|msg|mp)_[a-z0-9_]*_t[ ]*/, "", n);
sub(/^[*](sip|rtsp|http|msg|mp)_/, "", n);
if ($0 !~ /[\/][*][*][<]/) {
getline;
}
if ($0 !~ /[\/][*][*][<]/) {
printf "msg_protos.awk: header %s is malformed\n", n;
failed=1;
exit 1;
}
if (!NO_MIDDLE)
protos(n, $0, 0);
headers[total] = n; total++; ordinary++;
}
function print_parser_table(struct, scope, name, N, N_EXPERIMENTAL)
{
if (PT) {
if (N > ordinary) {
printf("/* Ordinary %u, extra %u, experimental %u */\n",
ordinary, N - ordinary, N_EXPERIMENTAL - N) > PT;
printf("struct %s {\n", struct) > PT;
printf(" %s_t base;\n", module) > PT;
printf(" msg_header_t *extra[%u];\n", N - ordinary) > PT;
if (N != N_EXPERIMENTAL) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" msg_header_t *extra[%u];\n", N_EXPERIMENTAL - N) > PT;
print "#endif" > PT;
}
printf("};\n\n") > PT;
}
printf("%s\n", scope) > PT;
printf("msg_mclass_t const %s[1] = \n{{\n", name) > PT;
printf("# if defined (%s_HCLASS)\n", toupper(module)) > PT;
printf(" %s_HCLASS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" {{ 0 }},\n") > PT;
printf("#endif\n") > PT;
printf(" %s_VERSION_CURRENT,\n", toupper(module)) > PT;
printf(" %s_PROTOCOL_TAG,\n", toupper(module)) > PT;
printf("#if defined (%s_PARSER_FLAGS)\n", toupper(module)) > PT;
printf(" %s_PARSER_FLAGS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" 0,\n") > PT;
printf("#endif\n") > PT;
if (N > ordinary) {
printf(" sizeof (struct %s),\n", struct) > PT;
}
else {
printf(" sizeof (%s_t),\n", module) > PT;
}
printf(" %s_extract_body,\n", module) > PT;
len = split("request status separator payload unknown error", unnamed, " ");
for (i = 1; i <= len; i++) {
printf(" {{ %s_%s_class, msg_offsetof(%s_t, %s_%s) }},\n",
tprefix, unnamed[i], module, prefix, unnamed[i]) > PT;
}
if (multipart) {
printf(" {{ %s_class, msg_offsetof(%s_t, %s_multipart) }},\n",
multipart, module, prefix) > PT;
} else {
printf(" {{ NULL, 0 }},\n") > PT;
}
if (MC_SHORT_SIZE) {
printf(" %s_short_forms, \n", module) > PT;
}
else {
printf(" NULL, \n") > PT;
}
printf(" %d, \n", MC_HASH_SIZE) > PT;
if (N != N_EXPERIMENTAL) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" %d,\n", N_EXPERIMENTAL) > PT;
print "#else" > PT;
}
printf(" %d,\n", N) > PT;
if (N != N_EXPERIMENTAL) {
print "#endif" > PT;
}
printf(" {\n") > PT;
for (j = 0; j < MC_HASH_SIZE; j++) {
c = (j + 1 == MC_HASH_SIZE) ? "" : ",";
if (j in header_hash) {
n = header_hash[j];
i = index_hash[j];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
if (i >= N) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
}
if (i >= ordinary) {
printf(" { %s_%s_class,\n" \
" msg_offsetof(struct %s, extra[%u])%s }%s\n",
tprefix, n, struct, Extra[n], flags, c) > PT;
}
else {
printf(" { %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
tprefix, n, module, prefix, n, flags, c) > PT;
}
if (i >= N) {
printf("#else\n { NULL, 0 }%s\n#endif\n", c) > PT;
}
}
else {
printf(" { NULL, 0 }%s\n", c) > PT;
}
}
printf(" }\n}};\n\n") > PT;
}
}
END {
if (failed) { exit };
if (!NO_LAST) {
protos("unknown", "/**< Unknown headers */", -3);
protos("error", "/**< Erroneous headers */", -4);
protos("separator", "/**< Separator line between headers and body */", -5);
protos("payload", "/**< Message payload */", -6);
if (multipart)
protos("multipart", "/**< Multipart payload */", -7);
}
if (PR) {
process_footer(footer);
}
else if (PT) {
if (FLAGFILE)
read_header_flags(FLAGFILE);
if (TEMPLATE == "") { TEMPLATE = PT ".in"; }
RS0=RS; RS=" \n";
getline theader < TEMPLATE;
getline header < TEMPLATE;
getline template < TEMPLATE;
getline footer < TEMPLATE;
RS=RS0;
sub(/.*[\/]/, "", TEMPLATE);
gsub(/#AUTO#/, auto, header);
gsub(/#DATE#/, "@date Generated: " date, header);
print header > PT;
print "" > PT;
print "#define msg_offsetof(s, f) ((unsigned short)offsetof(s ,f))" > PT;
print "" > PT;
if (MC_SHORT_SIZE) {
printf("static msg_href_t const " \
"%s_short_forms[MC_SHORT_SIZE] = \n{\n",
module) > PT;
for (i = 1; i <= MC_SHORT_SIZE; i = i + 1) {
c = (i == MC_SHORT_SIZE) ? "" : ",";
if (i in shorts) {
n = shorts[i];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
printf(" { /* %s */ %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
substr(lower_case, i, 1),
tprefix, n, module, prefix, n, flags, c) \
> PT;
}
else {
printf(" { NULL }%s\n", c) \
> PT;
}
}
printf("};\n\n") > PT;
}
# printf("extern msg_hclass_t msg_multipart_class[];\n\n") > PT;
if (basic == 0) basic = total;
if (without_experimental == 0) without_experimental = total;
split("", header_hash);
split("", index_hash);
for (i = 0; i < basic; i++) {
n = headers[i];
h = hashed[n];
if (h < 0)
continue;
j = h % MC_HASH_SIZE; if (j == -0) j = 0;
for (; j in header_hash;) {
if (++j == MC_HASH_SIZE) {
j = 0;
}
}
header_hash[j] = n;
index_hash[j] = i;
}
m = module "_mclass";
s = "_d_" module "_t";
# Add basic headers
if (ordinary == basic) {
print_parser_table(s, "", m, basic, basic);
}
else if (basic < without_experimental) {
print_parser_table(s, "", m, basic, basic);
}
else {
print_parser_table(s, "", m, without_experimental, basic);
}
if (0) {
# Hash extra headers
for (i = basic; i < total; i++) {
n = headers[i];
h = hashed[n];
if (h < 0)
continue;
j = h % MC_HASH_SIZE; if (j == -0) j = 0;
for (; j in header_hash;) {
if (++j == MC_HASH_SIZE) {
j = 0;
}
}
header_hash[j] = n;
index_hash[j] = i;
}
if (basic < total) {
m = module "_ext_mclass";
s = "_e_" module "_s";
print_parser_table(s, "static", m, without_experimental, total);
}
printf("msg_mclass_t const * %s_extended_mclass = %s;\n\n", module, m) > PT;
}
if (basic < total) {
printf("msg_hclass_t * const %s_extensions[] = {\n", module) > PT;
for (i = basic; i < total; i++) {
if (i == without_experimental) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
}
printf(" %s_%s_class,\n", module, headers[i]) > PT;
}
if (total != without_experimental)
print "#endif" > PT;
print " NULL\n};\n\n" > PT;
}
}
exit success;
}