gen-verstrs.pl revision fb96f4dd
1#!/usr/bin/env perl
2#
3# Generate C file that contains version strings
4
5($header        # This is lsquic.h that contains version enum which we parse
6    , $outfile  # This is destination C file
7    ) = @ARGV;
8
9open HEADER, $header
10    or die "cannot open $header for reading: $!";
11open OUT, ">$outfile"
12    or die "cannot open $outfile for writing: $!";
13
14while (<HEADER>) {
15    if (/^enum lsquic_version$/ .. /^}/) {
16        if (/^\s*(LSQVER_0*(\d+)),\s*$/ && $1 ne 'LSQVER_098') {
17            if ($2 < 50) {
18                push @enums, $1;
19                push @versions, $2;
20            }
21            push @all_versions, $1;
22            push @all_alpns, "h3-Q0$2";
23        }
24        if (/^\s*(LSQVER_ID(\d+))\b/) {
25            push @draft_versions, $2;
26            push @all_versions, $1;
27            push @all_alpns, "h3-$2";
28        }
29    }
30}
31
32close HEADER;
33
34$timestamp = localtime;
35
36print OUT <<C_CODE;
37/*
38 * Auto-generated by $0 on $timestamp
39 */
40
41#include <assert.h>
42#include <string.h>
43
44#include "lsquic.h"
45
46struct lsquic_engine;
47
48static const char *const versions_to_string[ 1 << N_LSQVER ] = {
49C_CODE
50
51$max_mask = (1 << @versions) - 1;
52
53for ($mask = 0; $mask <= $max_mask; ++$mask) {
54    my @indexes;
55    for ($i = 0; $i < @versions; ++$i) {
56        if ($mask & (1 << $i)) {
57            push @indexes, $i;
58        }
59    }
60    print OUT "    [",
61        join('|', map "(1<<$_)", @enums[@indexes]) || 0,
62        "] = \"",
63        join(',', @versions[@indexes]),
64        "\",\n";
65}
66
67$enums = join '|', map "(1<<$_)", sort @enums;
68
69print OUT <<"C_CODE";
70};
71
72
73const char *
74lsquic_get_alt_svc_versions (unsigned versions)
75{
76    /* Limit to versions in versions_to_string: */
77    versions &= ($enums);
78    return versions_to_string[ versions ];
79}
80
81C_CODE
82
83
84$all_version_count_and_null = scalar(@all_versions) + 1;
85
86print OUT <<"C_CODE";
87static const struct {
88    unsigned    versions;
89    const char *h3_alpns[$all_version_count_and_null];
90} vers_2_h3_alnps[] = {
91    { 0, { NULL }},
92C_CODE
93
94for ($i = 0; $i < (1 << @all_versions); ++$i)
95{
96    my (@vers, @alpns);
97    for ($j = 0; $j < @all_versions; ++$j)
98    {
99        if ($i & (1 << $j))
100        {
101            push @vers, $all_versions[$j];
102            push @alpns, $all_alpns[$j];
103        }
104    }
105    if (@vers) {
106        print OUT "    {", join("|", map "(1<<$_)", @vers), ", ",
107            "{ ", join(", ", (map qq("$_"), @alpns), "NULL"), " }},\n";
108    }
109}
110
111$all_versions = join "|", map "(1<<$_)", @all_versions;
112
113print OUT <<"C_CODE";
114};
115
116const char *const *
117lsquic_get_h3_alpns (unsigned versions)
118{
119    unsigned i;
120
121    versions &= ($all_versions);
122
123    for (i = 0; i < sizeof(vers_2_h3_alnps) / sizeof(vers_2_h3_alnps[0]); ++i)
124        if (versions == vers_2_h3_alnps[i].versions)
125            return vers_2_h3_alnps[i].h3_alpns;
126
127    assert(0);
128    return vers_2_h3_alnps[0].h3_alpns;
129}
130C_CODE
131
132
133print OUT <<'C_CODE';
134
135enum lsquic_version
136lsquic_alpn2ver (const char *alpn, size_t len)
137{
138    static const struct el {
139        size_t len;
140        char alpn[10];
141        enum lsquic_version version;
142    } map[] = {
143C_CODE
144
145for ($i = 0; $i < @versions; ++$i) {
146    print OUT "        {sizeof(\"h3-Q0$versions[$i]\")-1,\"h3-Q0$versions[$i]\", $enums[$i]},\n";
147}
148
149for ($i = 0; $i < @draft_versions; ++$i) {
150    print OUT "        {sizeof(\"h3-$draft_versions[$i]\")-1,\"h3-$draft_versions[$i]\", LSQVER_ID$draft_versions[$i]},\n";
151}
152
153print OUT <<'C_CODE';
154    };
155    const struct el *el;
156
157    if (alpn)
158        for (el = map; el < map + sizeof(map) / sizeof(map[0]); ++el)
159            if (el->len == len && 0 == strncmp(el->alpn, alpn, len))
160                return el->version;
161
162    return -1;
163}
164C_CODE
165
166close OUT;
167