123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- #!/usr/bin/tclsh
- #*
- #* SRT - Secure, Reliable, Transport
- #* Copyright (c) 2020 Haivision Systems Inc.
- #*
- #* This Source Code Form is subject to the terms of the Mozilla Public
- #* License, v. 2.0. If a copy of the MPL was not distributed with this
- #* file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #*
- #*/
- #
- #*****************************************************************************
- #written by
- # Haivision Systems Inc.
- #*****************************************************************************
- # What fields are there in every entry
- set model {
- longname
- shortname
- id
- description
- }
- # Logger definitions.
- # Comments here allowed, just only for the whole line.
- # Use values greater than 0. Value 0 is reserved for LOGFA_GENERAL,
- # which is considered always enabled.
- set loggers {
- GENERAL gg 0 "General uncategorized log, for serious issues only"
- SOCKMGMT sm 1 "Socket create/open/close/configure activities"
- CONN cn 2 "Connection establishment and handshake"
- XTIMER xt 3 "The checkTimer and around activities"
- TSBPD ts 4 "The TsBPD thread"
- RSRC rs 5 "System resource allocation and management"
- CONGEST cc 7 "Congestion control module"
- PFILTER pf 8 "Packet filter module"
- API_CTRL ac 11 "API part for socket and library managmenet"
- QUE_CTRL qc 13 "Queue control activities"
- EPOLL_UPD ei 16 "EPoll, internal update activities"
- API_RECV ar 21 "API part for receiving"
- BUF_RECV br 22 "Buffer, receiving side"
- QUE_RECV qr 23 "Queue, receiving side"
- CHN_RECV kr 24 "CChannel, receiving side"
- GRP_RECV gr 25 "Group, receiving side"
- API_SEND as 31 "API part for sending"
- BUF_SEND bs 32 "Buffer, sending side"
- QUE_SEND qs 33 "Queue, sending side"
- CHN_SEND ks 34 "CChannel, sending side"
- GRP_SEND gs 35 "Group, sending side"
- INTERNAL in 41 "Internal activities not connected directly to a socket"
- QUE_MGMT qm 43 "Queue, management part"
- CHN_MGMT km 44 "CChannel, management part"
- GRP_MGMT gm 45 "Group, management part"
- EPOLL_API ea 46 "EPoll, API part"
- }
- set hidden_loggers {
- # Haicrypt logging - usually off.
- HAICRYPT hc 6 "Haicrypt module area"
-
- # defined in apps, this is only a stub to lock the value
- APPLOG ap 10 "Applications"
- }
- set globalheader {
- /*
- WARNING: Generated from ../scripts/generate-logging-defs.tcl
- DO NOT MODIFY.
- Copyright applies as per the generator script.
- */
- }
- # This defines, what kind of definition will be generated
- # for a given file out of the log FA entry list.
- # Fields:
- # - prefix/postfix model
- # - logger_format
- # - hidden_logger_format
- # COMMENTS NOT ALLOWED HERE! Only as C++ comments inside C++ model code.
- set special {
- srtcore/logger_default.cpp {
- if {"$longname" == "HAICRYPT"} {
- puts $od "
- #if ENABLE_HAICRYPT_LOGGING
- allfa.set(SRT_LOGFA_HAICRYPT, true);
- #endif"
- }
- }
- }
- proc GenerateModelForSrtH {} {
- # `path` will be set to the git top path
- global path
- set fd [open [file join $path srtcore/srt.h] r]
- set contents ""
- set state read
- set pass looking
- while { [gets $fd line] != -1 } {
- if { $state == "read" } {
- if { $pass != "passed" } {
- set re [regexp {SRT_LOGFA BEGIN GENERATED SECTION} $line]
- if {$re} {
- set state skip
- set pass found
- }
- }
- append contents "$line\n"
- continue
- }
- if {$state == "skip"} {
- if { [string trim $line] == "" } {
- # Empty line, continue skipping
- continue
- }
- set re [regexp {SRT_LOGFA END GENERATED SECTION} $line]
- if {!$re} {
- # Still SRT_LOGFA definitions
- continue
- }
- # End of generated section. Switch back to pass-thru.
- # First fill the gap
- append contents "\n\$entries\n\n"
- append contents "$line\n"
- set state read
- set pass passed
- }
- }
- close $fd
- # Sanity check
- if {$pass != "passed"} {
- error "Invalid contents of `srt.h` file, can't find '#define SRT_LOGFA_' phrase"
- }
- return $contents
- }
- # COMMENTS NOT ALLOWED HERE! Only as C++ comments inside C++ model code.
- # (NOTE: Tcl syntax highlighter will likely falsely highlight # as comment here)
- #
- # Model: TARGET-NAME { format-model logger-pattern hidden-logger-pattern }
- #
- # Special syntax:
- #
- # %<command> : a high-level command execution. This declares a command that
- # must be executed to GENERATE the model. Then, [subst] is executed
- # on the results.
- #
- # = : when placed as the hidden-logger-pattern, it's equal to logger-pattern.
- #
- set generation {
- srtcore/srt.h {
- {%GenerateModelForSrtH}
- {#define [format "%-20s %-3d" SRT_LOGFA_${longname} $id] // ${shortname}log: $description}
- =
- }
- srtcore/logger_default.cpp {
- {
- $globalheader
- #include "srt.h"
- #include "logging.h"
- #include "logger_defs.h"
- namespace srt_logging
- {
- AllFaOn::AllFaOn()
- {
- $entries
- }
- } // namespace srt_logging
- }
- {
- allfa.set(SRT_LOGFA_${longname}, true);
- }
- }
- srtcore/logger_defs.cpp {
- {
- $globalheader
- #include "srt.h"
- #include "logging.h"
- #include "logger_defs.h"
- namespace srt_logging { AllFaOn logger_fa_all; }
- // We need it outside the namespace to preserve the global name.
- // It's a part of "hidden API" (used by applications)
- SRT_API srt_logging::LogConfig srt_logger_config(srt_logging::logger_fa_all.allfa);
- namespace srt_logging
- {
- $entries
- } // namespace srt_logging
- }
- {
- Logger ${shortname}log(SRT_LOGFA_${longname}, srt_logger_config, "SRT.${shortname}");
- }
- }
- srtcore/logger_defs.h {
- {
- $globalheader
- #ifndef INC_SRT_LOGGER_DEFS_H
- #define INC_SRT_LOGGER_DEFS_H
- #include "srt.h"
- #include "logging.h"
- namespace srt_logging
- {
- struct AllFaOn
- {
- LogConfig::fa_bitset_t allfa;
- AllFaOn();
- };
- $entries
- } // namespace srt_logging
- #endif
- }
- {
- extern Logger ${shortname}log;
- }
- }
- apps/logsupport_appdefs.cpp {
- {
- $globalheader
- #include "logsupport.hpp"
- LogFANames::LogFANames()
- {
- $entries
- }
- }
- {
- Install("$longname", SRT_LOGFA_${longname});
- }
- {
- Install("$longname", SRT_LOGFA_${longname});
- }
- }
- }
- # EXECUTION
- set here [file dirname [file normalize $argv0]]
- if {[lindex [file split $here] end] != "scripts"} {
- puts stderr "The script is in weird location."
- exit 1
- }
- set path [file join {*}[lrange [file split $here] 0 end-1]]
- # Utility. Allows to put line-oriented comments and have empty lines
- proc no_comments {input} {
- set output ""
- foreach line [split $input \n] {
- set nn [string trim $line]
- if { $nn == "" || [string index $nn 0] == "#" } {
- continue
- }
- append output $line\n
- }
- return $output
- }
- proc generate_file {od target} {
- global globalheader
- lassign [dict get $::generation $target] format_model pattern hpattern
- set ptabprefix ""
- if {[string index $format_model 0] == "%"} {
- set command [string range $format_model 1 end]
- set format_model [eval $command]
- }
- if {$format_model != ""} {
- set beginindex 0
- while { [string index $format_model $beginindex] == "\n" } {
- incr beginindex
- }
- set endindex $beginindex
- while { [string is space [string index $format_model $endindex]] } {
- incr endindex
- }
- set tabprefix [string range $pattern $beginindex $endindex-1]
- set newformat ""
- foreach line [split $format_model \n] {
- if {[string trim $line] == ""} {
- append newformat "\n"
- continue
- }
- if {[string first $tabprefix $line] == 0} {
- set line [string range $line [string length $tabprefix] end]
- }
- append newformat $line\n
- set ie [string first {$} $line]
- if {$ie != -1} {
- if {[string range $line $ie end] == {$entries}} {
- set ptabprefix "[string range $line 0 $ie-1]"
- }
- }
- }
- set format_model $newformat
- unset newformat
- }
- set entries ""
- if {[string trim $pattern] != "" } {
- set prevval 0
- set pattern [string trim $pattern]
- # The first "$::model" will expand into variable names
- # as defined there.
- foreach [list {*}$::model] [no_comments $::loggers] {
- if {$prevval + 1 != $id} {
- append entries "\n"
- }
- append entries "${ptabprefix}[subst -nobackslashes $pattern]\n"
- set prevval $id
- }
- }
- if {$hpattern != ""} {
- if {$hpattern == "="} {
- set hpattern $pattern
- } else {
- set hpattern [string trim $hpattern]
- }
- # Extra line to separate from the normal entries
- append entries "\n"
- foreach [list {*}$::model] [no_comments $::hidden_loggers] {
- append entries "${ptabprefix}[subst -nobackslashes $hpattern]\n"
- }
- }
- if { [dict exists $::special $target] } {
- set code [subst [dict get $::special $target]]
- # The code should contain "append entries" !
- eval $code
- }
- set entries [string trim $entries]
- if {$format_model == ""} {
- set format_model $entries
- }
- # For any case, cut external spaces
- puts $od [string trim [subst -nocommands -nobackslashes $format_model]]
- }
- proc debug_vars {list} {
- set output ""
- foreach name $list {
- upvar $name _${name}
- lappend output "${name}=[set _${name}]"
- }
- return $output
- }
- # MAIN
- set entryfiles $argv
- if {$entryfiles == ""} {
- set entryfiles [dict keys $generation]
- } else {
- foreach ef $entryfiles {
- if { $ef ni [dict keys $generation] } {
- error "Unknown generation target: $entryfiles"
- }
- }
- }
- foreach f $entryfiles {
- # Set simple relative path, if the file isn't defined as path.
- if { [llength [file split $f]] == 1 } {
- set filepath $f
- } else {
- set filepath [file join $path $f]
- }
- puts stderr "Generating '$filepath'"
- set od [open $filepath.tmp w]
- generate_file $od $f
- close $od
- if { [file exists $filepath] } {
- puts "WARNING: will overwrite exiting '$f'. Hit ENTER to confirm, or Control-C to stop"
- gets stdin
- }
- file rename -force $filepath.tmp $filepath
- }
- puts stderr Done.
|