mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			454 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			Tcl
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			454 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			Tcl
		
	
	
		
			Executable file
		
	
	
	
	
| #!/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.
 | |
| 
 |