gen-verstrs.pl revision 1245d2e0
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 push @enums, $1; 18 push @versions, $2; 19 push @all_versions, $1; 20 push @all_alpns, "h3-Q0$2"; 21 } 22 if (/^\s*(LSQVER_ID(\d+))\b/) { 23 push @draft_versions, $2; 24 push @all_versions, $1; 25 push @all_alpns, "h3-$2"; 26 } 27 } 28} 29 30close HEADER; 31 32$timestamp = localtime; 33 34print OUT <<C_CODE; 35/* 36 * Auto-generated by $0 on $timestamp 37 */ 38 39#include <assert.h> 40 41#include "lsquic.h" 42 43struct lsquic_engine; 44 45static const char *const versions_to_string[ 1 << N_LSQVER ] = { 46C_CODE 47 48$max_mask = (1 << @versions) - 1; 49 50for ($mask = 0; $mask <= $max_mask; ++$mask) { 51 my @indexes; 52 for ($i = 0; $i < @versions; ++$i) { 53 if ($mask & (1 << $i)) { 54 push @indexes, $i; 55 } 56 } 57 print OUT " [", 58 join('|', map "(1<<$_)", @enums[@indexes]) || 0, 59 "] = \"", 60 join(',', @versions[@indexes]), 61 "\",\n"; 62} 63 64$enums = join '|', map "(1<<$_)", sort @enums; 65 66print OUT <<"C_CODE"; 67}; 68 69 70const char * 71lsquic_get_alt_svc_versions (unsigned versions) 72{ 73 /* Limit to versions in versions_to_string: */ 74 versions &= ($enums); 75 return versions_to_string[ versions ]; 76} 77 78C_CODE 79 80 81$all_version_count_and_null = scalar(@all_versions) + 1; 82 83print OUT <<"C_CODE"; 84static const struct { 85 unsigned versions; 86 const char *h3_alpns[$all_version_count_and_null]; 87} vers_2_h3_alnps[] = { 88 { 0, { NULL }}, 89C_CODE 90 91for ($i = 0; $i < (1 << @all_versions); ++$i) 92{ 93 my (@vers, @alpns); 94 for ($j = 0; $j < @all_versions; ++$j) 95 { 96 if ($i & (1 << $j)) 97 { 98 push @vers, $all_versions[$j]; 99 push @alpns, $all_alpns[$j]; 100 } 101 } 102 if (@vers) { 103 print OUT " {", join("|", map "(1<<$_)", @vers), ", ", 104 "{ ", join(", ", (map qq("$_"), @alpns), "NULL"), " }},\n"; 105 } 106} 107 108$all_versions = join "|", map "(1<<$_)", @all_versions; 109 110print OUT <<"C_CODE"; 111}; 112 113const char *const * 114lsquic_get_h3_alpns (unsigned versions) 115{ 116 unsigned i; 117 118 versions &= ($all_versions); 119 120 for (i = 0; i < sizeof(vers_2_h3_alnps) / sizeof(vers_2_h3_alnps[0]); ++i) 121 if (versions == vers_2_h3_alnps[i].versions) 122 return vers_2_h3_alnps[i].h3_alpns; 123 124 assert(0); 125 return vers_2_h3_alnps[0].h3_alpns; 126} 127C_CODE 128 129 130close OUT; 131