From: Andre Noll Date: Sat, 5 Aug 2017 12:05:52 +0000 (+0200) Subject: Merge branch 'refs/heads/t/wma' X-Git-Tag: v0.6.1~44 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=80541d0f045e1ed57332800eff9832e0a5b72ddf;hp=f10ff3996cb652a46138310e58066752edb391ca Merge branch 'refs/heads/t/wma' A couple of patches which simplify the wma decoder and improve the robustness of the bitstream API. Cooking for a month. * refs/heads/t/wma: wma: Remove _XOPEN_SOURCE define from wmadec_filter.c. wma: make ->ms_stereo local to wma_decode_block(). wma: Simplify init_coef_vlc(). wma: Rename input/output buffer variables. wma: Drop unused argument from wma_decode_superframe(). wma: Remove pointless/incorrect sanity checks. wma: Combine wmadec_cleanup() and wmadec_close(). wma: Simplify get_vlc(). wma: Remove pointless VLC_TYPE define. wma: Make bitstream API more robust. --- diff --git a/Doxyfile b/Doxyfile index 70c71261..d8960dde 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.6 +# Doxyfile 1.8.11 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -46,10 +46,10 @@ PROJECT_NUMBER = PROJECT_BRIEF = -# With the PROJECT_LOGO tag one can specify an logo or icon that is included in -# the documentation. The maximum height of the logo should not exceed 55 pixels -# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo -# to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = @@ -60,7 +60,7 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = web_sync/doxygen -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where @@ -70,6 +70,14 @@ OUTPUT_DIRECTORY = web_sync/doxygen CREATE_SUBDIRS = NO +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. @@ -85,14 +93,14 @@ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the @@ -127,7 +135,7 @@ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. @@ -197,9 +205,9 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a -# new page for each member. If set to NO, the documentation of a member will be -# part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO @@ -261,11 +269,14 @@ OPTIMIZE_OUTPUT_VHDL = NO # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. # -# Note For files without extension you can use no_extension as a placeholder. +# Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. @@ -284,8 +295,8 @@ MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES @@ -325,13 +336,20 @@ SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent @@ -390,7 +408,7 @@ LOOKUP_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. @@ -400,35 +418,35 @@ LOOKUP_CACHE_SIZE = 0 EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = NO -# This flag is only useful for Objective-C code. When set to YES local methods, +# This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO only methods in the interface are +# included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. @@ -453,21 +471,21 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set -# to NO these classes will be included in the various overviews. This option has -# no effect if EXTRACT_ALL is enabled. +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO these declarations will be +# (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO these +# documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. @@ -481,7 +499,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES upper-case letters are also +# names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. @@ -490,12 +508,19 @@ INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES the +# their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = YES +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -523,14 +548,14 @@ INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. +# name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = NO # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. Note that +# name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. @@ -575,27 +600,25 @@ SORT_BY_SCOPE_NAME = NO STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the -# todo list. This list is created by putting \todo commands in the -# documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the -# test list. This list is created by putting \test commands in the -# documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. @@ -620,8 +643,8 @@ ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES the list -# will mention the files that were used to generate the documentation. +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES @@ -669,8 +692,7 @@ LAYOUT_FILE = # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. Do not use file names with spaces, bibtex cannot handle them. See -# also \cite for info how to create references. +# search path. See also \cite for info how to create references. CITE_BIB_FILES = @@ -686,7 +708,7 @@ CITE_BIB_FILES = QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. @@ -694,7 +716,7 @@ QUIET = YES WARNINGS = YES -# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. @@ -711,12 +733,18 @@ WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO doxygen will only warn about wrong or incomplete parameter -# documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = YES +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated @@ -740,7 +768,7 @@ WARN_LOGFILE = # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with -# spaces. +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = . @@ -756,12 +784,17 @@ INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank the -# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, -# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, -# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, -# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, -# *.qsf, *.as and *.js. +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, +# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. FILE_PATTERNS = *.c \ *.h @@ -848,6 +881,10 @@ IMAGE_PATH = # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. INPUT_FILTER = @@ -857,11 +894,15 @@ INPUT_FILTER = # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER ) will also be used to filter the input files that are used for +# INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. @@ -921,7 +962,7 @@ REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. @@ -998,7 +1039,7 @@ IGNORE_PREFIX = # Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES @@ -1060,13 +1101,15 @@ HTML_FOOTER = web/footer.html HTML_STYLESHEET = -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- -# defined cascading style sheet that is included after the standard style sheets +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. -# Doxygen will copy the style sheet file to the output directory. For an example -# see the documentation. +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1082,7 +1125,7 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the stylesheet and background images according to +# will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 @@ -1113,8 +1156,9 @@ HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: YES. +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES @@ -1210,28 +1254,29 @@ GENERATE_HTMLHELP = NO CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# The GENERATE_CHI flag controls if a separate .chi index file is generated ( -# YES) or that it should be included in the master .chm file ( NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1344,7 +1389,7 @@ DISABLE_INDEX = NO # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has @@ -1372,7 +1417,7 @@ ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1401,7 +1446,7 @@ FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. @@ -1471,11 +1516,11 @@ SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There -# are two flavours of web server based searching depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. See -# the section "External Indexing and Searching" for details. +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. @@ -1487,7 +1532,7 @@ SERVER_BASED_SEARCH = NO # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # @@ -1500,7 +1545,7 @@ EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. @@ -1538,7 +1583,7 @@ EXTRA_SEARCH_MAPPINGS = # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO @@ -1569,7 +1614,7 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1587,9 +1632,12 @@ COMPACT_LATEX = NO PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. To get the times font for -# instance you can specify -# EXTRA_PACKAGES=times +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1603,23 +1651,36 @@ EXTRA_PACKAGES = # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will -# replace them by respectively the title of the page, the current date and time, -# only the current date, the version number of doxygen, the project name (see -# PROJECT_NAME), or the project number (see PROJECT_NUMBER). +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or @@ -1637,8 +1698,8 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = NO -# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1679,11 +1740,19 @@ LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. @@ -1698,7 +1767,7 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1735,11 +1804,21 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for # classes and files. # The default value is: NO. @@ -1763,6 +1842,13 @@ MAN_OUTPUT = man MAN_EXTENSION = .3 +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without @@ -1776,7 +1862,7 @@ MAN_LINKS = NO # Configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. @@ -1790,19 +1876,7 @@ GENERATE_XML = NO XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. @@ -1815,7 +1889,7 @@ XML_PROGRAMLISTING = YES # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- -# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. @@ -1829,14 +1903,23 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen -# Definitions (see http://autogen.sf.net) file that captures the structure of -# the code including all documentation. Note that this feature is still -# experimental and incomplete at the moment. +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sf.net) file that captures the +# structure of the code including all documentation. Note that this feature is +# still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -1845,7 +1928,7 @@ GENERATE_AUTOGEN_DEF = NO # Configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. @@ -1853,7 +1936,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. @@ -1861,9 +1944,9 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely # formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO the +# understand what is going on. On the other hand, if this tag is set to NO, the # size of the Perl module output will be much smaller and Perl will parse it # just the same. # The default value is: YES. @@ -1883,14 +1966,14 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names -# in the source code. If set to NO only conditional compilation will be +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. @@ -1906,7 +1989,7 @@ MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1949,9 +2032,9 @@ PREDEFINED = __GNUC__=4 \ EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an -# all uppercase name, and do not end with a semicolon. Such function macros are -# typically used for boiler-plate code, and will confuse the parser if not +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not # removed. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1971,7 +2054,7 @@ SKIP_FUNCTION_MACROS = YES # where loc1 and loc2 can be relative or absolute paths or URLs. See the # section "Linking to external documentation" for more information about the use # of tag files. -# Note: Each tag file must have an unique name (where the name does NOT include +# Note: Each tag file must have a unique name (where the name does NOT include # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. @@ -1983,20 +2066,21 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external class will be listed in the -# class index. If set to NO only the inherited external classes will be listed. +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. # The default value is: NO. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in -# the modules index. If set to NO, only the current project's groups will be +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. EXTERNAL_GROUPS = YES -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. @@ -2013,7 +2097,7 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more @@ -2038,7 +2122,7 @@ MSCGEN_PATH = DIA_PATH = -# If set to YES, the inheritance and collaboration graphs will hide inheritance +# If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2063,7 +2147,7 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# When you want a differently looking font n the dot files that doxygen +# When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by @@ -2111,7 +2195,7 @@ COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. @@ -2163,7 +2247,8 @@ INCLUDED_BY_GRAPH = YES # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2174,7 +2259,8 @@ CALL_GRAPH = NO # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2197,11 +2283,15 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, jpg, gif and svg. +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2244,6 +2334,19 @@ MSCFILE_DIRS = DIAFILE_DIRS = +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized @@ -2280,7 +2383,7 @@ MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support # this, this feature is disabled by default. @@ -2297,7 +2400,7 @@ DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. diff --git a/NEWS.md b/NEWS.md index 60b94238..5e034215 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,20 @@ NEWS ==== +--------------------- +current master branch +--------------------- + +- New sort order for the ls command: -s=h sorts the ls output by hash + value of the audio file. +- The contents of overview.pdf have been integrated into the user + manual. +- The doxygen source browser has been disabled temporarily. The + API reference is still online, though. +- Overhaul of the source code documentation. +- The deprecated --full-path option of the ls command has been + removed. It was a no-op since 0.6.0. +- The wma decoder has been cleaned up and its bitstream API made + more robust. ------------------------------- 0.6.0 (2017-04-28) "fuzzy flux" diff --git a/aacdec_filter.c b/aacdec_filter.c index 26d5f652..ce3eb3bd 100644 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@ -28,7 +28,7 @@ /** * data specific to the aacdec filter * - * \sa filter, filter_node + * \sa \ref filter, \ref filter_node. */ struct private_aacdec_data { /** the return value of aac_open */ diff --git a/afh.h b/afh.h index 6dc5a3fc..20c61dba 100644 --- a/afh.h +++ b/afh.h @@ -103,7 +103,7 @@ struct audio_format_handler { * success, the function must return a positive value and fill in the * given struct afh_info. * - * \sa struct afh_info + * \sa struct \ref afh_info. */ int (*get_file_info)(char *map, size_t numbytes, int fd, struct afh_info *afhi); diff --git a/afh_common.c b/afh_common.c index 6feb7c35..1614c27c 100644 --- a/afh_common.c +++ b/afh_common.c @@ -16,8 +16,18 @@ #include "afh.h" typedef void afh_init_func(struct audio_format_handler *); -/* It does not hurt to declare init functions which are not available. */ -extern afh_init_func mp3_init, ogg_init, aac_afh_init, wma_afh_init, + +/* + * Declaration of the audio format handler init functions. + * + * These symbols are referenced in the afl array below. + * + * Most audio format handlers depend on an external library and are not + * compiled in if the library is not installed. Hence it is well possible that + * not all of these functions are defined. It does not hurt to declare them + * anyway, and this avoids another set of ifdefs. + */ +extern afh_init_func mp3_afh_init, ogg_afh_init, aac_afh_init, wma_afh_init, spx_afh_init, flac_afh_init, opus_afh_init; /** The list of all status items */ @@ -28,7 +38,7 @@ const char *status_item_list[] = {STATUS_ITEM_ARRAY}; * * We always define the full array of audio formats even if some audio formats * were not compiled in. This is because for each audio file the number of its - * audio format is stored in the database. We don't want that numbers to become + * audio format is stored in the database. We don't want these numbers to become * stale just because the user installed a new version of paraslash that * supports a different set of audio formats. * @@ -38,12 +48,12 @@ const char *status_item_list[] = {STATUS_ITEM_ARRAY}; static struct audio_format_handler afl[] = { { .name = "mp3", - .init = mp3_init, + .init = mp3_afh_init, }, { .name = "ogg", #if defined(HAVE_OGG) && defined(HAVE_VORBIS) - .init = ogg_init, + .init = ogg_afh_init, #endif }, { diff --git a/afh_recv.c b/afh_recv.c index 9d6effe1..d2d8b52b 100644 --- a/afh_recv.c +++ b/afh_recv.c @@ -237,6 +237,7 @@ out: return ret; } +/** See \ref recv_init(). */ const struct receiver lsg_recv_cmd_com_afh_user_data = { .init = afh_init, .open = afh_recv_open, diff --git a/afs.c b/afs.c index 75b82c21..59595567 100644 --- a/afs.c +++ b/afs.c @@ -37,22 +37,22 @@ #include "sideband.h" #include "command.h" -/** The osl tables used by afs. \sa blob.c. */ +/** The osl tables used by afs. \sa \ref blob.c. */ enum afs_table_num { - /** Contains audio file information. See aft.c. */ + /** Contains audio file information. See \ref aft.c. */ TBLNUM_AUDIO_FILES, - /** The table for the paraslash attributes. See attribute.c. */ + /** The table for the paraslash attributes. See \ref attribute.c. */ TBLNUM_ATTRIBUTES, /** * Paraslash's scoring system is based on Gaussian normal * distributions, and the relevant data is stored in the rbtrees of an - * osl table containing only volatile columns. See score.c for + * osl table containing only volatile columns. See \ref score.c for * details. */ TBLNUM_SCORES, /** * A standard blob table containing the mood definitions. For details - * see mood.c. + * see \ref mood.c. */ TBLNUM_MOODS, /** A blob table containing lyrics on a per-song basis. */ @@ -130,7 +130,7 @@ extern uint32_t afs_socket_cookie; * command socket, so that the handler process can read the id, attach the * shared memory area and use the result. * - * \sa struct callback_result. + * \sa \ref struct callback_result. */ struct callback_query { /** The function to be called. */ @@ -146,7 +146,7 @@ struct callback_query { * into the shared memory area holding the result, mainly to let the command * handler know the size of the result. * - * \sa struct callback_query. + * \sa \ref struct callback_query. */ struct callback_result { /** The number of bytes of the result. */ @@ -201,9 +201,8 @@ static int dispatch_result(int result_shmid, callback_result_handler *handler, * shmid are passed to that function as an osl object. The private_result_data * pointer is passed as the second argument to \a result_handler. * - * \return Number of shared memory areas dispatched on success, negative on errors. - * - * \sa send_option_arg_callback_request(), send_standard_callback_request(). + * \return Number of shared memory areas dispatched on success, negative on + * errors. */ int send_callback_request(afs_callback *f, struct osl_object *query, callback_result_handler *result_handler, @@ -381,7 +380,7 @@ int for_each_matching_row(struct pattern_match_data *pmd) * \a obj1 is found, respectively, to be less than, to match, or be greater than * obj2. * - * \sa strcmp(3), strncmp(3), osl_compare_func. + * \sa strcmp(3), strncmp(3). */ int string_compare(const struct osl_object *obj1, const struct osl_object *obj2) { @@ -433,7 +432,7 @@ static int pass_afd(int fd, char *buf, size_t size) * * \return Standard. * - * \sa open_and_update_audio_file(). + * \sa \ref open_and_update_audio_file(). */ static int open_next_audio_file(void) { diff --git a/afs.h b/afs.h index 879331ec..ea4b497e 100644 --- a/afs.h +++ b/afs.h @@ -141,7 +141,7 @@ struct pattern_match_data { unsigned loop_col_num; /** Data from this column is matched against the given patterns. */ unsigned match_col_num; - /** \see pattern_match_flags. */ + /** \see \ref pattern_match_flags. */ unsigned pm_flags; /** This value is passed verbatim to fnmatch(). */ int fnmatch_flags; @@ -174,16 +174,14 @@ struct afs_callback_arg { * Therefore afs commands typically consist of two functions: The command * handler and the corresponding callback function that runs in afs context. * - * \sa send_callback_request(). + * \sa \ref send_callback_request(). */ typedef int afs_callback(struct afs_callback_arg *aca); /** - * Callbacks send chunks to data back to the command handler. Pointers to - * this type of function are used by \ref send_callback_request and friends - * to deal with the data in the command handler process. - * - * \sa \ref send_callback_request(). + * Some AFS callbacks need to send data back to the command handler. Pointers + * to this type of function are passed to \ref send_callback_request() and + * related functions to dispatch the data in the command handler process. */ typedef int callback_result_handler(struct osl_object *result, uint8_t band, void *private); int afs_cb_result_handler(struct osl_object *result, uint8_t band, void *private); diff --git a/aft.c b/aft.c index 4a812448..63a40d79 100644 --- a/aft.c +++ b/aft.c @@ -138,7 +138,7 @@ struct ls_options { /** * Describes the layout of the mmapped-afs info struct. * - * \sa struct afs_info. + * \sa struct \ref afs_info. */ enum afsi_offsets { /** Where .last_played is stored. */ @@ -167,7 +167,7 @@ enum afsi_offsets { * \param afsi Pointer to the audio file info to be converted. * \param obj Result pointer. * - * \sa load_afsi(). + * \sa \ref load_afsi(). */ static void save_afsi(struct afs_info *afsi, struct osl_object *obj) { @@ -192,7 +192,7 @@ static void save_afsi(struct afs_info *afsi, struct osl_object *obj) * * \return Standard. * - * \sa save_afsi(). + * \sa \ref save_afsi(). */ static int load_afsi(struct afs_info *afsi, struct osl_object *obj) { @@ -365,7 +365,10 @@ static void save_afhi(struct afh_info *afhi, char *buf) write_u32(buf + CHUNK_TV_TV_SEC_OFFSET, afhi->chunk_tv.tv_sec); write_u32(buf + CHUNK_TV_TV_USEC_OFFSET, afhi->chunk_tv.tv_usec); p = buf + AFHI_INFO_STRING_OFFSET; - /* The sprintf's below are OK as our caller made sure that buf is large enough */ + /* + * The below sprintf(3) calls are OK because our caller already made + * sure that buf is large enough. + */ p += sprintf(p, "%s", afhi->techinfo) + 1; p += sprintf(p, "%s", afhi->tags.artist) + 1; p += sprintf(p, "%s", afhi->tags.title) + 1; @@ -374,6 +377,7 @@ static void save_afhi(struct afh_info *afhi, char *buf) sprintf(p, "%s", afhi->tags.comment); } +/* does not load the chunk table */ static void load_afhi(const char *buf, struct afh_info *afhi) { afhi->seconds_total = read_u32(buf + AFHI_SECONDS_TOTAL_OFFSET); @@ -528,7 +532,7 @@ static int get_afsi_of_path(const char *path, struct afs_info *afsi) * \param row Pointer to a row in the audio file table. * \param path Result pointer. * - * The result is a pointer to mmapped data. The caller must not attempt + * The result is a pointer to memory-mapped data. The caller must not attempt * to free it. * * \return Standard. @@ -552,7 +556,7 @@ int get_audio_file_path_of_row(const struct osl_row *row, char **path) * * \return The return value of the underlying call to osl_get_object(). * - * \sa get_hash_of_row(). + * \sa \ref get_hash_of_row(). */ static int get_hash_object_of_aft_row(const struct osl_row *row, struct osl_object *obj) @@ -590,7 +594,9 @@ static int get_hash_of_row(const struct osl_row *row, unsigned char **hash) * * \return The return value of the underlying call to osl_get_object(). * - * \sa get_chunk_table_of_row(). + * After the call the members of the afhi structure point to mapped memory + * which is owned by the osl table, Hence the caller must not attempt to free + * this memory by calling \ref clear_afhi(). */ int get_afhi_of_row(const struct osl_row *row, struct afh_info *afhi) { @@ -694,7 +700,7 @@ static int get_local_time(uint64_t *seconds, char *buf, size_t size, /* * If the given time is more than six month away from the current time, * we print only the year. The additional space character in the format - * string below makes the formated date align nicely with dates that + * string below makes the formatted date align nicely with dates that * contain the time (those written by the above strftime() statement). */ if (!strftime(buf, size, "%b %e %Y", tm)) @@ -1104,6 +1110,12 @@ out: return ret; } +static int ls_hash_compare(const void *a, const void *b) +{ + struct ls_data *d1 = *(struct ls_data **)a, *d2 = *(struct ls_data **)b; + return memcmp(d1->hash, d2->hash, HASH_SIZE); +} + static int ls_audio_format_compare(const void *a, const void *b) { struct ls_data *d1 = *(struct ls_data **)a, *d2 = *(struct ls_data **)b; @@ -1221,6 +1233,8 @@ static int sort_matching_paths(struct ls_options *options) compar = ls_duration_compare; break; case LS_SORT_BY_AUDIO_FORMAT: compar = ls_audio_format_compare; break; + case LS_SORT_BY_HASH: + compar = ls_hash_compare; break; default: return -E_BAD_SORT; } @@ -1369,7 +1383,6 @@ out: return ret; } -/* TODO: flags -h (sort by hash) */ static int com_ls(struct command_context *cc, struct lls_parse_result *lpr) { const struct lls_command *cmd = SERVER_CMD_CMD_PTR(LS); @@ -1435,6 +1448,8 @@ static int com_ls(struct command_context *cc, struct lls_parse_result *lpr) opts->sorting = LS_SORT_BY_DURATION; else if (!strcmp(val, "a") || !strcmp(val, "audio-format")) opts->sorting = LS_SORT_BY_AUDIO_FORMAT; + else if (!strcmp(val, "h") || !strcmp(val, "hash")) + opts->sorting = LS_SORT_BY_HASH; else { ret = -E_AFT_SYNTAX; goto out; @@ -1907,11 +1922,7 @@ out: } EXPORT_SERVER_CMD_HANDLER(add); -/** - * Flags used by the touch command. - * - * \sa com_touch(). - */ +/** Flags used by the touch command. */ enum touch_flags { /** Whether the \p FNM_PATHNAME flag should be passed to fnmatch(). */ TOUCH_FLAG_FNM_PATHNAME = 1, @@ -2397,8 +2408,6 @@ static int check_audio_file(struct osl_row *row, void *data) * \param aca Only ->pbout is used for diagnostics. * * \return Standard. Inconsistencies are reported but not regarded as an error. - * - * \sa com_check(). */ int aft_check_callback(struct afs_callback_arg *aca) { @@ -2467,7 +2476,7 @@ int aft_check_attributes(uint64_t att_mask, struct para_buffer *pb) * * \param flags Usual flags that are passed to osl_close_table(). * - * \sa osl_close_table(). + * \sa \ref osl_close_table(). */ static void aft_close(void) { @@ -2482,7 +2491,7 @@ static void aft_close(void) * * \return Standard. * - * \sa osl_open_table(). + * \sa \ref osl_open_table(). */ static int aft_open(const char *dir) { diff --git a/attribute.c b/attribute.c index 637e1f51..2ea73a6a 100644 --- a/attribute.c +++ b/attribute.c @@ -476,7 +476,7 @@ int attribute_check_callback(struct afs_callback_arg *aca) /** * Close the attribute table. * - * \sa osl_close_table(). + * \sa \ref osl_close_table(). */ static void attribute_close(void) { @@ -491,7 +491,7 @@ static void attribute_close(void) * * \return Positive on success, negative on errors. * - * \sa osl_open_table(). + * \sa \ref osl_open_table(). */ static int attribute_open(const char *dir) { diff --git a/audioc.c b/audioc.c index 38a8db5d..1d69b2c1 100644 --- a/audioc.c +++ b/audioc.c @@ -132,7 +132,6 @@ static void grab_completer(struct i9e_completion_info *ci, i9e_complete_option(opts, ci, cr); } -I9E_DUMMY_COMPLETER(SUPERCOMMAND_UNAVAILABLE); static struct i9e_completer audiod_completers[] = { #define LSG_AUDIOD_CMD_CMD(_name) {.name = #_name, \ .completer = _name ## _completer} @@ -332,7 +331,7 @@ static void handle_help_flag(void) * * \return EXIT_SUCCESS or EXIT_FAILURE. * - * \sa send_cred_buffer(), para_audioc(1), para_audiod(1). + * \sa \ref send_cred_buffer(), para_audioc(1), para_audiod(1). */ int main(int argc, char *argv[]) { diff --git a/audiod.c b/audiod.c index 74d0ce23..defd673d 100644 --- a/audiod.c +++ b/audiod.c @@ -109,9 +109,7 @@ struct slot_info { * para_audiod uses \p MAX_STREAM_SLOTS different slots, each of which may * be associated with a receiver/filter/writer triple. This array holds all * information on the status of these slots. - * - * \sa struct slot_info - * */ + */ struct slot_info slot[MAX_STREAM_SLOTS]; /** The vss status flags audiod is interested in. */ @@ -167,8 +165,8 @@ struct status_task { char *stat_item_values[NUM_STAT_ITEMS] = {NULL}; /** - * the current mode of operation of which can be changed by the on/off/cycle - * commands. It is either, AUDIOD_OFF, AUDIOD_ON or AUDIOD_STANDBY. + * The current mode of operation (AUDIOD_OFF, AUDIOD_ON or AUDIOD_STANDBY). + * Set by the on/off/cycle commands. */ int audiod_status = AUDIOD_ON; @@ -179,20 +177,20 @@ static struct status_task status_task_struct; static uid_t *uid_whitelist; /** - * the task that calls the status command of para_server + * The task that calls the status command of para_server. * - * \sa struct status_task + * \sa \ref struct status_task. */ static struct status_task *stat_task = &status_task_struct; struct command_task { /** The local listening socket. */ int fd; - /** the associated task structure */ + /** The associated task structure. */ struct task *task; }; -/** iterate over all supported audio formats */ +/** Iterate over all supported audio formats. */ #define FOR_EACH_AUDIO_FORMAT(af) for (af = 0; af < NUM_AUDIO_FORMATS; af++) /** diff --git a/audiod_command.c b/audiod_command.c index 9623c4f5..cccc2a89 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -416,7 +416,7 @@ EXPORT_AUDIOD_CMD_HANDLER(version) * \return Positive on success, negative on errors, zero if there was no * connection to accept. * - * \sa para_accept(), recv_cred_buffer() + * \sa \ref para_accept(), \ref recv_cred_buffer(). * */ int handle_connect(int accept_fd, fd_set *rfds) { diff --git a/blob.c b/blob.c index 8abecf6a..2d7c6050 100644 --- a/blob.c +++ b/blob.c @@ -30,8 +30,6 @@ * \param obj2 Pointer to the second integer. * * \return The values required for an osl compare function. - * - * \sa osl_compare_func, osl_hash_compare(). */ static int uint32_compare(const struct osl_object *obj1, const struct osl_object *obj2) { diff --git a/buffer_tree.c b/buffer_tree.c index b0cd6665..9b5bcda1 100644 --- a/buffer_tree.c +++ b/buffer_tree.c @@ -905,7 +905,7 @@ size_t btr_get_output_queue_size(struct btr_node *btrn) * \return \p -ENOTSUP if no parent node of \a btrn understands \a command. * Otherwise the return value of the command handler is returned. * - * \sa \ref receiver::execute, filter::execute, writer::execute. + * \sa \ref receiver::execute, \ref filter::execute, \ref writer::execute. */ int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result) { @@ -935,7 +935,7 @@ int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result) * * \return A pointer to the \a context address specified at node creation time. * - * \sa btr_new_node(), struct \ref btr_node_description. + * \sa \ref btr_new_node(), struct \ref btr_node_description. */ void *btr_context(struct btr_node *btrn) { diff --git a/client.c b/client.c index 68d8a7ef..2607ee20 100644 --- a/client.c +++ b/client.c @@ -497,7 +497,6 @@ static int client_i9e_line_handler(char *line) return 1; } -I9E_DUMMY_COMPLETER(SUPERCOMMAND_UNAVAILABLE); static struct i9e_completer completers[] = { #define LSG_SERVER_CMD_CMD(_name) {.name = #_name, \ .completer = _name ## _completer} @@ -616,7 +615,8 @@ static struct supervisor_task supervisor_task; * * \return EXIT_SUCCESS or EXIT_FAILURE * - * \sa client_open(), stdin.c, stdout.c, para_client(1), para_server(1) + * \sa \ref client_open(), \ref stdin.c, \ref stdout.c, para_client(1), + * para_server(1). */ int main(int argc, char *argv[]) { diff --git a/close_on_fork.c b/close_on_fork.c index c606d98c..655dbc56 100644 --- a/close_on_fork.c +++ b/close_on_fork.c @@ -19,7 +19,7 @@ static int initialized; /** * Describes an element of the close-on-fork list. * - * \sa list.h + * \sa \ref list.h. */ struct close_on_fork { /** The file descriptor which should be closed after fork(). */ diff --git a/command.c b/command.c index d0aeea3d..f1797304 100644 --- a/command.c +++ b/command.c @@ -107,8 +107,8 @@ static unsigned get_status(struct misc_meta_data *nmmd, bool parser_friendly, clock_get_realtime(¤t_time); /* * The calls to WRITE_STATUS_ITEM() below never fail because - * b->max_size is zero (unlimited), see para_printf(). However, clang - * is not smart enough to prove this and complains nevertheless. + * b->max_size is zero (unlimited), see \ref para_printf(). However, + * clang is not smart enough to prove this and complains nevertheless. * Casting the return value to void silences clang. */ (void)WRITE_STATUS_ITEM(&b, SI_STATUS, "%s\n", status); @@ -227,7 +227,7 @@ static int check_sender_args(struct command_context *cc, struct lls_parse_result *lpr, struct sender_command_data *scd) { int i, ret; - const char *subcmds[] = {SENDER_SUBCOMMANDS}; + const char * const subcmds[] = {SENDER_SUBCOMMANDS}; const char *arg; char *errctx; unsigned num_inputs = lls_num_inputs(lpr); @@ -246,10 +246,10 @@ static int check_sender_args(struct command_context *cc, return -E_COMMAND_SYNTAX; scd->sender_num = i; arg = lls_input(1, lpr); - for (i = 0; subcmds[i]; i++) + for (i = 0; i < NUM_SENDER_CMDS; i++) if (!strcmp(subcmds[i], arg)) break; - if (!subcmds[i]) + if (i == NUM_SENDER_CMDS) return -E_COMMAND_SYNTAX; scd->cmd_num = i; if (!senders[scd->sender_num].client_cmds[scd->cmd_num]) @@ -884,7 +884,7 @@ static int run_command(struct command_context *cc, struct iovec *iov, * the function if the connection was not authenticated when the timeout * expires. * - * \sa alarm(2), crypt.c, crypt.h + * \sa alarm(2), \ref crypt.c, \ref crypt.h. */ __noreturn void handle_connect(int fd, const char *peername) { diff --git a/configure.ac b/configure.ac index a589613b..c2cb47e6 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,6 @@ AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) AC_DEFUN([add_dot_o],[$(for i in $@; do printf "$i.o "; done)]) -AC_DEFUN([add_cmdline],[$(for i in $@; do printf "${i}.cmdline "; done)]) AC_DEFUN([LIB_ARG_WITH], [ AC_ARG_WITH($1-headers, [AS_HELP_STRING(--with-$1-headers=dir, [look for $1 headers in dir])]) @@ -76,7 +75,7 @@ STASH_FLAGS LIB_ARG_WITH([lopsub], [-llopsub]) HAVE_LOPSUB=yes AC_CHECK_HEADER(lopsub.h, [], [HAVE_LOPSUB=no]) -AC_CHECK_LIB([lopsub], [lls_merge], [], [HAVE_LOPSUB=yes]) +AC_CHECK_LIB([lopsub], [lls_merge], [], [HAVE_LOPSUB=no]) if test $HAVE_LOPSUB = no; then AC_MSG_ERROR([ The lopsub library is required to build this software, but the above checks indicate it is not installed on your system. @@ -197,7 +196,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]])],[have_ip_mreqn=yes],[have_ip_mreqn=no]) AC_MSG_RESULT($have_ip_mreqn) if test ${have_ip_mreqn} = yes; then - AC_DEFINE(HAVE_IP_MREQN, 1, define to 1 you have struct ip_mreqn) + AC_DEFINE(HAVE_IP_MREQN, 1, define to 1 if you have struct ip_mreqn) fi ########################################################################### ogg STASH_FLAGS diff --git a/daemon.c b/daemon.c index 20cdc6ae..4e15824f 100644 --- a/daemon.c +++ b/daemon.c @@ -374,8 +374,6 @@ time_t daemon_get_uptime(const struct timeval *current_time) * \param current_time See a \ref daemon_get_uptime(). * * \return A dynamically allocated string of the form "days:hours:minutes". - * - * \sa server_uptime. */ __malloc char *daemon_get_uptime_str(const struct timeval *current_time) { diff --git a/dccp_recv.c b/dccp_recv.c index 318969af..3385d66c 100644 --- a/dccp_recv.c +++ b/dccp_recv.c @@ -155,6 +155,7 @@ out: return ret; } +/** See \ref recv_init(). */ const struct receiver lsg_recv_cmd_com_dccp_user_data = { .open = dccp_recv_open, .close = dccp_recv_close, diff --git a/dccp_send.c b/dccp_send.c index 61d42126..4ad25e73 100644 --- a/dccp_send.c +++ b/dccp_send.c @@ -138,7 +138,7 @@ static void dccp_post_select(fd_set *rfds, __a_unused fd_set *wfds) /* * Bypass unused CCID paths: the sender does not receive application data * from the client; by shutting down this unused communication path we can - * reduce processing costs a bit. See analogous comment in dccp_recv.c. + * reduce processing costs a bit. See analogous comment in \ref dccp_recv.c. */ if (shutdown(sc->fd, SHUT_RD) < 0) { PARA_WARNING_LOG("%s\n", strerror(errno)); diff --git a/error.h b/error.h index ea8f82c4..e5d2469b 100644 --- a/error.h +++ b/error.h @@ -8,6 +8,7 @@ /** Codes and messages. */ #define PARA_ERRORS \ + PARA_ERROR(SUCCESS, "success"), \ PARA_ERROR(AACDEC_INIT, "failed to init aac decoder"), \ PARA_ERROR(AAC_DECODE, "aac decode error"), \ PARA_ERROR(ACL_PERM, "access denied by acl"), \ @@ -338,8 +339,8 @@ _static_inline_ int osl(int ret) /** * Wrapper for lopsub library calls. * - * \param ret See osl(). - * \return See osl(). + * \param ret See \ref osl(). + * \return See \ref osl(). */ _static_inline_ int lls(int ret) { diff --git a/fd.c b/fd.c index 6a26ce5e..dc4fd59c 100644 --- a/fd.c +++ b/fd.c @@ -405,7 +405,7 @@ __must_check int mark_fd_nonblocking(int fd) * This wrapper for FD_SET() passes its first two arguments to \p FD_SET. Upon * return, \a max_fileno contains the maximum of the old_value and \a fd. * - * \sa para_select. + * \sa \ref para_select. */ void para_fd_set(int fd, fd_set *fds, int *max_fileno) { @@ -674,7 +674,7 @@ out: * * \return Standard. * - * \sa munmap(2), mmap_full_file(). + * \sa munmap(2), \ref mmap_full_file(). */ int para_munmap(void *start, size_t length) { @@ -716,8 +716,6 @@ int write_ok(int fd) * * Common approach that opens /dev/null until it gets a file descriptor greater * than two. - * - * \sa okir's Black Hats Manual. */ void valid_fd_012(void) { diff --git a/filter.h b/filter.h index 4537b220..ab98c244 100644 --- a/filter.h +++ b/filter.h @@ -41,7 +41,7 @@ struct filter_node { * time, all these filter functions must be reentrant; no static non-constant * variables may be used. * - * \sa mp3dec_filter.c, oggdec_filter.c, wav_filter.c, compress_filter.c, filter_node + * \sa \ref filter_node. */ struct filter { /** @@ -143,6 +143,5 @@ static inline void write_int16_host_endian(char *buf, int val) #endif } -/** Make a filter pointer from the filter number. */ const struct filter *filter_get(int filter_num); const char *filter_name(int filter_num); diff --git a/grab_client.c b/grab_client.c index 11fff4cc..382b0470 100644 --- a/grab_client.c +++ b/grab_client.c @@ -8,7 +8,6 @@ #include #include -#include #include #include "audiod_cmd.lsg.h" diff --git a/gui.c b/gui.c index 24f1c727..5bad7e14 100644 --- a/gui.c +++ b/gui.c @@ -56,9 +56,7 @@ struct rb_entry { static struct ringbuffer *bot_win_rb; static unsigned scroll_position; - static pid_t exec_pid; - static int exec_fds[2] = {-1, -1}; static int loglevel; @@ -253,7 +251,7 @@ static char *km_keyname(int c) } /* Print given number of spaces to curses window. */ -static void add_spaces(WINDOW* win, unsigned int num) +static void add_spaces(WINDOW *win, unsigned int num) { const char space[] = " "; const unsigned sz = sizeof(space) - 1; /* number of spaces */ @@ -269,10 +267,10 @@ static void add_spaces(WINDOW* win, unsigned int num) } /* - * print aligned string to curses window. This function always prints + * Print aligned string to curses window. This function always prints * exactly len chars. */ -static int align_str(WINDOW* win, const char *str, unsigned int len, +static int align_str(WINDOW *win, const char *str, unsigned int len, unsigned int align) { int ret, num; /* of spaces */ @@ -458,10 +456,8 @@ static void rb_add_entry(int color, char *msg) waddstr(bot.win, msg); } -/* - * print formated output to bot win and refresh - */ -__printf_2_3 static void outputf(int color, const char* fmt,...) +/* Print formatted output to bot win and refresh. */ +__printf_2_3 static void outputf(int color, const char *fmt,...) { char *msg; va_list ap; @@ -504,8 +500,9 @@ static __printf_2_3 void curses_log(int ll, const char *fmt,...) vfprintf(stderr, fmt, ap); va_end(ap); } + /** The log function of para_gui, always set to curses_log(). */ -__printf_2_3 void (*para_log)(int, const char*, ...) = curses_log; +__printf_2_3 void (*para_log)(int, const char *, ...) = curses_log; /* Call endwin() to reset the terminal into non-visual mode. */ static void shutdown_curses(void) @@ -522,8 +519,8 @@ static void shutdown_curses(void) endwin(); } -/* disable curses, print a message, kill running processes and exit */ -__noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...) +/* Disable curses, print a message, kill running processes and exit. */ +__noreturn __printf_2_3 static void die(int exit_code, const char *fmt, ...) { va_list argp; @@ -546,9 +543,7 @@ __noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...) exit(exit_code); } -/* - * Print stat item #i to curses window - */ +/* Print stat item #i to curses window. */ static void print_stat_item(int i) { char *tmp; @@ -698,9 +693,7 @@ static int status_post_select(struct sched *s, void *context) return 0; } -/* - * init all windows - */ +/* Initialize all windows. */ static void init_wins(int top_lines) { int top_y = 0, bot_y = top_lines + 1, sb_y = LINES - 2, @@ -904,7 +897,7 @@ static void parse_config_file_or_die(bool reload) if (reload) /* config file overrides command line */ ret = lls(lls_merge(cf_lpr, cmdline_lpr, CMD_PTR, &merged_lpr, &errctx)); - else /* command line options overrride config file options */ + else /* command line options override config file options */ ret = lls(lls_merge(cmdline_lpr, cf_lpr, CMD_PTR, &merged_lpr, &errctx)); lls_free_parse_result(cf_lpr, CMD_PTR); @@ -928,7 +921,7 @@ free_cf: } } -/* reread configuration, terminate on errors */ +/* Reread configuration, terminate on errors. */ static void reread_conf(void) { /* @@ -942,9 +935,7 @@ static void reread_conf(void) print_in_bar(COLOR_MSG, "config file reloaded\n"); } -/* - * React to various signal-related events - */ +/* React to various signal-related events. */ static int signal_post_select(struct sched *s, __a_unused void *context) { int ret = para_next_signal(&s->rfds); @@ -1045,7 +1036,7 @@ static void input_pre_select(struct sched *s, __a_unused void *context) sched_min_delay(s); } -/* read from command pipe and print data to bot window */ +/* Read from command pipe and print data to bot window. */ static void exec_and_display(const char *file_and_args) { int ret, fds[3] = {0, 1, 1}; @@ -1079,9 +1070,7 @@ static void exec_para(const char *args) free(file_and_args); } -/* - * shutdown curses and stat pipe before executing external commands - */ +/* Shutdown curses and stat pipe before executing external commands. */ static void exec_external(char *file_and_args) { int fds[3] = {-1, -1, -1}; @@ -1135,7 +1124,8 @@ static void handle_command(int c) km_keyname(c)); } -static int input_post_select(__a_unused struct sched *s, __a_unused void *context) +static int input_post_select(__a_unused struct sched *s, + __a_unused void *context) { int ret; enum exec_status exs = exec_status(); diff --git a/http_recv.c b/http_recv.c index d49cf2a8..67691a34 100644 --- a/http_recv.c +++ b/http_recv.c @@ -30,7 +30,7 @@ /** * the possible states of a http receiver node * - * \sa receiver_node + * \sa \ref receiver_node. */ enum http_recv_status {HTTP_CONNECTED, HTTP_SENT_GET_REQUEST, HTTP_STREAMING}; @@ -46,7 +46,7 @@ struct private_http_recv_data { * It gets initialized to \p HTTP_CONNECTED by the open function of the * http receiver. * - * \sa receiver::open, receiver_node. + * \sa \ref receiver::open, \ref receiver_node. */ enum http_recv_status status; }; @@ -167,6 +167,7 @@ static int http_recv_open(struct receiver_node *rn) return 1; } +/** See \ref recv_init(). */ const struct receiver lsg_recv_cmd_com_http_user_data = { .open = http_recv_open, .close = http_recv_close, diff --git a/interactive.h b/interactive.h index e6d53dee..82d3cd71 100644 --- a/interactive.h +++ b/interactive.h @@ -33,7 +33,7 @@ struct i9e_completion_result { * * \param name Determines the name of the function to be defined. */ -#define I9E_DUMMY_COMPLETER(name) void name ## _completer( \ +#define I9E_DUMMY_COMPLETER(name) static void name ## _completer( \ __a_unused struct i9e_completion_info *ciname, \ struct i9e_completion_result *result) {result->matches = NULL;} diff --git a/ipc.c b/ipc.c index d7f515df..3cc5c156 100644 --- a/ipc.c +++ b/ipc.c @@ -68,7 +68,7 @@ static void para_semop(int id, struct sembuf *sops, int num) * * This function either succeeds or aborts. * - * \sa semop(2), struct misc_meta_data. + * \sa semop(2), struct \ref misc_meta_data. */ void mutex_lock(int id) { @@ -94,7 +94,7 @@ void mutex_lock(int id) * * This function either succeeds or aborts. * - * \sa semop(2), struct misc_meta_data. + * \sa semop(2), struct \ref misc_meta_data. */ void mutex_unlock(int id) { diff --git a/m4/lls/server_cmd.suite.m4 b/m4/lls/server_cmd.suite.m4 index e2bd162d..2145c516 100644 --- a/m4/lls/server_cmd.suite.m4 +++ b/m4/lls/server_cmd.suite.m4 @@ -219,13 +219,6 @@ aux_info_prefix = Permissions: also given), chunk time and chunk offsets. [/help] - [option full-path] - short_opt = F - summary = list full paths, match full paths against patterns - [help] - This option is the default, so it does nothing. Deprecated as of - v0.6.0, scheduled for removal in v0.6.1. - [/help] [option basename] short_opt = b summary = list and match basenames only @@ -284,6 +277,8 @@ aux_info_prefix = Permissions: audio-format (a) + hash (h) + If --sort is not given, path sort is implied. [/help] diff --git a/mm.h b/mm.h index 2caace7f..e6c0d125 100644 --- a/mm.h +++ b/mm.h @@ -17,7 +17,7 @@ * Mood score functions must return values between -100 and +100 inclusively. * Boolean score functions should always return either -100 or +100. * - * \sa struct mood_method, mood_parser. + * \sa struct \ref mood_method, \ref mood_parser. */ typedef int mood_score_function(const char *path, const struct afs_info *afsi, const struct afh_info *afhi, const void *data); @@ -36,19 +36,15 @@ typedef int mood_score_function(const char *path, const struct afs_info *afsi, * later in the mood_score_function of the mood_method. The mood_parser may * store a pointer to its structure via the void** pointer. * - * \sa mood_open(), mood_cleanup_function, mood_score_function. + * \sa \ref mood_cleanup_function, \ref mood_score_function. */ typedef int mood_parser(int, char **, void **); /** * Deallocate resources which were allocated by the mood_parser. * - * This optional function of a mood_method is used to free any resources - * allocated in mood_open() by the mood_parser. The argument passed is a - * pointer to the mood_method specific data structure that was returned by the - * mood_parser. - * - * \sa mood_parser. + * Function to free the resources allocated in \ref mood_method::parser. The + * argument is a pointer to mood method specific data returned by ->parser(). */ typedef void mood_cleanup_function(void *); diff --git a/mood.c b/mood.c index acc5583f..315ef0cb 100644 --- a/mood.c +++ b/mood.c @@ -59,15 +59,13 @@ struct mood_item { struct list_head mood_item_node; }; -/** - * Created from the mood definition by mood_open(). +/* + * Created from the mood definition by \ref change_current_mood(). * * When a mood is opened, each line of its definition is investigated, and a - * corresponding mood item is produced. Each mood line starts with \p accept, - * \p deny, or \p score which determines the type of the mood line. For each - * such type a linked list is maintained whose entries are the mood items. - * - * \sa mood_item, mood_open(). + * corresponding mood item is produced. Each mood line starts with accept, + * deny, or score which determines the type of the mood line. For each such + * type a linked list is maintained whose entries are the mood items. */ struct mood { /** The name of this mood. */ @@ -82,7 +80,7 @@ struct mood { /* * If current_mood is NULL then no mood is currently open. If - * current_mood->name is NULL, the dummy mood is currently open + * current_mood->name is NULL, the dummy mood is currently open. */ static struct mood *current_mood; @@ -142,8 +140,8 @@ static bool get_item_score(struct mood_item *item, const struct afs_info *afsi, } /* returns 1 if row admissible, 0 if not, negative on errors */ -static int compute_mood_score(const struct osl_row *aft_row, struct mood *m, - long *result) +static int row_is_admissible(const struct osl_row *aft_row, struct mood *m, + long *scorep) { struct mood_item *item; int ret; @@ -156,13 +154,13 @@ static int compute_mood_score(const struct osl_row *aft_row, struct mood *m, if (!m) return -E_NO_MOOD; ret = get_afsi_of_row(aft_row, &afsi); - if (ret< 0) + if (ret < 0) return ret; ret = get_afhi_of_row(aft_row, &afhi); - if (ret< 0) + if (ret < 0) return ret; ret = get_audio_file_path_of_row(aft_row, &path); - if (ret< 0) + if (ret < 0) return ret; /* reject audio file if it matches any entry in the deny list */ list_for_each_entry(item, &m->deny_list, mood_item_node) { @@ -192,7 +190,7 @@ static int compute_mood_score(const struct osl_row *aft_row, struct mood *m, } if (score_arg_sum) score /= score_arg_sum; - *result = score; + *scorep = score; return 1; } @@ -259,7 +257,6 @@ struct mood_line_parser_data { * is either an integer or "random" which assigns a random score to * all matching files */ - static int parse_mood_line(char *mood_line, void *data) { struct mood_line_parser_data *mlpd = data; @@ -524,9 +521,7 @@ static int del_afs_statistics(const struct osl_row *row) return 1; } -/** - * Structure used during mood_open(). - * +/* * At mood open time we determine the set of admissible files for the given * mood. The mood score of each admissible file is computed by adding up all * mood item scores. Next, we update the afs statistics and append a struct @@ -537,8 +532,6 @@ static int del_afs_statistics(const struct osl_row *row) * the afs_statistics and the current time) to the mood score. Finally, all * audio files in the temporary array are added to the score table and the * array is freed. - * - * \sa mood_method, admissible_array. */ struct admissible_file_info { @@ -572,7 +565,7 @@ static int add_if_admissible(struct osl_row *aft_row, void *data) int ret; long score = 0; - ret = compute_mood_score(aft_row, aa->m, &score); + ret = row_is_admissible(aft_row, aa->m, &score); if (ret <= 0) return ret; if (statistics.num >= aa->size) { @@ -631,7 +624,8 @@ _static_inline_ int64_t update_quadratic_deviation(int64_t n, int64_t old_qd, return old_qd + delta * (sigma - 2 * old_sum / n - delta / n); } -static int update_afs_statistics(struct afs_info *old_afsi, struct afs_info *new_afsi) +static int update_afs_statistics(struct afs_info *old_afsi, + struct afs_info *new_afsi) { unsigned n; int ret = get_num_admissible_files(&n); @@ -679,7 +673,7 @@ static int delete_from_statistics_and_score_table(const struct osl_row *aft_row) * * \return Positive on success, negative on errors. * - * \sa score_delete(). + * \sa \ref score_delete(). */ static int mood_delete_audio_file(const struct osl_row *aft_row) { @@ -718,7 +712,7 @@ static int mood_update_audio_file(const struct osl_row *aft_row, if (ret < 0) return ret; was_admissible = ret; - ret = compute_mood_score(aft_row, current_mood, &score); + ret = row_is_admissible(aft_row, current_mood, &score); if (ret < 0) return ret; is_admissible = (ret > 0); @@ -782,8 +776,7 @@ static void log_statistics(void) /** * Close the current mood. * - * Free all resources of the current mood which were allocated during - * mood_open(). + * Frees all resources of the current mood. */ void close_current_mood(void) { @@ -805,8 +798,7 @@ void close_current_mood(void) * \return Positive on success, negative on errors. Loading the dummy mood * always succeeds. * - * \sa struct admissible_file_info, struct admissible_array, struct - * afs_info::last_played, mood_close(). + * \sa struct \ref afs_info::last_played. */ int change_current_mood(const char *mood_name) { @@ -854,18 +846,15 @@ out: free(aa.array); return ret; } -/** + +/* * Close and re-open the current mood. * - * This function is used if changes to the audio file table or the - * attribute table were made that render the current list of admissible - * files useless. For example, if an attribute is removed from the - * attribute table, this function is called. - * - * \return Positive on success, negative on errors. If no mood is currently - * open, the function returns success. + * This function is called on events which render the current list of + * admissible files useless, for example if an attribute is removed from the + * attribute table. * - * \sa mood_open(), mood_close(). + * If no mood is currently open, the function returns success. */ static int reload_current_mood(void) { diff --git a/mp3_afh.c b/mp3_afh.c index e5d0ff13..08837bec 100644 --- a/mp3_afh.c +++ b/mp3_afh.c @@ -690,7 +690,7 @@ static const char * const mp3_suffixes[] = {"mp3", NULL}; * * \param afh pointer to the struct to initialize */ -void mp3_init(struct audio_format_handler *afh) +void mp3_afh_init(struct audio_format_handler *afh) { afh->get_file_info = mp3_get_file_info; afh->suffixes = mp3_suffixes; diff --git a/net.c b/net.c index 50243673..a58d84ef 100644 --- a/net.c +++ b/net.c @@ -44,7 +44,7 @@ * default of 32 if not specified. * * \return Pointer to \a addr if successful, NULL on error. - * \sa RFC 4632 + * \sa RFC 4632. */ char *parse_cidr(const char *cidr, char *addr, ssize_t addrlen, @@ -104,7 +104,7 @@ static bool is_v4_dot_quad(const char *address) * \param host The host string to check. * \return True if \a host passes the syntax checks. * - * \sa RFC 3986, 3.2.2; RFC 1123, 2.1; RFC 1034, 3.5 + * \sa RFC 3986, 3.2.2; RFC 1123, 2.1; RFC 1034, 3.5. */ static bool host_string_ok(const char *host) { @@ -146,7 +146,7 @@ static bool host_string_ok(const char *host) * \a host and \a port are undefined. If no port number was present in \a url, * \a port is set to -1. * - * \sa RFC 3986, 3.2.2/3.2.3 + * \sa RFC 3986, 3.2.2/3.2.3. */ char *parse_url(const char *url, char *host, ssize_t hostlen, @@ -191,7 +191,7 @@ failed: * \param transport Transport protocol name (e.g. "udp", "tcp"), or NULL. * \return Pointer to static result buffer. * - * \sa getservent(3), services(5), nsswitch.conf(5) + * \sa getservent(3), services(5), nsswitch.conf(5). */ const char *stringify_port(int port, const char *transport) { @@ -215,7 +215,7 @@ const char *stringify_port(int port, const char *transport) * * \param l4type The symbolic name of the transport-layer protocol. * - * \sa ip(7), socket(2) + * \sa ip(7), socket(2). */ static inline int sock_type(const unsigned l4type) { @@ -247,7 +247,7 @@ static const char *layer4_name(const unsigned l4type) * directly after makesock(). The 'pre_conn_opt' structure is for internal use * only and should not be visible elsewhere. * - * \sa setsockopt(2), makesock() + * \sa setsockopt(2), \ref makesock(). */ struct pre_conn_opt { int sock_level; /**< Second argument to setsockopt() */ @@ -288,7 +288,7 @@ struct flowopts *flowopt_new(void) * \param val The value to set \a opt to. * \param len Length of \a val. * - * \sa setsockopt(2) + * \sa setsockopt(2). */ void flowopt_add(struct flowopts *fo, int lev, int opt, const char *name, const void *val, int len) @@ -505,7 +505,7 @@ int makesock(unsigned l4type, bool passive, const char *host, uint16_t port_numb * \return Positive integer (socket descriptor) on success, negative value * otherwise. * - * \sa makesock(), ip(7), ipv6(7), bind(2), listen(2). + * \sa \ref makesock(), ip(7), ipv6(7), bind(2), listen(2). */ int para_listen(unsigned l4type, uint16_t port, struct flowopts *fo) { @@ -551,7 +551,7 @@ static bool SS_IS_ADDR_V4MAPPED(const struct sockaddr_storage *ss) * \param ss Container of IPv4/6 address. * \return Pointer to normalized address (may be static storage). * - * \sa RFC 3493 + * \sa RFC 3493. */ static const struct sockaddr * normalize_ip_address(const struct sockaddr_storage *ss) @@ -624,7 +624,7 @@ int generic_max_transport_msg_size(int sockfd) * \return A static character string identifying hostname and port of the * chosen side in numeric host:port format. * - * \sa getsockname(2), getpeername(2), parse_url(), getnameinfo(3), + * \sa getsockname(2), getpeername(2), \ref parse_url(), getnameinfo(3), * services(5), nsswitch.conf(5). */ char *remote_name(int fd) @@ -735,7 +735,7 @@ __must_check int recv_bin_buffer(int fd, char *buf, size_t size) * * \return The return value of the underlying call to \a recv_bin_buffer(). * - * \sa recv_bin_buffer() + * \sa \ref recv_bin_buffer() */ int recv_buffer(int fd, char *buf, size_t size) { @@ -914,7 +914,7 @@ err: * \return The file descriptor of the connected socket on success, negative on * errors. * - * \sa create_local_socket(), unix(7), connect(2). + * \sa \ref create_local_socket(), unix(7), connect(2). */ int connect_local_socket(const char *name) { @@ -956,8 +956,7 @@ int recv_cred_buffer(int fd, char *buf, size_t size) * \return On success, this call returns the number of bytes sent. On errors, * \p -E_SENDMSG is returned. * - * \sa \ref recv_cred_buffer, sendmsg(2), socket(7), unix(7), okir's Black Hats - * Manual. + * \sa \ref recv_cred_buffer, sendmsg(2), socket(7), unix(7). */ ssize_t send_cred_buffer(int sock, char *buf) { diff --git a/net.h b/net.h index a70954a9..a8dd650b 100644 --- a/net.h +++ b/net.h @@ -93,7 +93,7 @@ _static_inline_ bool is_valid_ipv4_address(const char *address) * \param address The address string to check. * * \return 1 if string has a valid IPv6 address syntax, 0 if not. - * \sa RFC 4291 + * \sa RFC 4291. */ _static_inline_ bool is_valid_ipv6_address(const char *address) { diff --git a/ogg_afh.c b/ogg_afh.c index 2ddf0ee3..cb0611e0 100644 --- a/ogg_afh.c +++ b/ogg_afh.c @@ -212,7 +212,7 @@ static const char * const ogg_suffixes[] = {"ogg", NULL}; * * \param afh Pointer to the struct to initialize. */ -void ogg_init(struct audio_format_handler *afh) +void ogg_afh_init(struct audio_format_handler *afh) { afh->get_file_info = ogg_vorbis_get_file_info; afh->get_header = vorbis_get_header; diff --git a/play.c b/play.c index 4bd32a67..2155ebf8 100644 --- a/play.c +++ b/play.c @@ -8,7 +8,6 @@ #include #include -#include #include #include "recv_cmd.lsg.h" @@ -86,7 +85,7 @@ struct play_task { struct filter_node fn; struct writer_node wn; - /* See comment to enum state_change_request_type above */ + /* See comment to enum \ref state_change_request_type above. */ enum state_change_request_type rq; /* only relevant if rq == CRT_FILE_CHANGE */ unsigned next_file; @@ -109,8 +108,7 @@ struct play_task { char *afhi_txt; }; -typedef int (*play_cmd_handler_t)(struct play_task *pt, - struct lls_parse_result *lpr); +typedef int (*play_cmd_handler_t)(struct lls_parse_result *lpr); struct play_command_info { play_cmd_handler_t handler; }; @@ -127,7 +125,7 @@ INIT_STDERR_LOGGING(loglevel); char *stat_item_values[NUM_STAT_ITEMS] = {NULL}; static struct sched sched = {.max_fileno = 0}; -static struct play_task play_task; +static struct play_task play_task, *pt = &play_task; #define AFH_RECV_CMD (lls_cmd(LSG_RECV_CMD_CMD_AFH, recv_cmd_suite)) #define AFH_RECV ((struct receiver *)lls_user_data(AFH_RECV_CMD)) @@ -228,7 +226,7 @@ fail: exit(EXIT_FAILURE); } -static char get_playback_state(struct play_task *pt) +static char get_playback_state(void) { switch (pt->rq) { case CRT_NONE: return pt->playing? 'P' : 'U'; @@ -239,9 +237,9 @@ static char get_playback_state(struct play_task *pt) assert(false); }; -static long unsigned get_play_time(struct play_task *pt) +static long unsigned get_play_time(void) { - char state = get_playback_state(pt); + char state = get_playback_state(); long unsigned result; if (state != 'P' && state != 'U') @@ -263,7 +261,7 @@ static long unsigned get_play_time(struct play_task *pt) } -static void wipe_receiver_node(struct play_task *pt) +static void wipe_receiver_node(void) { PARA_NOTICE_LOG("cleaning up receiver node\n"); btr_remove_node(&pt->rn.btrn); @@ -273,7 +271,7 @@ static void wipe_receiver_node(struct play_task *pt) } /* returns: 0 not eof, 1: eof, < 0: fatal error. */ -static int get_playback_error(struct play_task *pt) +static int get_playback_error(void) { int err; @@ -292,13 +290,13 @@ static int get_playback_error(struct play_task *pt) return err; } -static int eof_cleanup(struct play_task *pt) +static int eof_cleanup(void) { const struct filter *decoder; const struct writer *w = writer_get(-1); /* default writer */ int ret; - ret = get_playback_error(pt); + ret = get_playback_error(); if (ret == 0) return ret; PARA_NOTICE_LOG("cleaning up wn/fn nodes\n"); @@ -324,7 +322,7 @@ static int eof_cleanup(struct play_task *pt) * paused. */ if (ret < 0) - wipe_receiver_node(pt); + wipe_receiver_node(); return ret; } @@ -352,7 +350,7 @@ static struct btr_node *new_recv_btrn(struct receiver_node *rn) .handler = AFH_RECV->execute)); } -static int open_new_file(struct play_task *pt) +static int open_new_file(void) { int ret; const char *path = get_playlist_file(pt->next_file); @@ -360,7 +358,7 @@ static int open_new_file(struct play_task *pt) char *argv[] = {"play", "-f", tmp, "-b", "0", NULL}; PARA_NOTICE_LOG("next file: %s\n", path); - wipe_receiver_node(pt); + wipe_receiver_node(); pt->start_chunk = 0; pt->rn.btrn = new_recv_btrn(&pt->rn); ret = lls(lls_parse(ARRAY_SIZE(argv) - 1, argv, AFH_RECV_CMD, @@ -400,11 +398,11 @@ static int open_new_file(struct play_task *pt) } return 1; fail: - wipe_receiver_node(pt); + wipe_receiver_node(); return ret; } -static int load_file(struct play_task *pt) +static int load_file(void) { const char *af; char *tmp, buf[20]; @@ -414,7 +412,7 @@ static int load_file(struct play_task *pt) btr_remove_node(&pt->rn.btrn); if (!pt->rn.receiver || pt->next_file != pt->current_file) { - ret = open_new_file(pt); + ret = open_new_file(); if (ret < 0) return ret; } else { @@ -468,11 +466,11 @@ static int load_file(struct play_task *pt) register_writer_node(&pt->wn, pt->fn.btrn, &sched); return 1; fail: - wipe_receiver_node(pt); + wipe_receiver_node(); return ret; } -static int next_valid_file(struct play_task *pt) +static int next_valid_file(void) { int i, j = pt->current_file; unsigned num_inputs = lls_num_inputs(play_lpr); @@ -485,20 +483,20 @@ static int next_valid_file(struct play_task *pt) return -E_NO_VALID_FILES; } -static int load_next_file(struct play_task *pt) +static int load_next_file(void) { int ret; again: if (pt->rq == CRT_NONE) { pt->start_chunk = 0; - ret = next_valid_file(pt); + ret = next_valid_file(); if (ret < 0) return ret; pt->next_file = ret; } else if (pt->rq == CRT_REPOS) pt->next_file = pt->current_file; - ret = load_file(pt); + ret = load_file(); if (ret < 0) { PARA_ERROR_LOG("%s: marking file as invalid\n", para_strerror(-ret)); @@ -511,7 +509,7 @@ again: return ret; } -static void kill_stream(struct play_task *pt) +static void kill_stream(void) { if (pt->wn.task) task_notify(pt->wn.task, E_EOF); @@ -520,7 +518,7 @@ static void kill_stream(struct play_task *pt) #ifdef HAVE_READLINE /* only called from com_prev(), nec. only if we have readline */ -static int previous_valid_file(struct play_task *pt) +static int previous_valid_file(void) { int i, j = pt->current_file; unsigned num_inputs = lls_num_inputs(play_lpr); @@ -720,7 +718,6 @@ static void help_completer(struct i9e_completion_info *ci, result->matches = i9e_complete_commands(ci->word, pp_completers); } -I9E_DUMMY_COMPLETER(SUPERCOMMAND_UNAVAILABLE); static struct i9e_completer pp_completers[] = { #define LSG_PLAY_CMD_CMD(_name) {.name = #_name, \ .completer = _name ## _completer} @@ -729,7 +726,7 @@ static struct i9e_completer pp_completers[] = { {.name = NULL} }; -static void attach_stdout(struct play_task *pt, const char *name) +static void attach_stdout(const char *name) { if (pt->btrn) return; @@ -738,20 +735,19 @@ static void attach_stdout(struct play_task *pt, const char *name) i9e_attach_to_stdout(pt->btrn); } -static void detach_stdout(struct play_task *pt) +static void detach_stdout(void) { btr_remove_node(&pt->btrn); } -static int com_quit(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_quit(__a_unused struct lls_parse_result *lpr) { pt->rq = CRT_TERM_RQ; return 0; } EXPORT_PLAY_CMD_HANDLER(quit); -static int com_help(struct play_task *pt, struct lls_parse_result *lpr) +static int com_help(struct lls_parse_result *lpr) { int i, ret; char *buf, *errctx; @@ -804,8 +800,7 @@ static int com_help(struct play_task *pt, struct lls_parse_result *lpr) } EXPORT_PLAY_CMD_HANDLER(help); -static int com_info(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_info(__a_unused struct lls_parse_result *lpr) { char *buf; size_t sz; @@ -820,7 +815,7 @@ static int com_info(struct play_task *pt, } EXPORT_PLAY_CMD_HANDLER(info); -static void list_file(struct play_task *pt, int num) +static void list_file(int num) { char *buf; size_t sz; @@ -830,8 +825,7 @@ static void list_file(struct play_task *pt, int num) btr_add_output(buf, sz, pt->btrn); } -static int com_tasks(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_tasks(__a_unused struct lls_parse_result *lpr) { static char state; char *buf; @@ -839,26 +833,25 @@ static int com_tasks(struct play_task *pt, buf = get_task_list(&sched); btr_add_output(buf, strlen(buf), pt->btrn); - state = get_playback_state(pt); + state = get_playback_state(); sz = xasprintf(&buf, "state: %c\n", state); btr_add_output(buf, sz, pt->btrn); return 0; } EXPORT_PLAY_CMD_HANDLER(tasks); -static int com_ls(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_ls(__a_unused struct lls_parse_result *lpr) { int i; unsigned num_inputs = lls_num_inputs(play_lpr); for (i = 0; i < num_inputs; i++) - list_file(pt, i); + list_file(i); return 0; } EXPORT_PLAY_CMD_HANDLER(ls); -static int com_play(struct play_task *pt, struct lls_parse_result *lpr) +static int com_play(struct lls_parse_result *lpr) { int32_t x; int ret; @@ -871,7 +864,7 @@ static int com_play(struct play_task *pt, struct lls_parse_result *lpr) free(errctx); return ret; } - state = get_playback_state(pt); + state = get_playback_state(); if (lls_num_inputs(lpr) == 0) { if (state == 'P') return 0; @@ -885,24 +878,23 @@ static int com_play(struct play_task *pt, struct lls_parse_result *lpr) return ret; if (x < 0 || x >= lls_num_inputs(play_lpr)) return -ERRNO_TO_PARA_ERROR(EINVAL); - kill_stream(pt); + kill_stream(); pt->next_file = x; pt->rq = CRT_FILE_CHANGE; return 0; } EXPORT_PLAY_CMD_HANDLER(play); -static int com_pause(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_pause(__a_unused struct lls_parse_result *lpr) { char state; long unsigned seconds, ss; - state = get_playback_state(pt); + state = get_playback_state(); pt->playing = false; if (state != 'P') return 0; - seconds = get_play_time(pt); + seconds = get_play_time(); pt->playing = false; ss = 0; if (pt->seconds > 0) @@ -910,20 +902,19 @@ static int com_pause(struct play_task *pt, ss = PARA_MAX(ss, 0UL); ss = PARA_MIN(ss, pt->num_chunks); pt->start_chunk = ss; - kill_stream(pt); + kill_stream(); return 0; } EXPORT_PLAY_CMD_HANDLER(pause); -static int com_prev(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_prev(__a_unused struct lls_parse_result *lpr) { int ret; - ret = previous_valid_file(pt); + ret = previous_valid_file(); if (ret < 0) return ret; - kill_stream(pt); + kill_stream(); pt->next_file = ret; pt->rq = CRT_FILE_CHANGE; pt->start_chunk = 0; @@ -931,15 +922,14 @@ static int com_prev(struct play_task *pt, } EXPORT_PLAY_CMD_HANDLER(prev); -static int com_next(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_next(__a_unused struct lls_parse_result *lpr) { int ret; - ret = next_valid_file(pt); + ret = next_valid_file(); if (ret < 0) return ret; - kill_stream(pt); + kill_stream(); pt->next_file = ret; pt->rq = CRT_FILE_CHANGE; pt->start_chunk = 0; @@ -947,23 +937,21 @@ static int com_next(struct play_task *pt, } EXPORT_PLAY_CMD_HANDLER(next); -static int com_fg(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_fg(__a_unused struct lls_parse_result *lpr) { pt->background = false; return 0; } EXPORT_PLAY_CMD_HANDLER(fg); -static int com_bg(struct play_task *pt, - __a_unused struct lls_parse_result *lpr) +static int com_bg(__a_unused struct lls_parse_result *lpr) { pt->background = true; return 0; } EXPORT_PLAY_CMD_HANDLER(bg); -static int com_jmp(struct play_task *pt, struct lls_parse_result *lpr) +static int com_jmp(struct lls_parse_result *lpr) { int32_t percent; int ret; @@ -982,19 +970,19 @@ static int com_jmp(struct play_task *pt, struct lls_parse_result *lpr) if (percent < 0 || percent > 100) return -ERRNO_TO_PARA_ERROR(EINVAL); if (percent == 100) - return com_next(pt, NULL); + return com_next(NULL); if (pt->playing && !pt->fn.btrn) return 0; pt->start_chunk = percent * pt->num_chunks / 100; if (!pt->playing) return 0; pt->rq = CRT_REPOS; - kill_stream(pt); + kill_stream(); return 0; } EXPORT_PLAY_CMD_HANDLER(jmp); -static int com_ff(struct play_task *pt, struct lls_parse_result *lpr) +static int com_ff(struct lls_parse_result *lpr) { int32_t seconds; char *errctx; @@ -1012,7 +1000,7 @@ static int com_ff(struct play_task *pt, struct lls_parse_result *lpr) return ret; if (pt->playing && !pt->fn.btrn) return 0; - seconds += get_play_time(pt); + seconds += get_play_time(); seconds = PARA_MIN(seconds, (typeof(seconds))pt->seconds - 4); seconds = PARA_MAX(seconds, 0); pt->start_chunk = pt->num_chunks * seconds / pt->seconds; @@ -1021,12 +1009,12 @@ static int com_ff(struct play_task *pt, struct lls_parse_result *lpr) if (!pt->playing) return 0; pt->rq = CRT_REPOS; - kill_stream(pt); + kill_stream(); return 0; } EXPORT_PLAY_CMD_HANDLER(ff); -static int run_command(char *line, struct play_task *pt) +static int run_command(char *line) { int ret, argc; char **argv = NULL; @@ -1035,7 +1023,7 @@ static int run_command(char *line, struct play_task *pt) struct lls_parse_result *lpr; const struct lls_command *cmd; - attach_stdout(pt, __FUNCTION__); + attach_stdout(__FUNCTION__); ret = create_argv(line, " ", &argv); if (ret < 0) goto out; @@ -1050,7 +1038,7 @@ static int run_command(char *line, struct play_task *pt) if (ret < 0) goto out; pci = lls_user_data(cmd); - ret = pci->handler(pt, lpr); + ret = pci->handler(lpr); lls_free_parse_result(lpr, cmd); out: if (errctx) @@ -1062,12 +1050,11 @@ out: static int play_i9e_line_handler(char *line) { - return run_command(line, &play_task); + return run_command(line); } static int play_i9e_key_handler(int key) { - struct play_task *pt = &play_task; int idx = get_key_map_idx(key); char *seq = get_key_map_seq(key); char *cmd = get_key_map_cmd(key); @@ -1076,7 +1063,7 @@ static int play_i9e_key_handler(int key) PARA_NOTICE_LOG("pressed %d: %s key #%d (%s -> %s)\n", key, internal? "internal" : "user-defined", idx, seq, cmd); - run_command(cmd, pt); + run_command(cmd); free(seq); free(cmd); pt->next_update = *now; @@ -1093,7 +1080,7 @@ static struct i9e_client_info ici = { static void sigint_handler(int sig) { - play_task.background = true; + pt->background = true; i9e_signal_dispatch(sig); } @@ -1102,7 +1089,7 @@ static void sigint_handler(int sig) * stderr. Once the i9e subsystem has been initialized, we switch to the i9e * log facility. */ -static void session_open(struct play_task *pt) +static void session_open(void) { int ret; char *history_file; @@ -1146,7 +1133,7 @@ out: exit(EXIT_FAILURE); } -static void session_update_time_string(struct play_task *pt, char *str, unsigned len) +static void session_update_time_string(char *str, unsigned len) { if (pt->background) return; @@ -1171,30 +1158,30 @@ static void session_update_time_string(struct play_task *pt, char *str, unsigned * terminates. Subsequent calls to i9e_get_error() then return negative and we * are allowed to call i9e_close() and terminate as well. */ -static int session_post_select(__a_unused struct sched *s, struct play_task *pt) +static int session_post_select(__a_unused struct sched *s) { int ret; if (pt->background) - detach_stdout(pt); + detach_stdout(); else - attach_stdout(pt, __FUNCTION__); + attach_stdout(__FUNCTION__); ret = i9e_get_error(); if (ret < 0) { - kill_stream(pt); + kill_stream(); i9e_close(); para_log = stderr_log; free(ici.history_file); return ret; } - if (get_playback_state(pt) == 'X') + if (get_playback_state() == 'X') i9e_signal_dispatch(SIGTERM); return 0; } #else /* HAVE_READLINE */ -static int session_post_select(struct sched *s, struct play_task *pt) +static int session_post_select(struct sched *s) { char c; @@ -1202,38 +1189,36 @@ static int session_post_select(struct sched *s, struct play_task *pt) return 0; if (read(STDIN_FILENO, &c, 1)) do_nothing; - kill_stream(pt); + kill_stream(); return 1; } -static void session_open(__a_unused struct play_task *pt) +static void session_open(void) { } -static void session_update_time_string(__a_unused struct play_task *pt, - char *str, __a_unused unsigned len) +static void session_update_time_string(char *str, __a_unused unsigned len) { printf("\r%s ", str); fflush(stdout); } #endif /* HAVE_READLINE */ -static void play_pre_select(struct sched *s, void *context) +static void play_pre_select(struct sched *s, __a_unused void *context) { - struct play_task *pt = context; char state; para_fd_set(STDIN_FILENO, &s->rfds, &s->max_fileno); - state = get_playback_state(pt); + state = get_playback_state(); if (state == 'R' || state == 'F' || state == 'X') return sched_min_delay(s); sched_request_barrier_or_min_delay(&pt->next_update, s); } -static unsigned get_time_string(struct play_task *pt, char **result) +static unsigned get_time_string(char **result) { int seconds, length; - char state = get_playback_state(pt); + char state = get_playback_state(); /* do not return anything if things are about to change */ if (state != 'P' && state != 'U') { @@ -1243,7 +1228,7 @@ static unsigned get_time_string(struct play_task *pt, char **result) length = pt->seconds; if (length == 0) return xasprintf(result, "0:00 [0:00] (0%%/0:00)"); - seconds = get_play_time(pt); + seconds = get_play_time(); return xasprintf(result, "#%u: %d:%02d [%d:%02d] (%d%%/%d:%02d) %s", pt->current_file, seconds / 60, @@ -1257,24 +1242,23 @@ static unsigned get_time_string(struct play_task *pt, char **result) ); } -static int play_post_select(struct sched *s, void *context) +static int play_post_select(struct sched *s, __a_unused void *context) { - struct play_task *pt = context; int ret; - ret = eof_cleanup(pt); + ret = eof_cleanup(); if (ret < 0) { pt->rq = CRT_TERM_RQ; return 0; } - ret = session_post_select(s, pt); + ret = session_post_select(s); if (ret < 0) goto out; if (!pt->wn.btrn && !pt->fn.btrn) { - char state = get_playback_state(pt); + char state = get_playback_state(); if (state == 'P' || state == 'R' || state == 'F') { PARA_NOTICE_LOG("state: %c\n", state); - ret = load_next_file(pt); + ret = load_next_file(); if (ret < 0) { PARA_ERROR_LOG("%s\n", para_strerror(-ret)); pt->rq = CRT_TERM_RQ; @@ -1286,10 +1270,10 @@ static int play_post_select(struct sched *s, void *context) } if (tv_diff(now, &pt->next_update, NULL) >= 0) { char *str; - unsigned len = get_time_string(pt, &str); + unsigned len = get_time_string(&str); struct timeval delay = {.tv_sec = 0, .tv_usec = 100 * 1000}; if (str && len > 0) - session_update_time_string(pt, str, len); + session_update_time_string(str, len); free(str); tv_add(now, &delay, &pt->next_update); } @@ -1309,7 +1293,6 @@ out: int main(int argc, char *argv[]) { int ret; - struct play_task *pt = &play_task; unsigned num_inputs; /* needed this early to make help work */ @@ -1318,7 +1301,7 @@ int main(int argc, char *argv[]) sched.default_timeout.tv_sec = 5; parse_config_or_die(argc, argv); AFH_RECV->init(); - session_open(pt); + session_open(); num_inputs = lls_num_inputs(play_lpr); init_shuffle_map(); pt->invalid = para_calloc(sizeof(*pt->invalid) * num_inputs); diff --git a/playlist.c b/playlist.c index b9e52c75..55a83436 100644 --- a/playlist.c +++ b/playlist.c @@ -140,7 +140,7 @@ int playlist_check_callback(struct afs_callback_arg *aca) /** * Close the current playlist. * - * \sa playlist_open(). + * \sa \ref playlist_open(). */ void playlist_close(void) { diff --git a/recv.c b/recv.c index 9842c7dc..26aa7fd7 100644 --- a/recv.c +++ b/recv.c @@ -8,7 +8,6 @@ #include #include -#include #include #include "recv_cmd.lsg.h" diff --git a/recv.h b/recv.h index 68978a38..6fb70b9a 100644 --- a/recv.h +++ b/recv.h @@ -40,27 +40,23 @@ struct receiver_node { /** * Describes one supported paraslash receiver. * - * \sa http_recv.c, udp_recv.c + * \sa \ref http_recv.c, \ref udp_recv.c. */ struct receiver { /** * The optional receiver init function. * * Performs any initialization needed before the receiver can be opened. - * - * \sa http_recv_init udp_recv_init. */ void (*init)(void); /** * Open one instance of the receiver. * - * This should allocate the output buffer of \a rn. and may also - * perform any other work necessary for retrieving the stream according - * to the configuration stored in the \a conf member of \a rn which is - * guaranteed to point to valid configuration data (as previously - * obtained from the config parser). + * This should allocate the output buffer of the given receiver node + * and prepare it for retrieving the audio stream according to the + * configuration stored in rn->lpr. * - * \sa receiver_node::conf, receiver_node::buf. + * \sa struct \ref receiver_node. */ int (*open)(struct receiver_node *rn); /** @@ -69,37 +65,38 @@ struct receiver { * It should free all resources associated with given receiver node * that were allocated during the corresponding open call. * - * \sa receiver_node. + * \sa \ref receiver_node. */ void (*close)(struct receiver_node *rn); /** * Add file descriptors to fd_sets and compute timeout for select(2). * - * The pre_select function gets called from the driving application - * before entering its select loop. The receiver may use this hook to - * add any file descriptors to the sets of file descriptors given by \a - * s. + * If this is not NULL, the function is called in each iteration of the + * scheduler's select loop. The receiver may define it to add file + * descriptors to the file descriptor sets given by s. Those will be + * monitored in the subsequent call to select(2). The function may also + * lower the timeout value of s to make select(2) return earlier if no + * file descriptors are ready for I/O. * - * \sa select(2), time.c struct task, struct sched. + * \sa select(2), \ref time.c, struct \ref sched. */ void (*pre_select)(struct sched *s, void *context); /** - * Evaluate the result from select(). + * Evaluate the result from select(2). * - * This hook gets called after the call to select(). It should check - * all file descriptors which were added to any of the fd sets during - * the previous call to pre_select. According to the result, it may - * then use any non-blocking I/O to establish a connection or to - * receive the audio data. + * This is called after the call to select(2). It should check all file + * descriptors which were added to any of the fd sets in the previous + * call to ->pre_select() and perform (non-blocking) I/O operations on + * those fds which are ready for I/O, for example in order to establish + * a connection or to receive a part of the audio stream. * - * \sa select(2), struct receiver. + * \sa select(2), struct \ref receiver. */ int (*post_select)(struct sched *s, void *context); - /** * Answer a buffer tree query. * - * This optional function pointer is used for inter node communications + * This optional function pointer allows for inter node communication * of the buffer tree nodes. See \ref btr_command_handler for details. */ btr_command_handler execute; diff --git a/recv_common.c b/recv_common.c index d48b3476..1ad84438 100644 --- a/recv_common.c +++ b/recv_common.c @@ -21,6 +21,12 @@ /** * Call the init function of each paraslash receiver. + * + * Receivers employ the user_data feature of the lopsub library: Each receiver + * of the recv_cmd suite defines a struct receiver as its user data. + * recv_init() obtains a pointer to this structure by calling lls_user_data(). + * If the receiver has an init function (i.e., if ->init is not NULL), ->init() + * is called to initialize the receiver. */ void recv_init(void) { diff --git a/sched.c b/sched.c index bc301778..297348a1 100644 --- a/sched.c +++ b/sched.c @@ -387,7 +387,7 @@ void sched_min_delay(struct sched *s) * function does nothing. Otherwise the timeout for the next select() call is * set to the given value. * - * \sa sched_request_timeout_ms(). + * \sa \ref sched_request_timeout_ms(). */ void sched_request_timeout(struct timeval *to, struct sched *s) { @@ -420,7 +420,7 @@ void sched_request_timeout_ms(long unsigned ms, struct sched *s) * \return If \a barrier is in the past, this function does nothing and returns * zero. Otherwise it returns one. * - * \sa sched_request_barrier_or_min_delay(). + * \sa \ref sched_request_barrier_or_min_delay(). */ int sched_request_barrier(struct timeval *barrier, struct sched *s) { @@ -441,7 +441,7 @@ int sched_request_barrier(struct timeval *barrier, struct sched *s) * \return If \a barrier is in the past, this function requests a minimal * timeout and returns zero. Otherwise it returns one. * - * \sa sched_min_delay(), sched_request_barrier(). + * \sa \ref sched_min_delay(), \ref sched_request_barrier(). */ int sched_request_barrier_or_min_delay(struct timeval *barrier, struct sched *s) { diff --git a/score.c b/score.c index ddd3c7a2..30761e75 100644 --- a/score.c +++ b/score.c @@ -34,8 +34,6 @@ static int ptr_compare(const struct osl_object *obj1, const struct osl_object *o * This function first compares the score values as usual integers. If they compare as * equal, the address of \a obj1 and \a obj2 are compared. So this compare function * returns zero if and only if \a obj1 and \a obj2 point to the same memory area. - * - * \sa osl_compare_function. */ static int score_compare(const struct osl_object *obj1, const struct osl_object *obj2) { @@ -92,8 +90,6 @@ static struct osl_table_description score_table_desc = { * \param num Result is returned here. * * \return Positive on success, negative on errors. - * - * \sa osl_get_num_rows(). */ int get_num_admissible_files(unsigned *num) { @@ -284,7 +280,7 @@ int score_get_best(struct osl_row **aft_row, long *score) * \return Positive on success, negative on errors. Possible errors: * Errors returned by osl_get_row() and osl_del_row(). * - * \sa score_add(), score_shutdown(). + * \sa \ref score_add(). */ int score_delete(const struct osl_row *aft_row) { diff --git a/send.h b/send.h index 54205234..b70ba094 100644 --- a/send.h +++ b/send.h @@ -25,7 +25,7 @@ enum sender_subcommand { /** * Describes one supported sender of para_server. * - * \sa http_send.c udp_send.c, dccp_send.c. + * \sa \ref http_send.c \ref udp_send.c, \ref dccp_send.c. */ struct sender { /** The name of the sender. */ diff --git a/send_common.c b/send_common.c index 988e8d48..b03be877 100644 --- a/send_common.c +++ b/send_common.c @@ -72,7 +72,7 @@ static int open_sender(unsigned l4type, int port) * list, destroy the chunk queue of this client, delete the client from the * list of connected clients and free the sender_client struct. * - * \sa shutdown_clients(). + * \sa \ref shutdown_clients(). */ void shutdown_client(struct sender_client *sc, struct sender_status *ss) { @@ -212,7 +212,7 @@ char *generic_sender_status(struct sender_status *ss, const char *name) * \param scd Contains the IP and the netmask. * \param ss The sender. * - * \sa generic_com_deny(). + * \sa \ref generic_com_deny(). */ void generic_com_allow(struct sender_command_data *scd, struct sender_status *ss) @@ -226,7 +226,7 @@ void generic_com_allow(struct sender_command_data *scd, * \param scd see \ref generic_com_allow(). * \param ss see \ref generic_com_allow(). * - * \sa generic_com_allow(). + * \sa \ref generic_com_allow(). */ void generic_com_deny(struct sender_command_data *scd, struct sender_status *ss) @@ -262,7 +262,7 @@ int generic_com_on(struct sender_status *ss, unsigned protocol) * * \param ss The sender to deactivate. * - * \sa \ref del_close_on_fork_list(), shutdown_clients(). + * \sa \ref del_close_on_fork_list(), \ref shutdown_clients(). */ void generic_com_off(struct sender_status *ss) { diff --git a/stdout.c b/stdout.c index 29db2b7e..43e194db 100644 --- a/stdout.c +++ b/stdout.c @@ -89,7 +89,7 @@ void stdout_task_register(struct stdout_task *sot, struct sched *s) .name = "stdout", }; - /* See stdin.c for details. */ + /* See \ref stdin.c for details. */ ret = fcntl(STDOUT_FILENO, F_GETFL); if (ret < 0) { PARA_EMERG_LOG("F_GETFL: %s\n", strerror(errno)); diff --git a/string.c b/string.c index 6033a008..e675502c 100644 --- a/string.c +++ b/string.c @@ -10,7 +10,6 @@ #include #include /* uname() */ -#include #include #include #include @@ -190,7 +189,7 @@ __printf_2_3 unsigned xasprintf(char **result, const char *fmt, ...) * \return This function either returns a pointer to a string that must be * freed by the caller or aborts without returning. * - * \sa printf(3), xasprintf(). + * \sa printf(3), \ref xasprintf(). */ __must_check __printf_1_2 __malloc char *make_message(const char *fmt, ...) { @@ -230,7 +229,7 @@ void freep(void *arg) * return \a a without making a copy of \a a. Otherwise, construct the * concatenation \a c, free \a a (but not \a b) and return \a c. * - * \sa strcat(3) + * \sa strcat(3). */ __must_check __malloc char *para_strcat(char *a, const char *b) { @@ -548,7 +547,7 @@ __printf_2_3 int para_printf(struct para_buffer *b, const char *fmt, ...) * * \return Standard. * - * \sa para_atoi32(), strtol(3), atoi(3). + * \sa \ref para_atoi32(), strtol(3), atoi(3). */ int para_atoi64(const char *str, int64_t *value) { @@ -585,7 +584,7 @@ int para_atoi64(const char *str, int64_t *value) * * \return Standard. * - * \sa para_atoi64(). + * \sa \ref para_atoi64(). */ int para_atoi32(const char *str, int32_t *value) { diff --git a/string.h b/string.h index 52f98941..93bb6cba 100644 --- a/string.h +++ b/string.h @@ -20,7 +20,7 @@ struct para_buffer { size_t size; /** The maximal size this buffer may grow. Zero means unlimited. */ size_t max_size; - /** \sa para_buffer_flags. */ + /** \sa \ref para_buffer_flags. */ unsigned flags; /** The next para_printf() will write at this offset. */ size_t offset; @@ -37,7 +37,7 @@ struct para_buffer { /** * Controls the behavior of for_each_line(). * - * \sa for_each_line(). + * \sa \ref for_each_line(). */ enum for_each_line_flags { /** Activate read-only mode. */ diff --git a/t/t0004-server.sh b/t/t0004-server.sh index 5329ef0f..6a8e5bf1 100755 --- a/t/t0004-server.sh +++ b/t/t0004-server.sh @@ -69,7 +69,7 @@ bad[$i]='.' let i++ commands[$i]="ls" required_objects[$i]='ogg_afh' -cmdline[$i]="ls -l=v -F ${oggs[@]}" +cmdline[$i]="ls -l=v ${oggs[@]}" good[$i]='^attributes_txt: 33' let i++ diff --git a/udp_recv.c b/udp_recv.c index a5dfc879..4620d61a 100644 --- a/udp_recv.c +++ b/udp_recv.c @@ -190,6 +190,7 @@ err: return ret; } +/** See \ref recv_init(). */ const struct receiver lsg_recv_cmd_com_udp_user_data = { .open = udp_recv_open, .close = udp_recv_close, diff --git a/udp_send.c b/udp_send.c index 8c9eebc9..0ea95e41 100644 --- a/udp_send.c +++ b/udp_send.c @@ -65,8 +65,9 @@ static void udp_close_target(struct sender_client *sc) PARA_NOTICE_LOG("sending FEC EOF\n"); len = vss_get_fec_eof_packet(&buf); /* Ignore write() errors since we are closing the target anyway. */ - if (write(sc->fd, buf, len) == len) - ut->sent_fec_eof = true; + if (write(sc->fd, buf, len)) + do_nothing; /* avoid "ignoring return value" warning */ + ut->sent_fec_eof = true; } static void udp_delete_target(struct sender_client *sc, const char *msg) diff --git a/vss.c b/vss.c index 3632cf54..4a1db40d 100644 --- a/vss.c +++ b/vss.c @@ -1046,9 +1046,9 @@ static void vss_send(struct vss_task *vsst) continue; PARA_DEBUG_LOG("sending %u:%u (%u bytes)\n", fc->group.num, fc->current_slice_num, fc->group.slice_bytes); + fc->current_slice_num++; fc->fcp->send_fec(fc->sc, (char *)fc->enc_buf, fc->group.slice_bytes + FEC_HEADER_SIZE); - fc->current_slice_num++; fec_active = 1; } if (mmd->current_chunk >= mmd->afd.afhi.chunks_total) { /* eof */ diff --git a/web/dia/overview.dia b/web/dia/overview.dia deleted file mode 100644 index f9e01586..00000000 --- a/web/dia/overview.dia +++ /dev/null @@ -1,3817 +0,0 @@ - - - - - - - - - - - - - #A4# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Overview# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_server# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Incoming connections arrive via TCP at the dispatcher which creates a -command handler process for each connection. - -After the connecting client has been authenticated, the command -handler propagates the incoming request either to the audio file -selector (afs) or to the virtual streaming system (vss). Results are sent -back to the client. - -afs maintans the audio file database and is responsible for selecting -and loading audio files while vss controls the paraslash senders. When -vss needs to stream an audio file it requests an open file descriptor from -afs and feeds small chunks of data (e.g. mp3 frames) to the senders -which send the chunks to all connected clients.# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #dispatcher# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #senders# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #vss# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #command -handler# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #afs# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_server# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_audiod# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_audioc# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_gui# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_client# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #The two main applications of the paraslash suite (shaded green) are -para_server and para_audiod. Both run in the background usually. -para_server maintains the audio file database and acts as the streaming -source, while para_audiod is the streaming client. - -The two client programs, para_client and para_audioc communicate -with para_server and para_audiod, respectively. - -para_gui controls para_server/audiod by executing paraslash commands. -Command output is shown in a curses window. para_gui automatically -executes para_audioc to obtain the state of para_audiod and para_server -and the metadata of the current audio file. - -Network connections are shaded grey, local connections black.# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_audiod# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #The purpose of para_audiod is to download, decode and play an audio -stream received from para_server. It fetches the para_server status and -starts a suitable buffer tree (shaded blue) if an audio stream is available. - -The buffer tree usually consists of a receiver, any number of filters and -a writer. The receiver downloads the audio stream from para_server and -the filters decode or modify the received data. The writer plays the -decoded stream. - -The dispatcher acts on (local) requests from para_audioc, for example to -dump information about the current audio file.# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #The audio file selector (afs) accepts two different kinds of incoming -connections: A bidirectional pipe shared with para_server is used for -passing the file descriptor of the current audio file to the server -process. The local socket is used by command handlers which query -or update the database. - -To add a new file to the database, afs opens the file and locates an -audio format handler (afh) that recognizes the file. A new database -entry with metadata obtained from the afh is then added to the -database.# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #The audio file selector# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #audio files# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_server# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #afh# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #osl db# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #command handler# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #afs# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #The OSL database# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Metadata about all known audio files is stored in serveral tables of a -database which is driven by libosl, the object storage layer library. - -The "audio files" table is the main table of the database. It contains -path, hash and metadata of each known file. - -The "attributes" table maps each of the 64 possible attributes to a -string. The attribute value of the file's metadata is translated through -this table. - -The tables shown shaded are blob tables which support add, rm, mv, -cat, ls commands. All of these are optional. - -The "score" table describes the subset of admissible files for the -current playlist or mood. This table is created on demand, resides -only in memory and is discarded on exit. - -When the next audio file is to be streamed, the audio file selector gets -the entry with the highest score from the "score" table, obtains path, -hash, and metadata for this entry from the "audio files" table, opens -the path and verifies the hash.# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #audio files# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #playlists# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #images# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #attributes# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #lyrics# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #moods# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #score# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #dispatcher# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #status fetcher# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_server# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #receiver# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #filter1# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #filter 2# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #writer# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #para_audioc# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/web/documentation.in.html b/web/documentation.in.html index 9e8b59ce..d6d690a1 100644 --- a/web/documentation.in.html +++ b/web/documentation.in.html @@ -5,12 +5,6 @@

General information

    -
  • overview.pdf, - - a pdf file containing a sketch which illustrates how - the pieces of paraslash work together. - -
  • user manual, Installation, Configuration and Usage.
  • diff --git a/web/manual.md b/web/manual.md index 5216c6b5..96d724c9 100644 --- a/web/manual.md +++ b/web/manual.md @@ -12,81 +12,143 @@ paraslash executable. Introduction ============ -In this chapter we give an [overview](#Overview) of the interactions of -the two main programs contained in the paraslash package, followed by +In this chapter we give an [overview](#Overview) of the interactions +of the programs contained in the paraslash package, followed by [brief descriptions](#The.paraslash.executables) of all executables. Overview -------- The core functionality of the para suite is provided by two main -executables, para_server and para_audiod. The former maintains a -database of audio files and streams these files to para_audiod which -receives and plays the stream. - -In a typical setting, both para_server and para_audiod act as -background daemons whose functionality is controlled by client -programs: the para_audioc client controls para_audiod over a local -socket while the para_client program connects to para_server over a -local or remote networking connection. - -Typically, these two daemons run on different hosts but a local setup -is also possible. +applications, para_server and para_audiod. para_server maintains +the audio file database and acts as the streaming source, while +para_audiod is the streaming client. Usually, both run in the +background on different hosts but a local setup is also possible. A simplified picture of a typical setup is as follows - server_host client_host - ~~~~~~~~~~~ ~~~~~~~~~~~ - +-----------+ audio stream +-----------+ - |para_server| -----------------------------> |para_audiod| - +-----------+ +-----------+ - ^ ^ - | | - | | connect - | | - | | - | +-----------+ - | |para_audioc| - | +-----------+ - | - | - | connect +-----------+ - +-------------------------------------- |para_client| - +-----------+ + .____________________. + | ______ | + .-----------------------. | .d########b. | + |.---------------------.| | .d############b | + || || | .d######""####//b. | + || || | 9######( )######P | + || || | 'b######++######d' | + || Screen || | "9############P" | + || || | "9a########P" | + || || | `""""'' | + |`---------------------'| | ________________ | + `-----------------------' | |________________| | + ___) (___ |____________________| + `-._______.-' loudspeaker + | | + | | + | | + .____/ \___. ._____________. ._____/ \_____. + | | | | | | + | para_gui |-----| para_audioc |-----| para_audiod | + |____ ___| |_____________| |_____ _____| + \ / \ / + | | + | | + | | + ._____/ \_____. ._____/ \_____. + | | | | + | para_client |-----------------------| para_server | + |_____________| |_____ _____| + \ / + | + | + .-'"""`-. + ( ) + |`-.___.-'| + | | + |. ' " ` .| + | | + `-.___.-' + Database + +The two client programs, para_client and para_audioc communicate with +para_server and para_audiod, respectively. + +para_gui controls para_server and para_audiod by executing para_client +and para_audioc. In particular, it runs a command to obtain the state +of para_audiod and para_server, and the metadata of the current audio +file. This information is pretty-printed in a curses window. + The paraslash executables ------------------------- -### para_server ### +

    para_server

    para_server streams binary audio data (MP3, ...) over local and/or remote networks. It listens on a TCP port and accepts commands such -as play, stop, pause, next from authenticated clients. There are -many more commands though, see the man page of para_server for a -description of all commands. - -It supports three built-in network streaming protocols -(senders/receivers): HTTP, DCCP, or UDP. This is explained in more -detail in the section on [networking](#Networking). - -The built-in audio file selector of paraslash is used to manage your -audio files. It maintains statistics on the usage of all available -audio files such as last-played time, and the number of times each -file was selected. - -Additional information may be added to the database to allow +as play, stop, pause, next from authenticated clients. The components +of para_server are illustrated in the following diagram: + + ______________________________________________________________________ network + | | | | | + | .-'""""`-. | | | | + | ( ) | | | | + .____/ \_____. |`-.____.-'| .____/ \____/ \____/ \____. | + | | | | | | | + | dispatcher | | database | | senders (http/udp/dccp) | | + |____ _____| | | |___________ ___________| | + \ / |. ' "" ` .| \ / | + | | | | | + | `-.____.-' | | + | | | | + | | | | + | | | | + | ._____/ \_____. .________/ \________. | + | | | | | | + | | audio file |________| virtual streaming | | + | | selector | | system | | + | |_____ _____| |________ ________| | + | \ / \ / | + | | | | + | | | | + | | ._________________. | | + | | | | | | + | `---| command handler |---' | + | |____ ___ ____| | + | \ / \ / | + | | | | + | | | | + | | | | + `-------------------------' `--------------------------' + + +Incoming connections arrive at the dispatcher which creates a process +dedicated to the connection. Its task is to authenticate the client +and to run the command handler which forwards the client request to +either the audio file selector or the virtual streaming system. Results +(if any) are sent back to the client. + +The audio file selector manages audio files using various database +tables. It maintains statistics on the usage of all audio files such as +last-played time and the number of times each file was selected. It +is also responsible for selecting and loading audio files for +streaming. Additional information may be added to the database to allow fine-grained selection based on various properties of the audio file, -including information found in (ID3) tags. However, old-fashioned -playlists are also supported. - -It is also possible to store images (album covers) and lyrics in the -database and associate these to the corresponding audio files. - +including information found in (ID3) tags. Simple playlists are also +supported. It is possible to store images (album covers) and lyrics +in the database and associate these to the corresponding audio files. The section on the [audio file selector](#The.audio.file.selector) -discusses this topic. +discusses this topic in more detail. + +Another component of para_server is the virtual streaming system, +which controls the paraslash senders. During streaming it requests +small chunks of data (e.g., mp3 frames) from the audio file selector +and feeds them to the senders which forward the chunks to connected +clients. +The three senders of para_server correspond to network streaming +protocols based on HTTP, DCCP, or UDP. This is explained in the +section on [networking](#Networking). -### para_client ### +

    para_client

    The client program to connect to para_server. paraslash commands are sent to para_server and the response is dumped to STDOUT. This @@ -101,29 +163,67 @@ If para_client is started without non-option arguments, an interactive session (shell) is started. Command history and command completion are supported through libreadline. -### para_audiod ### - -The local daemon that collects information from para_server. - -It runs on the client side and connects to para_server. As soon as -para_server announces the availability of an audio stream, para_audiod -starts an appropriate receiver, any number of filters and a paraslash -writer to play the stream. - -Moreover, para_audiod listens on a local socket and sends status -information about para_server and para_audiod to local clients on -request. Access via this local socket may be restricted by using Unix -socket credentials, if available. - - -### para_audioc ### +

    para_audiod

    + +The purpose of para_audiod is to download, decode and play an audio +stream received from para_server. A typical setup looks as follows. + + + .----------------------------. + | | + | | + ._____/ \_____. .___/ \____. + | | .----------| | + | para_server | | .______| receiver | + |_____ ____| | | |___ ____| + \ / | | \ / + | | | | + | | | | + | | | | + ._____/ \_____. | | .___/ \____. + | | | | | | + | status task |-----+ | | filter 1 | + |_____________| | |___ ____| + | \ / + | | .____________________. + | | | ______ | + .____________. | .___/ \____. | .d########b. | + | | | | | | .d############b | + | dispatcher |----------' | filter 2 | | .d######""####//b. | + |_____ ____| |___ ____| | 9######( )######P | + \ / \ / | 'b######++######d' | + | | | "9############P" | + | | | "9a########P" | + ._____/ \_____. .___/ \____. | `""""'' | + | | | | | ________________ | + | para_audioc | | writer |------| |________________| | + |_____________| |__________| |____________________| + + +The status task of para_audiod connects to para_server and runs the +"stat" command to retrieve the current server status. If an audio +stream is available, para_audiod starts a so-called buffer tree to +play the stream. + +The buffer tree consists of a receiver, any number of filters and a +writer. The receiver downloads the audio stream from para_server and +the filters decode or modify the received data. The writer plays the +decoded stream. + +The dispatcher of para_audiod listens on a local socket and runs +audiod commands on behalf of para_audioc. For example, para_gui runs +para_audioc to obtain status information about para_audiod and the +current audio file. Access to the local socket may be restricted by +means of Unix socket credentials. + +

    para_audioc

    The client program which talks to para_audiod. Used to control para_audiod, to receive status info, or to grab the stream at any point of the decoding process. Like para_client, para_audioc supports interactive sessions on systems with libreadline. -### para_recv ### +

    para_recv

    A command line HTTP/DCCP/UDP stream grabber. The http mode is compatible with arbitrary HTTP streaming sources (e.g. icecast). @@ -134,7 +234,7 @@ optionally 'just in time'. This allows to cut an audio file without first decoding it, and it enables third-party software which is unaware of the particular audio format to send complete frames in real time. -### para_filter ### +

    para_filter

    A filter program that reads from STDIN and writes to STDOUT. Like para_recv, this is an atomic building block which can be used to @@ -143,30 +243,33 @@ different functionalities in one tool: decoders for multiple audio formats and a number of processing filters, among these a normalizer for audio volume. -### para_afh ### +

    para_afh

    A small stand-alone program that prints tech info about the given audio file to STDOUT. It can be instructed to print a "chunk table", an array of offsets within the audio file. -### para_write ### +

    para_write

    A modular audio stream writer. It supports a simple file writer output plug-in and optional WAV/raw players for ALSA (Linux) and OSS. para_write can also be used as a stand-alone WAV or raw audio player. -### para_play ### +

    para_play

    -A command line audio player. +A command line audio player which supports the same audio formats as +para_server. It differs from other players in that it has an insert +and a command mode, like the vi editor. Line editing is based on +libreadline, and tab completion and command history are supported. -### para_gui ### +

    para_gui

    Curses-based gui that presents status information obtained in a curses window. Appearance can be customized via themes. para_gui provides key-bindings for the most common server commands and new key-bindings can be added easily. -### para_mixer ### +

    para_mixer

    An alarm clock and volume-fader for OSS and ALSA. @@ -182,8 +285,10 @@ source code and the steps that have to be performed in order to Requirements ------------ -### For the impatient ### +

    For the impatient

    + git clone git://git.tuebingen.mpg.de/lopsub + cd lopsub && make && sudo make install git clone git://git.tuebingen.mpg.de/osl cd osl && make && sudo make install && sudo ldconfig sudo apt-get install autoconf libssl-dev m4 \ @@ -192,16 +297,10 @@ Requirements libasound2-dev libao-dev libreadline-dev libncurses-dev \ libopus-dev -### Detailed description ### +

    Detailed description

    In any case you will need -- [libosl](http://people.tuebingen.mpg.de/maan/osl/). The _object -storage layer_ library is used by para_server. To clone the source -code repository, execute - - git clone git://git.tuebingen.mpg.de/osl - - [lopsub](http://people.tuebingen.mpg.de/maan/lopsub/). The long option parser for subcommands generates the command line and config file parsers for all paraslash executables. Clone the source code @@ -225,6 +324,12 @@ from templates by the m4 macro processor. Optional: +- [libosl](http://people.tuebingen.mpg.de/maan/osl/). The _object +storage layer_ library is used by para_server. To clone the source +code repository, execute + + git clone git://git.tuebingen.mpg.de/osl + - [openssl](http://www.openssl.org/) or [libgcrypt](ftp://ftp.gnupg.org/gcrypt/libgcrypt/). At least one of these two libraries is needed as the backend for cryptographic @@ -311,7 +416,7 @@ to install executables under /usr/local/bin and the man pages under Configuration ------------- -### Create a paraslash user ### +

    Create a paraslash user

    In order to control para_server at runtime you must create a paraslash user. As authentication is based on the RSA crypto system you'll have @@ -355,7 +460,7 @@ Finally, tell para_client to connect to server_host: echo 'hostname server_host' > $conf -### Start para_server ### +

    Start para_server

    For this first try, we'll use the info loglevel to make the output of para_server more verbose. @@ -371,7 +476,7 @@ commands. Open a new shell as bar@client_host and try to retrieve the list of available commands and some server info. Don't proceed if this doesn't work. -### Create and populate the database ### +

    Create and populate the database

    An empty database is created with @@ -399,7 +504,7 @@ You may print the list of all known audio files with para_client ls -### Configure para_audiod ### +

    Configure para_audiod

    We will have to tell para_audiod that it should receive the audio stream from server_host via http: @@ -420,14 +525,6 @@ in which order. Troubleshooting --------------- -If you receive a socket related error on server or audiod startup, -make sure you have write permissions to the /var/paraslash directory: - - sudo chown $LOGNAME /var/paraslash - -Alternatively, use the --afs-socket (para_server) or --socket -(para_audiod) option to specify a different socket pathname. - To identify streaming problems try to receive, decode and play the stream manually using para_recv, para_filter and para_write as follows. For simplicity we assume that you're running Linux/ALSA and that only @@ -569,8 +666,7 @@ execute. The output of para_client help -contains in the third column the permissions needed to execute the -command. +contains the permissions needed to execute the command. It is possible to make para_server reread the user_list file by executing the paraslash "hup" command or by sending SIGHUP to the @@ -596,27 +692,21 @@ The audio file selector paraslash comes with a sophisticated audio file selector (AFS), whose main task is to determine which file to stream next, based on information on the audio files stored in a database. It communicates -also with para_client whenever an AFS command is executed, for example -to answer a database query. +also with para_client via the command handler whenever an AFS command +is executed, for example to answer a database query. -Besides the traditional playlists, AFS supports audio file selection +Besides the simple playlists, AFS supports audio file selection based on _moods_ which act as a filter that limits the set of all -known audio files to those which satisfy certain criteria. It also +known audio files to those which satisfy certain criteria. It also maintains tables containing images (e.g. album cover art) and lyrics that can be associated with one or more audio files. -AFS employs [libosl](http://people.tuebingen.mpg.de/maan/osl/), the -object storage layer library, as the backend library for storing -information on audio files, playlists, etc. This library offers -functionality similar to a relational database, but is much more -lightweight than a full database backend. - In this chapter we sketch the setup of the [AFS process](#The.AFS.process) during server startup and proceed with the description of the [layout](#Database.layout) of the various database tables. The section on [playlists and moods](#Playlists.and.moods) explains these two audio file selection mechanisms in detail -and contains pratical examples. The way [file renames and content +and contains practical examples. The way [file renames and content changes](#File.renames.and.content.changes) are detected is discussed briefly before the [Troubleshooting](#Troubleshooting) section concludes the chapter. @@ -625,25 +715,85 @@ The AFS process --------------- On startup, para_server forks to create the AFS process which opens -the OSL database tables. The server process communicates with the -AFS process via pipes and shared memory. Usually, the AFS process -awakes only briefly whenever the current audio file changes. The AFS -process determines the next audio file, opens it, verifies it has -not been changed since it was added to the database and passes the -open file descriptor to the server process, along with audio file -meta-data such as file name, duration, audio format and so on. The -server process then starts to stream the audio file. - -The AFS process also accepts connections from local clients via -a well-known socket. However, only child processes of para_server -may connect through this socket. All server commands that have the -AFS_READ or AFS_WRITE permission bits use this mechanism to query or -change the database. +the database tables. The AFS process accepts incoming connections +which arrive either on a pipe which is shared with para_server, +or on the local socket it is listening on. The setup is as follows. + + .___________________. .______________. + | | | | + | virtual streaming | | audio format | + | system | | handler | + |_________ _______| |_____ ______| + \ / \ / + | | + .-'""""`-. | | .-'""""`-. + ( ) | | ( ) + |`-.____.-'| .__/ \________________/ \___. |`-.____.-'| + | | | | | | + | file |----| AFS (audio file selector) |----| OSL | + | system | | process | | database | + | | |___________________________| | | + |. ' "" ` .| | |. ' "" ` .| + | | | | | + `-.____.-' | `-.____.-' + ._______/ \_______. + | | + | command handler | + |_______ _______| + \ / + | + | + | + ._____/ \_____. + | | + | para_client | + |_____________| + +The virtual streaming system, which is part of the server process, +communicates with the AFS process via pipes and shared memory. When +the current audio file changes, it sends a notification through the +shared pipe. The AFS process queries the database to determine the +next audio file, opens it, verifies that it has not been changed since +it was added to the database and passes the open file descriptor back +to the virtual streaming system, along with audio file meta-data such +as file name, duration, audio format and so on. The virtual streaming +system then starts to stream the file. + +The command handlers of all AFS server commands use the local socket +to query or update the database. For example, the command handler of +the add command sends the path of an audio file to the local socket. +The AFS process opens the file and tries to find an audio format +handler which recognizes the file. If all goes well, a new database +entry with metadata obtained from the audio format handler is added +to the database. + +Note that AFS employs +[libosl](http://people.tuebingen.mpg.de/maan/osl/), the object +storage layer library, as the database backend. This library offers +functionality similar to a relational database, but is much more +lightweight than a full featured database management system. Database layout --------------- -### The audio file table ### +Metadata about the known audio files is stored in an OSL database. This +database consists of the following tables: + +- The audio file table contains path, hash and metadata of each +known file. + +- The "attributes" table maps each of the 64 possible attributes to a +string. + +- The "blob" tables store images, lyrics, moods, playlists. All of +these are optional. + +- The "score" table describes the subset of admissible files for the +current playlist or mood. + +All tables are described in more detail below. + +

    The audio file table

    This is the most important and usually also the largest table of the AFS database. It contains the information needed to stream each audio @@ -692,7 +842,7 @@ directory. In the latter case, the directory is traversed recursively and all files which are recognized as valid audio files are added to the database. -### The attribute table ### +

    The attribute table

    The attribute table contains two columns, _name_ and _bitnum_. An attribute is simply a name for a certain bit number in the attribute @@ -752,7 +902,7 @@ Read the output of for more information and a complete list of command line options to these commands. -### Blob tables ### +

    Blob tables

    The image, lyrics, moods and playlists tables are all blob tables. Blob tables consist of three columns each: The identifier which is @@ -779,7 +929,7 @@ Note that the images and lyrics are not interpreted at all, and also the playlist and the mood blobs are only investigated when the mood or playlist is activated with the select command. -### The score table ### +

    The score table

    The score table describes those audio files which are admissible for the current mood or playlist (see below). The table has two columns: @@ -805,7 +955,7 @@ terms of attributes and other type of information available in the audio file table. As an example, a mood can define a filename pattern, which is then matched against the names of audio files in the table. -### Playlists ### +

    Playlists

    Playlists are accommodated in the playlist table of the afs database, using the aforementioned blob format for tables. A new playlist is @@ -824,7 +974,7 @@ in descending order so that files will be selected in order. If a file could not be opened for streaming, its entry is removed from the score table (but not from the playlist). -### Moods ### +

    Moods

    A mood consists of a unique name and its *mood definition*, which is a set of *mood lines* containing expressions in terms of attributes @@ -899,7 +1049,7 @@ special treatment: -### List of mood_methods ### +

    List of mood_methods

    no_attributes_set @@ -945,7 +1095,7 @@ if the year tag is a two-digit number. In this case either 1900 or greater than 2000 plus the current year. -### Mood usage ### +

    Mood usage

    To create a new mood called "my_mood", write its definition into some temporary file, say "tmpfile", and add it to the mood table @@ -973,7 +1123,7 @@ if the "-a" switch is given: para ls -a -### Example mood definition ### +

    Example mood definition

    Suppose you have defined attributes "punk" and "rock" and want to define a mood containing only Punk-Rock songs. That is, an audio file should be @@ -1062,7 +1212,7 @@ Audio formats The following audio formats are supported by paraslash: -### MP3 ### +

    MP3

    Mp3, MPEG-1 Audio Layer 3, is a common audio format for audio storage, designed as part of its MPEG-1 standard. An MP3 file is made up of @@ -1072,7 +1222,7 @@ of channels. For a typical CD-audio file (sample rate of 44.1 kHz stereo), encoded with a bit rate of 128 kbit, an MP3 frame is about 400 bytes large. -### OGG/Vorbis ### +

    OGG/Vorbis

    OGG is a standardized audio container format, while Vorbis is an open source codec for lossy audio compression. Since Vorbis is most @@ -1082,7 +1232,7 @@ chunks called OGG pages. A typical OGG page is about 4KB large. The Vorbis codec creates variable-bitrate (VBR) data, where the bitrate may vary considerably. -### OGG/Speex ### +

    OGG/Speex

    Speex is an open-source speech codec that is based on CELP (Code Excited Linear Prediction) coding. It is designed for voice @@ -1092,7 +1242,7 @@ supported. As for Vorbis audio, Speex bit-streams are often stored in OGG files. As of 2012 this codec is considered obsolete since the Oppus codec, described below, surpasses its performance in all areas. -### OGG/Opus ### +

    OGG/Opus

    Opus is a lossy audio compression format standardized through RFC 6716 in 2012. It combines the speech-oriented SILK codec and the @@ -1101,7 +1251,7 @@ OGG/Vorbis and OGG/Speex, Opus data is usually encapsulated in OGG containers. All known software patents which cover Opus are licensed under royalty-free terms. -### AAC ### +

    AAC

    Advanced Audio Coding (AAC) is a standardized, lossy compression and encoding scheme for digital audio which is the default audio @@ -1109,7 +1259,7 @@ format for Apple's iPhone, iPod, iTunes. Usually MPEG-4 is used as the container format and audio files encoded with AAC have the .m4a extension. A typical AAC frame is about 700 bytes large. -### WMA ### +

    WMA

    Windows Media Audio (WMA) is an audio data compression technology developed by Microsoft. A WMA file is usually encapsulated in the @@ -1118,7 +1268,7 @@ how meta data about the file is to be encoded. The bit stream of WMA is composed of superframes, each containing one or more frames of 2048 samples. For 16 bit stereo a WMA superframe is about 8K large. -### FLAC ### +

    FLAC

    The Free Lossless Audio Codec (FLAC) compresses audio without quality loss. It gives better compression ratios than a general purpose @@ -1583,7 +1733,7 @@ they are usually placed directly after the decoding filter. Each sample is multiplied with a scaling factor (>= 1) which makes amp and compress quite expensive in terms of computing power. -### amp ### +

    amp

    The amp filter amplifies the audio stream by a fixed scaling factor that must be known in advance. For para_audiod this factor is derived @@ -1610,7 +1760,7 @@ To store V in the audio file table, the command is used. The reader is encouraged to write a script that performs these computations :) -### compress ### +

    compress

    Unlike the amplification filter, the compress filter adjusts the volume of the audio stream dynamically without prior knowledge about the peak @@ -1831,12 +1981,14 @@ welcome. Here's a list of things you can do to help the project: - Compile and test on your favorite architecture or operating system. The code is tested only on a limited set of systems, so you will probably encounter problems when building on different systems. -- Post about about paraslash on your blog or on social networks. +- Post about paraslash on your blog or on social networks. - Build and maintain Debian/RPM packages for your favorite distribution. Note that there is no mailing list, no bug tracker and no discussion forum for paraslash. If you'd like to contribute, or have questions about contributing, send email to Andre Noll . +New releases are announced by email. If you would like to receive +these announcements, contact the author through the above address. Tools ----- @@ -2025,14 +2177,14 @@ Appendix Network protocols ----------------- -### IP ### +

    IP

    The _Internet Protocol_ is the primary networking protocol used for the Internet. All protocols described below use IP as the underlying layer. Both the prevalent IPv4 and the next-generation IPv6 variant are being deployed actively worldwide. -### Connection-oriented and connectionless protocols ### +

    Connection-oriented and connectionless protocols

    Connectionless protocols differ from connection-oriented ones in that state associated with the sending/receiving endpoints is treated @@ -2048,7 +2200,7 @@ up-to-date internal state of the connection also in general means that the sending endpoints perform congestion control, adapting to qualitative changes of the connection medium. -### Reliability ### +

    Reliability

    In IP networking, packets can be lost, duplicated, or delivered out of order, and different network protocols handle these @@ -2060,7 +2212,7 @@ out-of-order. Retransmission is used to guarantee loss-free delivery. Unreliable protocols, in contrast, do not guarantee ordering or data integrity. -### Classification ### +

    Classification

    With these definitions the protocols which are used by paraslash for steaming audio data may be classified as follows. @@ -2071,7 +2223,7 @@ steaming audio data may be classified as follows. Below we give a short descriptions of these protocols. -### TCP ### +

    TCP

    The _Transmission Control Protocol_ provides reliable, ordered delivery of a stream and a classic window-based congestion control. In contrast @@ -2082,7 +2234,7 @@ extensively by many application layers. Besides HTTP (the Hypertext Transfer Protocol), also FTP (the File Transfer protocol), SMTP (Simple Mail Transfer Protocol), SSH (Secure Shell) all sit on top of TCP. -### UDP ### +

    UDP

    The _User Datagram Protocol_ is the simplest transport-layer protocol, built as a thin layer directly on top of IP. For this reason, it offers @@ -2093,7 +2245,7 @@ means that there is no protection against packet loss or network congestion. Error checking and correction (if at all) are performed in the application. -### DCCP ### +

    DCCP

    The _Datagram Congestion Control Protocol_ combines the connection-oriented state maintenance known from TCP with the @@ -2110,7 +2262,7 @@ the choice of congestion control: classic, window-based congestion control known from TCP is available as CCID-2, rate-based, "smooth" congestion control is offered as CCID-3. -### HTTP ### +

    HTTP

    The _Hypertext Transfer Protocol_ is an application layer protocol on top of TCP. It is spoken by web servers and is most often used @@ -2120,7 +2272,7 @@ delivery of web pages only. Being a simple request/response based protocol, the semantics of the protocol also allow the delivery of multimedia content, such as audio over http. -### Multicast ### +

    Multicast

    IP multicast is not really a protocol but a technique for one-to-many communication over an IP network. The challenge is to deliver