15.04.2014 - Version 0.3.8_beta, last version of 0.3.8 branch. Too much added and fixed...
This commit is contained in:
@@ -2,11 +2,12 @@ project(pip)
|
|||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.6)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} .)
|
||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
set(VERSION "0.0307")
|
set(VERSION "0.0308")
|
||||||
set(SOVERSION ${VERSION})
|
set(SOVERSION ${VERSION})
|
||||||
set(CMAKE_BUILD_TYPE "Release")
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
set(LIBS)
|
set(LIBS)
|
||||||
file(GLOB CPPS "pi*.cpp" "ifaddrs_3rd.c")
|
file(GLOB HDRS "pi*.h")
|
||||||
|
file(GLOB CPPS "pi*.cpp")
|
||||||
|
|
||||||
|
|
||||||
# Check Bessel functions
|
# Check Bessel functions
|
||||||
@@ -87,15 +88,34 @@ else ()
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
target_link_libraries(pip ${LIBS})
|
target_link_libraries(pip ${LIBS})
|
||||||
install(TARGETS pip DESTINATION bin)
|
#install(TARGETS pip DESTINATION bin)
|
||||||
|
|
||||||
|
|
||||||
# Test program
|
# Test program
|
||||||
find_package(Qt4 REQUIRED)
|
#find_package(Qt4 REQUIRED)
|
||||||
include_directories(${QT_INCLUDES})
|
#include_directories(${QT_INCLUDES})
|
||||||
add_executable(pip_test "main.cpp")
|
add_executable(pip_test "main.cpp")
|
||||||
target_link_libraries(pip_test pip ${QT_QTCORE_LIBRARY})
|
#target_link_libraries(pip_test pip ${QT_QTCORE_LIBRARY})
|
||||||
|
target_link_libraries(pip_test pip)
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(system_test)
|
add_subdirectory(system_test)
|
||||||
add_subdirectory(remote_console)
|
add_subdirectory(remote_console)
|
||||||
|
|
||||||
|
if (DEFINED LIB)
|
||||||
|
unset(LIB)
|
||||||
|
if (${WIN32})
|
||||||
|
get_filename_component(MGWDIR ${CMAKE_C_COMPILER} PATH)
|
||||||
|
#get_filename_component(QTDIR ${QT_QMAKE_EXECUTABLE} PATH)
|
||||||
|
set(CMAKE_INSTALL_PREFIX)
|
||||||
|
#install(TARGETS pip DESTINATION ${QTDIR})
|
||||||
|
install(TARGETS pip DESTINATION ${MGWDIR}/../lib)
|
||||||
|
install(FILES ${HDRS} DESTINATION ${MGWDIR}/../include)
|
||||||
|
else ()
|
||||||
|
set(CMAKE_INSTALL_PREFIX /usr)
|
||||||
|
install(TARGETS pip DESTINATION lib)
|
||||||
|
install(FILES ${HDRS} DESTINATION include)
|
||||||
|
endif ()
|
||||||
|
else ()
|
||||||
|
install(TARGETS pip DESTINATION bin)
|
||||||
|
endif ()
|
||||||
|
|||||||
2269
Doxyfile
2269
Doxyfile
@@ -1,104 +1,114 @@
|
|||||||
# Doxyfile 1.8.4
|
# Doxyfile 1.8.6
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project
|
# doxygen (www.doxygen.org) for a project.
|
||||||
#
|
#
|
||||||
# All text after a hash (#) is considered a comment and will be ignored
|
# All text after a double hash (##) is considered a comment and is placed in
|
||||||
|
# front of the TAG it is preceding.
|
||||||
|
#
|
||||||
|
# All text after a single hash (#) is considered a comment and will be ignored.
|
||||||
# The format is:
|
# The format is:
|
||||||
# TAG = value [value, ...]
|
# TAG = value [value, ...]
|
||||||
# For lists items can also be appended using:
|
# For lists, items can also be appended using:
|
||||||
# TAG += value [value, ...]
|
# TAG += value [value, ...]
|
||||||
# Values that contain spaces should be placed between quotes (" ")
|
# Values that contain spaces should be placed between quotes (\" \").
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Project related configuration options
|
# Project related configuration options
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# This tag specifies the encoding used for all characters in the config file
|
# This tag specifies the encoding used for all characters in the config file
|
||||||
# that follow. The default is UTF-8 which is also the encoding used for all
|
# that follow. The default is UTF-8 which is also the encoding used for all text
|
||||||
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
|
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
|
||||||
# iconv built into libc) for the transcoding. See
|
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
|
||||||
# http://www.gnu.org/software/libiconv for the list of possible encodings.
|
# for the list of possible encodings.
|
||||||
|
# The default value is: UTF-8.
|
||||||
|
|
||||||
DOXYFILE_ENCODING = UTF-8
|
DOXYFILE_ENCODING = UTF-8
|
||||||
|
|
||||||
# The PROJECT_NAME tag is a single word (or sequence of words) that should
|
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
|
||||||
# identify the project. Note that if you do not use Doxywizard you need
|
# double-quotes, unless you are using Doxywizard) that should identify the
|
||||||
# to put quotes around the project name if it contains spaces.
|
# project for which the documentation is generated. This name is used in the
|
||||||
|
# title of most generated pages and in a few other places.
|
||||||
|
# The default value is: My Project.
|
||||||
|
|
||||||
PROJECT_NAME = PIP
|
PROJECT_NAME = PIP
|
||||||
|
|
||||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||||
# This could be handy for archiving the generated documentation or
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# if some version control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.3.7
|
PROJECT_NUMBER = 0.3.8
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
# a quick idea about the purpose of the project. Keep the description short.
|
# quick idea about the purpose of the project. Keep the description short.
|
||||||
|
|
||||||
PROJECT_BRIEF = "Platform-Independent Primitives"
|
PROJECT_BRIEF = "Platform-Independent Primitives"
|
||||||
|
|
||||||
# With the PROJECT_LOGO tag one can specify an logo or icon that is
|
# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
|
||||||
# included in the documentation. The maximum height of the logo should not
|
# the documentation. The maximum height of the logo should not exceed 55 pixels
|
||||||
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
|
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
|
||||||
# Doxygen will copy the logo to the output directory.
|
# to the output directory.
|
||||||
|
|
||||||
PROJECT_LOGO =
|
PROJECT_LOGO =
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||||
# base path where the generated documentation will be put.
|
# into which the generated documentation will be written. If a relative path is
|
||||||
# If a relative path is entered, it will be relative to the location
|
# entered, it will be relative to the location where doxygen was started. If
|
||||||
# where doxygen was started. If left blank the current directory will be used.
|
# left blank the current directory will be used.
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = doc
|
OUTPUT_DIRECTORY = doc
|
||||||
|
|
||||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
|
||||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
# directories (in 2 levels) under the output directory of each output format and
|
||||||
# format and will distribute the generated files over these directories.
|
# will distribute the generated files over these directories. Enabling this
|
||||||
# Enabling this option can be useful when feeding doxygen a huge amount of
|
# option can be useful when feeding doxygen a huge amount of source files, where
|
||||||
# source files, where putting all generated files in the same directory would
|
# putting all generated files in the same directory would otherwise causes
|
||||||
# otherwise cause performance problems for the file system.
|
# performance problems for the file system.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
CREATE_SUBDIRS = NO
|
CREATE_SUBDIRS = NO
|
||||||
|
|
||||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||||
# documentation generated by doxygen is written. Doxygen will use this
|
# documentation generated by doxygen is written. Doxygen will use this
|
||||||
# information to generate all constant output in the proper language.
|
# information to generate all constant output in the proper language.
|
||||||
# The default language is English, other supported languages are:
|
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
|
||||||
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
|
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
|
||||||
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
|
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
|
||||||
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
|
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
|
||||||
# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
|
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
|
||||||
# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
|
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
|
||||||
# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
|
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
|
||||||
|
# Ukrainian and Vietnamese.
|
||||||
|
# The default value is: English.
|
||||||
|
|
||||||
OUTPUT_LANGUAGE = English
|
OUTPUT_LANGUAGE = English
|
||||||
|
|
||||||
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
|
# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
|
||||||
# include brief member descriptions after the members that are listed in
|
# descriptions after the members that are listed in the file and class
|
||||||
# the file and class documentation (similar to JavaDoc).
|
# documentation (similar to Javadoc). Set to NO to disable this.
|
||||||
# Set to NO to disable this.
|
# The default value is: YES.
|
||||||
|
|
||||||
BRIEF_MEMBER_DESC = YES
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
|
||||||
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
|
# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
|
||||||
# the brief description of a member or function before the detailed description.
|
# 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
|
#
|
||||||
|
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
|
||||||
# brief descriptions will be completely suppressed.
|
# brief descriptions will be completely suppressed.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
REPEAT_BRIEF = YES
|
REPEAT_BRIEF = YES
|
||||||
|
|
||||||
# This tag implements a quasi-intelligent brief description abbreviator
|
# This tag implements a quasi-intelligent brief description abbreviator that is
|
||||||
# that is used to form the text in various listings. Each string
|
# used to form the text in various listings. Each string in this list, if found
|
||||||
# in this list, if found as the leading text of the brief description, will be
|
# as the leading text of the brief description, will be stripped from the text
|
||||||
# stripped from the text and the result after processing the whole list, is
|
# and the result, after processing the whole list, is used as the annotated
|
||||||
# used as the annotated text. Otherwise, the brief description is used as-is.
|
# text. Otherwise, the brief description is used as-is. If left blank, the
|
||||||
# If left blank, the following values are used ("$name" is automatically
|
# following values are used ($name is automatically replaced with the name of
|
||||||
# replaced with the name of the entity): "The $name class" "The $name widget"
|
# the entity):The $name class, The $name widget, The $name file, is, provides,
|
||||||
# "The $name file" "is" "provides" "specifies" "contains"
|
# specifies, contains, represents, a, an and the.
|
||||||
# "represents" "a" "an" "the"
|
|
||||||
|
|
||||||
ABBREVIATE_BRIEF = "The $name class" \
|
ABBREVIATE_BRIEF = "The $name class" \
|
||||||
"The $name widget" \
|
"The $name widget" \
|
||||||
@@ -113,8 +123,9 @@ ABBREVIATE_BRIEF = "The $name class" \
|
|||||||
the
|
the
|
||||||
|
|
||||||
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
||||||
# Doxygen will generate a detailed section even if there is only a brief
|
# doxygen will generate a detailed section even if there is only a brief
|
||||||
# description.
|
# description.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
ALWAYS_DETAILED_SEC = NO
|
ALWAYS_DETAILED_SEC = NO
|
||||||
|
|
||||||
@@ -122,88 +133,102 @@ ALWAYS_DETAILED_SEC = NO
|
|||||||
# inherited members of a class in the documentation of that class as if those
|
# inherited members of a class in the documentation of that class as if those
|
||||||
# members were ordinary class members. Constructors, destructors and assignment
|
# members were ordinary class members. Constructors, destructors and assignment
|
||||||
# operators of the base classes will not be shown.
|
# operators of the base classes will not be shown.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
INLINE_INHERITED_MEMB = NO
|
INLINE_INHERITED_MEMB = NO
|
||||||
|
|
||||||
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
|
# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
|
||||||
# path before files name in the file list and in the header files. If set
|
# before files name in the file list and in the header files. If set to NO the
|
||||||
# to NO the shortest path that makes the file name unique will be used.
|
# shortest path that makes the file name unique will be used
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
FULL_PATH_NAMES = YES
|
FULL_PATH_NAMES = YES
|
||||||
|
|
||||||
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
|
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
|
||||||
# can be used to strip a user-defined part of the path. Stripping is
|
# Stripping is only done if one of the specified strings matches the left-hand
|
||||||
# only done if one of the specified strings matches the left-hand part of
|
# part of the path. The tag can be used to show relative paths in the file list.
|
||||||
# the path. The tag can be used to show relative paths in the file list.
|
# If left blank the directory from which doxygen is run is used as the path to
|
||||||
# If left blank the directory from which doxygen is run is used as the
|
# strip.
|
||||||
# path to strip. Note that you specify absolute paths here, but also
|
#
|
||||||
# relative paths, which will be relative from the directory where doxygen is
|
# Note that you can specify absolute paths here, but also relative paths, which
|
||||||
# started.
|
# will be relative from the directory where doxygen is started.
|
||||||
|
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||||
|
|
||||||
STRIP_FROM_PATH =
|
STRIP_FROM_PATH =
|
||||||
|
|
||||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||||
# the path mentioned in the documentation of a class, which tells
|
# path mentioned in the documentation of a class, which tells the reader which
|
||||||
# the reader which header file to include in order to use a class.
|
# header file to include in order to use a class. If left blank only the name of
|
||||||
# If left blank only the name of the header file containing the class
|
# the header file containing the class definition is used. Otherwise one should
|
||||||
# definition is used. Otherwise one should specify the include paths that
|
# specify the list of include paths that are normally passed to the compiler
|
||||||
# are normally passed to the compiler using the -I flag.
|
# using the -I flag.
|
||||||
|
|
||||||
STRIP_FROM_INC_PATH =
|
STRIP_FROM_INC_PATH =
|
||||||
|
|
||||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
|
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
||||||
# (but less readable) file names. This can be useful if your file system
|
# less readable) file names. This can be useful is your file systems doesn't
|
||||||
# doesn't support long names like on DOS, Mac, or CD-ROM.
|
# support long names like on DOS, Mac, or CD-ROM.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SHORT_NAMES = NO
|
SHORT_NAMES = NO
|
||||||
|
|
||||||
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
|
||||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
# first line (until the first dot) of a Javadoc-style comment as the brief
|
||||||
# comment as the brief description. If set to NO, the JavaDoc
|
# description. If set to NO, the Javadoc-style will behave just like regular Qt-
|
||||||
# comments will behave just like regular Qt-style comments
|
# style comments (thus requiring an explicit @brief command for a brief
|
||||||
# (thus requiring an explicit @brief command for a brief description.)
|
# description.)
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
JAVADOC_AUTOBRIEF = NO
|
JAVADOC_AUTOBRIEF = NO
|
||||||
|
|
||||||
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
|
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
|
||||||
# interpret the first line (until the first dot) of a Qt-style
|
# line (until the first dot) of a Qt-style comment as the brief description. If
|
||||||
# comment as the brief description. If set to NO, the comments
|
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
|
||||||
# will behave just like regular Qt-style comments (thus requiring
|
# requiring an explicit \brief command for a brief description.)
|
||||||
# an explicit \brief command for a brief description.)
|
# The default value is: NO.
|
||||||
|
|
||||||
QT_AUTOBRIEF = NO
|
QT_AUTOBRIEF = NO
|
||||||
|
|
||||||
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
|
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
|
||||||
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
|
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
|
||||||
# comments) as a brief description. This used to be the default behaviour.
|
# a brief description. This used to be the default behavior. The new default is
|
||||||
# The new default is to treat a multi-line C++ comment block as a detailed
|
# to treat a multi-line C++ comment block as a detailed description. Set this
|
||||||
# description. Set this tag to YES if you prefer the old behaviour instead.
|
# tag to YES if you prefer the old behavior instead.
|
||||||
|
#
|
||||||
|
# Note that setting this tag to YES also means that rational rose comments are
|
||||||
|
# not recognized any more.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
MULTILINE_CPP_IS_BRIEF = NO
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
|
||||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
|
||||||
# member inherits the documentation from any documented member that it
|
# documentation from any documented member that it re-implements.
|
||||||
# re-implements.
|
# The default value is: YES.
|
||||||
|
|
||||||
INHERIT_DOCS = YES
|
INHERIT_DOCS = YES
|
||||||
|
|
||||||
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
|
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
|
||||||
# a new page for each member. If set to NO, the documentation of a member will
|
# new page for each member. If set to NO, the documentation of a member will be
|
||||||
# be part of the file/class/namespace that contains it.
|
# part of the file/class/namespace that contains it.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SEPARATE_MEMBER_PAGES = NO
|
SEPARATE_MEMBER_PAGES = NO
|
||||||
|
|
||||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
|
||||||
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
# uses this value to replace tabs by spaces in code fragments.
|
||||||
|
# Minimum value: 1, maximum value: 16, default value: 4.
|
||||||
|
|
||||||
TAB_SIZE = 4
|
TAB_SIZE = 4
|
||||||
|
|
||||||
# This tag can be used to specify a number of aliases that acts
|
# This tag can be used to specify a number of aliases that act as commands in
|
||||||
# as commands in the documentation. An alias has the form "name=value".
|
# the documentation. An alias has the form:
|
||||||
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
|
# name=value
|
||||||
# put the command \sideeffect (or @sideeffect) in the documentation, which
|
# For example adding
|
||||||
# will result in a user-defined paragraph with heading "Side Effects:".
|
# "sideeffect=@par Side Effects:\n"
|
||||||
# You can put \n's in the value part of an alias to insert newlines.
|
# will allow you to put the command \sideeffect (or @sideeffect) in the
|
||||||
|
# documentation, which will result in a user-defined paragraph with heading
|
||||||
|
# "Side Effects:". You can put \n's in the value part of an alias to insert
|
||||||
|
# newlines.
|
||||||
|
|
||||||
ALIASES = "handlers=\name Handlers" \
|
ALIASES = "handlers=\name Handlers" \
|
||||||
"vhandlers=\name Virtual handlers" \
|
"vhandlers=\name Virtual handlers" \
|
||||||
@@ -211,57 +236,62 @@ ALIASES = "handlers=\name Handlers" \
|
|||||||
"ioparams=\name Configurable parameters"
|
"ioparams=\name Configurable parameters"
|
||||||
|
|
||||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||||
# A mapping has the form "name=value". For example adding
|
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||||
# "class=itcl::class" will allow you to use the command class in the
|
# will allow you to use the command class in the itcl::class meaning.
|
||||||
# itcl::class meaning.
|
|
||||||
|
|
||||||
TCL_SUBST =
|
TCL_SUBST =
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
|
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||||
# sources only. Doxygen will then generate output that is more tailored for C.
|
# only. Doxygen will then generate output that is more tailored for C. For
|
||||||
# For instance, some of the names that are used will be different. The list
|
# instance, some of the names that are used will be different. The list of all
|
||||||
# of all members will be omitted, etc.
|
# members will be omitted, etc.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
|
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
|
||||||
# sources only. Doxygen will then generate output that is more tailored for
|
# Python sources only. Doxygen will then generate output that is more tailored
|
||||||
# Java. For instance, namespaces will be presented as packages, qualified
|
# for that language. For instance, namespaces will be presented as packages,
|
||||||
# scopes will look different, etc.
|
# qualified scopes will look different, etc.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
OPTIMIZE_OUTPUT_JAVA = NO
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
|
||||||
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
|
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
|
||||||
# sources only. Doxygen will then generate output that is more tailored for
|
# sources. Doxygen will then generate output that is tailored for Fortran.
|
||||||
# Fortran.
|
# The default value is: NO.
|
||||||
|
|
||||||
OPTIMIZE_FOR_FORTRAN = NO
|
OPTIMIZE_FOR_FORTRAN = NO
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
|
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
|
||||||
# sources. Doxygen will then generate output that is tailored for
|
# sources. Doxygen will then generate output that is tailored for VHDL.
|
||||||
# VHDL.
|
# The default value is: NO.
|
||||||
|
|
||||||
OPTIMIZE_OUTPUT_VHDL = NO
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
|
|
||||||
# Doxygen selects the parser to use depending on the extension of the files it
|
# Doxygen selects the parser to use depending on the extension of the files it
|
||||||
# parses. With this tag you can assign which parser to use for a given
|
# parses. With this tag you can assign which parser to use for a given
|
||||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
# 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,
|
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||||
# and language is one of the parsers supported by doxygen: IDL, Java,
|
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
||||||
# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
|
# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
|
||||||
# C++. For instance to make doxygen treat .inc files as Fortran files (default
|
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
|
||||||
# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
|
# (default is Fortran), use: inc=Fortran f=C.
|
||||||
# that for custom extensions you also need to set FILE_PATTERNS otherwise the
|
#
|
||||||
# files are not read by doxygen.
|
# 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.
|
||||||
|
|
||||||
EXTENSION_MAPPING =
|
EXTENSION_MAPPING =
|
||||||
|
|
||||||
# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
|
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
|
||||||
# comments according to the Markdown format, which allows for more readable
|
# according to the Markdown format, which allows for more readable
|
||||||
# documentation. See http://daringfireball.net/projects/markdown/ for details.
|
# documentation. See http://daringfireball.net/projects/markdown/ for details.
|
||||||
# The output of markdown processing is further processed by doxygen, so you
|
# The output of markdown processing is further processed by doxygen, so you can
|
||||||
# can mix doxygen, HTML, and XML commands with Markdown formatting.
|
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
|
||||||
# Disable only in case of backward compatibilities issues.
|
# case of backward compatibilities issues.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
MARKDOWN_SUPPORT = YES
|
MARKDOWN_SUPPORT = YES
|
||||||
|
|
||||||
@@ -269,35 +299,41 @@ MARKDOWN_SUPPORT = YES
|
|||||||
# classes, or namespaces to their corresponding documentation. Such a link can
|
# 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
|
# be prevented in individual cases by by putting a % sign in front of the word
|
||||||
# or globally by setting AUTOLINK_SUPPORT to NO.
|
# or globally by setting AUTOLINK_SUPPORT to NO.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
AUTOLINK_SUPPORT = YES
|
AUTOLINK_SUPPORT = YES
|
||||||
|
|
||||||
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
|
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
|
||||||
# to include (a tag file for) the STL sources as input, then you should
|
# to include (a tag file for) the STL sources as input, then you should set this
|
||||||
# set this tag to YES in order to let doxygen match functions declarations and
|
# tag to YES in order to let doxygen match functions declarations and
|
||||||
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
|
# definitions whose arguments contain STL classes (e.g. func(std::string);
|
||||||
# func(std::string) {}). This also makes the inheritance and collaboration
|
# versus func(std::string) {}). This also make the inheritance and collaboration
|
||||||
# diagrams that involve STL classes more complete and accurate.
|
# diagrams that involve STL classes more complete and accurate.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
BUILTIN_STL_SUPPORT = NO
|
BUILTIN_STL_SUPPORT = NO
|
||||||
|
|
||||||
# If you use Microsoft's C++/CLI language, you should set this option to YES to
|
# If you use Microsoft's C++/CLI language, you should set this option to YES to
|
||||||
# enable parsing support.
|
# enable parsing support.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
CPP_CLI_SUPPORT = NO
|
CPP_CLI_SUPPORT = NO
|
||||||
|
|
||||||
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
|
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
|
||||||
# Doxygen will parse them like normal C++ but will assume all classes use public
|
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
|
||||||
# instead of private inheritance when no explicit protection keyword is present.
|
# will parse them like normal C++ but will assume all classes use public instead
|
||||||
|
# of private inheritance when no explicit protection keyword is present.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SIP_SUPPORT = NO
|
SIP_SUPPORT = NO
|
||||||
|
|
||||||
# For Microsoft's IDL there are propget and propput attributes to indicate
|
# For Microsoft's IDL there are propget and propput attributes to indicate
|
||||||
# getter and setter methods for a property. Setting this option to YES (the
|
# getter and setter methods for a property. Setting this option to YES will make
|
||||||
# default) will make doxygen replace the get and set methods by a property in
|
# doxygen to replace the get and set methods by a property in the documentation.
|
||||||
# the documentation. This will only work if the methods are indeed getting or
|
# This will only work if the methods are indeed getting or setting a simple
|
||||||
# setting a simple type. If this is not the case, or you want to show the
|
# type. If this is not the case, or you want to show the methods anyway, you
|
||||||
# methods anyway, you should set this option to NO.
|
# should set this option to NO.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
IDL_PROPERTY_SUPPORT = NO
|
IDL_PROPERTY_SUPPORT = NO
|
||||||
|
|
||||||
@@ -305,51 +341,61 @@ IDL_PROPERTY_SUPPORT = NO
|
|||||||
# 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
|
# member in the group (if any) for the other members of the group. By default
|
||||||
# all members of a group must be documented explicitly.
|
# all members of a group must be documented explicitly.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
DISTRIBUTE_GROUP_DOC = NO
|
DISTRIBUTE_GROUP_DOC = NO
|
||||||
|
|
||||||
# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
|
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
|
||||||
# the same type (for instance a group of public functions) to be put as a
|
# (for instance a group of public functions) to be put as a subgroup of that
|
||||||
# subgroup of that type (e.g. under the Public Functions section). Set it to
|
# type (e.g. under the Public Functions section). Set it to NO to prevent
|
||||||
# NO to prevent subgrouping. Alternatively, this can be done per class using
|
# subgrouping. Alternatively, this can be done per class using the
|
||||||
# the \nosubgrouping command.
|
# \nosubgrouping command.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
SUBGROUPING = NO
|
SUBGROUPING = NO
|
||||||
|
|
||||||
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
|
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
|
||||||
# unions are shown inside the group in which they are included (e.g. using
|
# are shown inside the group in which they are included (e.g. using \ingroup)
|
||||||
# @ingroup) instead of on a separate page (for HTML and Man pages) or
|
# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
|
||||||
# section (for LaTeX and RTF).
|
# and RTF).
|
||||||
|
#
|
||||||
|
# Note that this feature does not work in combination with
|
||||||
|
# SEPARATE_MEMBER_PAGES.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
INLINE_GROUPED_CLASSES = NO
|
INLINE_GROUPED_CLASSES = NO
|
||||||
|
|
||||||
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
|
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
|
||||||
# unions with only public data fields or simple typedef fields will be shown
|
# with only public data fields or simple typedef fields will be shown inline in
|
||||||
# inline in the documentation of the scope in which they are defined (i.e. file,
|
# the documentation of the scope in which they are defined (i.e. file,
|
||||||
# namespace, or group documentation), provided this scope is documented. If set
|
# namespace, or group documentation), provided this scope is documented. If set
|
||||||
# to NO (the default), structs, classes, and unions are shown on a separate
|
# to NO, structs, classes, and unions are shown on a separate page (for HTML and
|
||||||
# page (for HTML and Man pages) or section (for LaTeX and RTF).
|
# Man pages) or section (for LaTeX and RTF).
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
INLINE_SIMPLE_STRUCTS = NO
|
INLINE_SIMPLE_STRUCTS = NO
|
||||||
|
|
||||||
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
|
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
|
||||||
# is documented as struct, union, or enum with the name of the typedef. So
|
# enum is documented as struct, union, or enum with the name of the typedef. So
|
||||||
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
|
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
|
||||||
# with name TypeT. When disabled the typedef will appear as a member of a file,
|
# with name TypeT. When disabled the typedef will appear as a member of a file,
|
||||||
# namespace, or class. And the struct will be named TypeS. This can typically
|
# namespace, or class. And the struct will be named TypeS. This can typically be
|
||||||
# be useful for C code in case the coding convention dictates that all compound
|
# useful for C code in case the coding convention dictates that all compound
|
||||||
# types are typedef'ed and only the typedef is referenced, never the tag name.
|
# types are typedef'ed and only the typedef is referenced, never the tag name.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
TYPEDEF_HIDES_STRUCT = NO
|
TYPEDEF_HIDES_STRUCT = NO
|
||||||
|
|
||||||
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
|
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
|
||||||
# cache is used to resolve symbols given their name and scope. Since this can
|
# cache is used to resolve symbols given their name and scope. Since this can be
|
||||||
# be an expensive process and often the same symbol appear multiple times in
|
# an expensive process and often the same symbol appears multiple times in the
|
||||||
# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
|
# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
|
||||||
# small doxygen will become slower. If the cache is too large, memory is wasted.
|
# doxygen will become slower. If the cache is too large, memory is wasted. The
|
||||||
# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
|
# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
|
||||||
# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
|
# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
|
||||||
# symbols.
|
# symbols. At the end of a run doxygen will report the cache usage and suggest
|
||||||
|
# the optimal cache size from a speed point of view.
|
||||||
|
# Minimum value: 0, maximum value: 9, default value: 0.
|
||||||
|
|
||||||
LOOKUP_CACHE_SIZE = 0
|
LOOKUP_CACHE_SIZE = 0
|
||||||
|
|
||||||
@@ -358,329 +404,377 @@ LOOKUP_CACHE_SIZE = 0
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# 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.
|
# documentation are documented, even if no documentation was available. Private
|
||||||
# Private class members and static file members will be hidden unless
|
# class members and static file members will be hidden unless the
|
||||||
# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
|
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
|
||||||
|
# Note: This will also disable the warnings about undocumented members that are
|
||||||
|
# normally produced when WARNINGS is set to YES.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_ALL = NO
|
EXTRACT_ALL = NO
|
||||||
|
|
||||||
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
|
||||||
# will be included in the documentation.
|
# be included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_PRIVATE = 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.
|
# scope will be included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_PACKAGE = NO
|
EXTRACT_PACKAGE = NO
|
||||||
|
|
||||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file
|
# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
|
||||||
# will be included in the documentation.
|
# included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_STATIC = NO
|
EXTRACT_STATIC = NO
|
||||||
|
|
||||||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
|
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
|
||||||
# defined locally in source files will be included in the documentation.
|
# locally in source files will be included in the documentation. If set to NO
|
||||||
# If set to NO only classes defined in header files are included.
|
# only classes defined in header files are included. Does not have any effect
|
||||||
|
# for Java sources.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
EXTRACT_LOCAL_CLASSES = YES
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
|
||||||
# This flag is only useful for Objective-C code. When set to YES local
|
# This flag is only useful for Objective-C code. When set to YES local methods,
|
||||||
# methods, which are defined in the implementation section but not in
|
# which are defined in the implementation section but not in the interface are
|
||||||
# the interface are included in the documentation.
|
# included in the documentation. If set to NO only methods in the interface are
|
||||||
# If set to NO (the default) only methods in the interface are included.
|
# included.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_LOCAL_METHODS = YES
|
EXTRACT_LOCAL_METHODS = YES
|
||||||
|
|
||||||
# If this flag is set to YES, the members of anonymous namespaces will be
|
# If this flag is set to YES, the members of anonymous namespaces will be
|
||||||
# extracted and appear in the documentation as a namespace called
|
# extracted and appear in the documentation as a namespace called
|
||||||
# 'anonymous_namespace{file}', where file will be replaced with the base
|
# 'anonymous_namespace{file}', where file will be replaced with the base name of
|
||||||
# name of the file that contains the anonymous namespace. By default
|
# the file that contains the anonymous namespace. By default anonymous namespace
|
||||||
# anonymous namespaces are hidden.
|
# are hidden.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_ANON_NSPACES = NO
|
EXTRACT_ANON_NSPACES = NO
|
||||||
|
|
||||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
|
||||||
# undocumented members of documented classes, files or namespaces.
|
# undocumented members inside documented classes or files. If set to NO these
|
||||||
# If set to NO (the default) these members will be included in the
|
# members will be included in the various overviews, but no documentation
|
||||||
# various overviews, but no documentation section is generated.
|
# section is generated. This option has no effect if EXTRACT_ALL is enabled.
|
||||||
# This option has no effect if EXTRACT_ALL is enabled.
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_UNDOC_MEMBERS = YES
|
HIDE_UNDOC_MEMBERS = YES
|
||||||
|
|
||||||
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
|
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
|
||||||
# undocumented classes that are normally visible in the class hierarchy.
|
# undocumented classes that are normally visible in the class hierarchy. If set
|
||||||
# If set to NO (the default) these classes will be included in the various
|
# to NO these classes will be included in the various overviews. This option has
|
||||||
# overviews. This option has no effect if EXTRACT_ALL is enabled.
|
# no effect if EXTRACT_ALL is enabled.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_UNDOC_CLASSES = YES
|
HIDE_UNDOC_CLASSES = YES
|
||||||
|
|
||||||
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
|
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
|
||||||
# friend (class|struct|union) declarations.
|
# (class|struct|union) declarations. If set to NO these declarations will be
|
||||||
# If set to NO (the default) these declarations will be included in the
|
# included in the documentation.
|
||||||
# documentation.
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_FRIEND_COMPOUNDS = YES
|
HIDE_FRIEND_COMPOUNDS = YES
|
||||||
|
|
||||||
# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
|
# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
|
||||||
# documentation blocks found inside the body of a function.
|
# documentation blocks found inside the body of a function. If set to NO these
|
||||||
# If set to NO (the default) these blocks will be appended to the
|
# blocks will be appended to the function's detailed documentation block.
|
||||||
# function's detailed documentation block.
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_IN_BODY_DOCS = NO
|
HIDE_IN_BODY_DOCS = NO
|
||||||
|
|
||||||
# The INTERNAL_DOCS tag determines if documentation
|
# The INTERNAL_DOCS tag determines if documentation that is typed after a
|
||||||
# that is typed after a \internal command is included. If the tag is set
|
# \internal command is included. If the tag is set to NO then the documentation
|
||||||
# to NO (the default) then the documentation will be excluded.
|
# will be excluded. Set it to YES to include the internal documentation.
|
||||||
# Set it to YES to include the internal documentation.
|
# The default value is: NO.
|
||||||
|
|
||||||
INTERNAL_DOCS = NO
|
INTERNAL_DOCS = NO
|
||||||
|
|
||||||
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
|
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
|
||||||
# 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
|
# 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
|
# in case and if your file system supports case sensitive file names. Windows
|
||||||
# and Mac users are advised to set this option to NO.
|
# and Mac users are advised to set this option to NO.
|
||||||
|
# The default value is: system dependent.
|
||||||
|
|
||||||
CASE_SENSE_NAMES = NO
|
CASE_SENSE_NAMES = NO
|
||||||
|
|
||||||
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
|
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
|
||||||
# will show members with their full class and namespace scopes in the
|
# their full class and namespace scopes in the documentation. If set to YES the
|
||||||
# documentation. If set to YES the scope will be hidden.
|
# scope will be hidden.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_SCOPE_NAMES = NO
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
|
||||||
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
|
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
|
||||||
# will put a list of the files that are included by a file in the documentation
|
# the files that are included by a file in the documentation of that file.
|
||||||
# of that file.
|
# The default value is: YES.
|
||||||
|
|
||||||
SHOW_INCLUDE_FILES = NO
|
SHOW_INCLUDE_FILES = NO
|
||||||
|
|
||||||
# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
|
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
|
||||||
# will list include files with double quotes in the documentation
|
# grouped member an include statement to the documentation, telling the reader
|
||||||
# rather than with sharp brackets.
|
# which file to include in order to use the member.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SHOW_GROUPED_MEMB_INC = NO
|
||||||
|
|
||||||
|
# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
|
||||||
|
# files with double quotes in the documentation rather than with sharp brackets.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
FORCE_LOCAL_INCLUDES = NO
|
FORCE_LOCAL_INCLUDES = NO
|
||||||
|
|
||||||
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
|
# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
|
||||||
# is inserted in the documentation for inline members.
|
# documentation for inline members.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
INLINE_INFO = YES
|
INLINE_INFO = YES
|
||||||
|
|
||||||
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
|
# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
|
||||||
# will sort the (detailed) documentation of file and class members
|
# (detailed) documentation of file and class members alphabetically by member
|
||||||
# alphabetically by member name. If set to NO the members will appear in
|
# name. If set to NO the members will appear in declaration order.
|
||||||
# declaration order.
|
# The default value is: YES.
|
||||||
|
|
||||||
SORT_MEMBER_DOCS = NO
|
SORT_MEMBER_DOCS = NO
|
||||||
|
|
||||||
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
|
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
|
||||||
# brief documentation of file, namespace and class members alphabetically
|
# descriptions of file, namespace and class members alphabetically by member
|
||||||
# by member name. If set to NO (the default) the members will appear in
|
# name. If set to NO the members will appear in declaration order. Note that
|
||||||
# declaration order.
|
# this will also influence the order of the classes in the class list.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SORT_BRIEF_DOCS = NO
|
SORT_BRIEF_DOCS = NO
|
||||||
|
|
||||||
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
|
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
|
||||||
# will sort the (brief and detailed) documentation of class members so that
|
# (brief and detailed) documentation of class members so that constructors and
|
||||||
# constructors and destructors are listed first. If set to NO (the default)
|
# destructors are listed first. If set to NO the constructors will appear in the
|
||||||
# the constructors will appear in the respective orders defined by
|
# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
|
||||||
# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
|
# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
|
||||||
# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
|
# member documentation.
|
||||||
# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
|
# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
|
||||||
|
# detailed member documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SORT_MEMBERS_CTORS_1ST = NO
|
SORT_MEMBERS_CTORS_1ST = NO
|
||||||
|
|
||||||
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
|
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
|
||||||
# hierarchy of group names into alphabetical order. If set to NO (the default)
|
# of group names into alphabetical order. If set to NO the group names will
|
||||||
# the group names will appear in their defined order.
|
# appear in their defined order.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SORT_GROUP_NAMES = NO
|
SORT_GROUP_NAMES = NO
|
||||||
|
|
||||||
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
|
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
|
||||||
# sorted by fully-qualified names, including namespaces. If set to
|
# fully-qualified names, including namespaces. If set to NO, the class list will
|
||||||
# NO (the default), the class list will be sorted only by class name,
|
# be sorted only by class name, not including the namespace part.
|
||||||
# not including the namespace part.
|
|
||||||
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
|
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
|
||||||
# Note: This option applies only to the class list, not to the
|
# Note: This option applies only to the class list, not to the alphabetical
|
||||||
# alphabetical list.
|
# list.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SORT_BY_SCOPE_NAME = NO
|
SORT_BY_SCOPE_NAME = NO
|
||||||
|
|
||||||
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
|
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
|
||||||
# do proper type resolution of all parameters of a function it will reject a
|
# type resolution of all parameters of a function it will reject a match between
|
||||||
# match between the prototype and the implementation of a member function even
|
# the prototype and the implementation of a member function even if there is
|
||||||
# if there is only one candidate or it is obvious which candidate to choose
|
# only one candidate or it is obvious which candidate to choose by doing a
|
||||||
# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
|
# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
|
||||||
# will still accept a match between prototype and implementation in such cases.
|
# accept a match between prototype and implementation in such cases.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
STRICT_PROTO_MATCHING = NO
|
STRICT_PROTO_MATCHING = NO
|
||||||
|
|
||||||
# The GENERATE_TODOLIST tag can be used to enable (YES) or
|
# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
|
||||||
# disable (NO) the todo list. This list is created by putting \todo
|
# todo list. This list is created by putting \todo commands in the
|
||||||
# commands in the documentation.
|
# documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
GENERATE_TODOLIST = YES
|
GENERATE_TODOLIST = YES
|
||||||
|
|
||||||
# The GENERATE_TESTLIST tag can be used to enable (YES) or
|
# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
|
||||||
# disable (NO) the test list. This list is created by putting \test
|
# test list. This list is created by putting \test commands in the
|
||||||
# commands in the documentation.
|
# documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
GENERATE_TESTLIST = YES
|
GENERATE_TESTLIST = YES
|
||||||
|
|
||||||
# The GENERATE_BUGLIST tag can be used to enable (YES) or
|
# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
|
||||||
# disable (NO) the bug list. This list is created by putting \bug
|
# list. This list is created by putting \bug commands in the documentation.
|
||||||
# commands in the documentation.
|
# The default value is: YES.
|
||||||
|
|
||||||
GENERATE_BUGLIST = YES
|
GENERATE_BUGLIST = YES
|
||||||
|
|
||||||
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
|
# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
|
||||||
# disable (NO) the deprecated list. This list is created by putting
|
# the deprecated list. This list is created by putting \deprecated commands in
|
||||||
# \deprecated commands in the documentation.
|
# the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
GENERATE_DEPRECATEDLIST= YES
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
|
|
||||||
# The ENABLED_SECTIONS tag can be used to enable conditional
|
# The ENABLED_SECTIONS tag can be used to enable conditional documentation
|
||||||
# documentation sections, marked by \if section-label ... \endif
|
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
||||||
# and \cond section-label ... \endcond blocks.
|
# ... \endcond blocks.
|
||||||
|
|
||||||
ENABLED_SECTIONS =
|
ENABLED_SECTIONS =
|
||||||
|
|
||||||
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
|
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
|
||||||
# the initial value of a variable or macro consists of for it to appear in
|
# initial value of a variable or macro / define can have for it to appear in the
|
||||||
# the documentation. If the initializer consists of more lines than specified
|
# documentation. If the initializer consists of more lines than specified here
|
||||||
# here it will be hidden. Use a value of 0 to hide initializers completely.
|
# it will be hidden. Use a value of 0 to hide initializers completely. The
|
||||||
# The appearance of the initializer of individual variables and macros in the
|
# appearance of the value of individual variables and macros / defines can be
|
||||||
# documentation can be controlled using \showinitializer or \hideinitializer
|
# controlled using \showinitializer or \hideinitializer command in the
|
||||||
# command in the documentation regardless of this setting.
|
# documentation regardless of this setting.
|
||||||
|
# Minimum value: 0, maximum value: 10000, default value: 30.
|
||||||
|
|
||||||
MAX_INITIALIZER_LINES = 30
|
MAX_INITIALIZER_LINES = 30
|
||||||
|
|
||||||
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
|
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
|
||||||
# at the bottom of the documentation of classes and structs. If set to YES the
|
# the bottom of the documentation of classes and structs. If set to YES the list
|
||||||
# list will mention the files that were used to generate the documentation.
|
# will mention the files that were used to generate the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
SHOW_USED_FILES = NO
|
SHOW_USED_FILES = NO
|
||||||
|
|
||||||
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
|
# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
|
||||||
# This will remove the Files entry from the Quick Index and from the
|
# will remove the Files entry from the Quick Index and from the Folder Tree View
|
||||||
# Folder Tree View (if specified). The default is YES.
|
# (if specified).
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
SHOW_FILES = YES
|
SHOW_FILES = YES
|
||||||
|
|
||||||
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
|
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
|
||||||
# Namespaces page. This will remove the Namespaces entry from the Quick Index
|
# page. This will remove the Namespaces entry from the Quick Index and from the
|
||||||
# and from the Folder Tree View (if specified). The default is YES.
|
# Folder Tree View (if specified).
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
SHOW_NAMESPACES = YES
|
SHOW_NAMESPACES = YES
|
||||||
|
|
||||||
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
||||||
# doxygen should invoke to get the current version for each file (typically from
|
# doxygen should invoke to get the current version for each file (typically from
|
||||||
# the version control system). Doxygen will invoke the program by executing (via
|
# the version control system). Doxygen will invoke the program by executing (via
|
||||||
# popen()) the command <command> <input-file>, where <command> is the value of
|
# popen()) the command command input-file, where command is the value of the
|
||||||
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
|
# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
|
||||||
# provided by doxygen. Whatever the program writes to standard output
|
# by doxygen. Whatever the program writes to standard output is used as the file
|
||||||
# is used as the file version. See the manual for examples.
|
# version. For an example see the documentation.
|
||||||
|
|
||||||
FILE_VERSION_FILTER =
|
FILE_VERSION_FILTER =
|
||||||
|
|
||||||
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
|
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
|
||||||
# by doxygen. The layout file controls the global structure of the generated
|
# by doxygen. The layout file controls the global structure of the generated
|
||||||
# output files in an output format independent way. To create the layout file
|
# output files in an output format independent way. To create the layout file
|
||||||
# that represents doxygen's defaults, run doxygen with the -l option.
|
# that represents doxygen's defaults, run doxygen with the -l option. You can
|
||||||
# You can optionally specify a file name after the option, if omitted
|
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
|
||||||
# DoxygenLayout.xml will be used as the name of the layout file.
|
# will be used as the name of the layout file.
|
||||||
|
#
|
||||||
|
# Note that if you run doxygen from a directory containing a file called
|
||||||
|
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
|
||||||
|
# tag is left empty.
|
||||||
|
|
||||||
LAYOUT_FILE =
|
LAYOUT_FILE =
|
||||||
|
|
||||||
# The CITE_BIB_FILES tag can be used to specify one or more bib files
|
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||||
# containing the references data. This must be a list of .bib files. The
|
# the reference definitions. This must be a list of .bib files. The .bib
|
||||||
# .bib extension is automatically appended if omitted. Using this command
|
# extension is automatically appended if omitted. This requires the bibtex tool
|
||||||
# requires the bibtex tool to be installed. See also
|
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
|
||||||
# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
|
# For LaTeX the style of the bibliography can be controlled using
|
||||||
# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
|
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
|
||||||
# feature you need bibtex and perl available in the search path. Do not use
|
# search path. Do not use file names with spaces, bibtex cannot handle them. See
|
||||||
# file names with spaces, bibtex cannot handle them.
|
# also \cite for info how to create references.
|
||||||
|
|
||||||
CITE_BIB_FILES =
|
CITE_BIB_FILES =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to warning and progress messages
|
# Configuration options related to warning and progress messages
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# The QUIET tag can be used to turn on/off the messages that are generated
|
# The QUIET tag can be used to turn on/off the messages that are generated to
|
||||||
# by doxygen. Possible values are YES and NO. If left blank NO is used.
|
# standard output by doxygen. If QUIET is set to YES this implies that the
|
||||||
|
# messages are off.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
QUIET = NO
|
QUIET = NO
|
||||||
|
|
||||||
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||||
# generated by doxygen. Possible values are YES and NO. If left blank
|
# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
|
||||||
# NO is used.
|
# this implies that the warnings are on.
|
||||||
|
#
|
||||||
|
# Tip: Turn warnings on while writing the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
WARNINGS = YES
|
WARNINGS = YES
|
||||||
|
|
||||||
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
|
# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
|
||||||
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
|
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
|
||||||
# automatically be disabled.
|
# will automatically be disabled.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
WARN_IF_UNDOCUMENTED = YES
|
WARN_IF_UNDOCUMENTED = YES
|
||||||
|
|
||||||
# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
|
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
|
||||||
# potential errors in the documentation, such as not documenting some
|
# potential errors in the documentation, such as not documenting some parameters
|
||||||
# parameters in a documented function, or documenting parameters that
|
# in a documented function, or documenting parameters that don't exist or using
|
||||||
# don't exist or using markup commands wrongly.
|
# markup commands wrongly.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
WARN_IF_DOC_ERROR = YES
|
WARN_IF_DOC_ERROR = YES
|
||||||
|
|
||||||
# The WARN_NO_PARAMDOC option can be enabled to get warnings for
|
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
|
||||||
# functions that are documented, but have no documentation for their parameters
|
# are documented, but have no documentation for their parameters or return
|
||||||
# or return value. If set to NO (the default) doxygen will only warn about
|
# value. If set to NO doxygen will only warn about wrong or incomplete parameter
|
||||||
# wrong or incomplete parameter documentation, but not about the absence of
|
# documentation, but not about the absence of documentation.
|
||||||
# documentation.
|
# The default value is: NO.
|
||||||
|
|
||||||
WARN_NO_PARAMDOC = NO
|
WARN_NO_PARAMDOC = NO
|
||||||
|
|
||||||
# The WARN_FORMAT tag determines the format of the warning messages that
|
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
|
||||||
# doxygen can produce. The string should contain the $file, $line, and $text
|
# can produce. The string should contain the $file, $line, and $text tags, which
|
||||||
# tags, which will be replaced by the file and line number from which the
|
# will be replaced by the file and line number from which the warning originated
|
||||||
# warning originated and the warning text. Optionally the format may contain
|
# and the warning text. Optionally the format may contain $version, which will
|
||||||
# $version, which will be replaced by the version of the file (if it could
|
# be replaced by the version of the file (if it could be obtained via
|
||||||
# be obtained via FILE_VERSION_FILTER)
|
# FILE_VERSION_FILTER)
|
||||||
|
# The default value is: $file:$line: $text.
|
||||||
|
|
||||||
WARN_FORMAT = "$file:$line: $text"
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
|
||||||
# The WARN_LOGFILE tag can be used to specify a file to which warning
|
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
|
||||||
# and error messages should be written. If left blank the output is written
|
# messages should be written. If left blank the output is written to standard
|
||||||
# to stderr.
|
# error (stderr).
|
||||||
|
|
||||||
WARN_LOGFILE =
|
WARN_LOGFILE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the input files
|
# Configuration options related to the input files
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# The INPUT tag can be used to specify the files and/or directories that contain
|
# 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
|
# documented source files. You may enter file names like myfile.cpp or
|
||||||
# directories like "/usr/src/myproject". Separate the files or directories
|
# directories like /usr/src/myproject. Separate the files or directories with
|
||||||
# with spaces.
|
# spaces.
|
||||||
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = .
|
INPUT = .
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
# also the default input encoding. Doxygen uses libiconv (or the iconv built
|
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||||
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
|
# documentation (see: http://www.gnu.org/software/libiconv) for the list of
|
||||||
# the list of possible encodings.
|
# possible encodings.
|
||||||
|
# The default value is: UTF-8.
|
||||||
|
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
|
|
||||||
# If the value of the INPUT tag contains directories, you can use the
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
|
||||||
# and *.h) to filter out the source-files in the directories. If left
|
# *.h) to filter out the source-files in the directories. If left blank the
|
||||||
# blank the following patterns are tested:
|
# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
|
||||||
# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
|
# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
|
||||||
# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
|
# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
|
||||||
# *.f90 *.f *.for *.vhd *.vhdl
|
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
|
||||||
|
# *.qsf, *.as and *.js.
|
||||||
|
|
||||||
FILE_PATTERNS = *.c \
|
FILE_PATTERNS = *.c \
|
||||||
*.cc \
|
*.cc \
|
||||||
@@ -717,15 +811,16 @@ FILE_PATTERNS = *.c \
|
|||||||
*.vhd \
|
*.vhd \
|
||||||
*.vhdl
|
*.vhdl
|
||||||
|
|
||||||
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||||
# should be searched for input files as well. Possible values are YES and NO.
|
# be searched for input files as well.
|
||||||
# If left blank NO is used.
|
# The default value is: NO.
|
||||||
|
|
||||||
RECURSIVE = NO
|
RECURSIVE = NO
|
||||||
|
|
||||||
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
||||||
# excluded from the INPUT source files. This way you can easily exclude a
|
# excluded from the INPUT source files. This way you can easily exclude a
|
||||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||||
|
#
|
||||||
# Note that relative paths are relative to the directory from which doxygen is
|
# Note that relative paths are relative to the directory from which doxygen is
|
||||||
# run.
|
# run.
|
||||||
|
|
||||||
@@ -734,14 +829,16 @@ EXCLUDE =
|
|||||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||||
# from the input.
|
# from the input.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
EXCLUDE_SYMLINKS = NO
|
EXCLUDE_SYMLINKS = NO
|
||||||
|
|
||||||
# If the value of the INPUT tag contains directories, you can use the
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
||||||
# certain files from those directories. Note that the wildcards are matched
|
# certain files from those directories.
|
||||||
# against the file with absolute path, so to exclude all test directories
|
#
|
||||||
# for example use the pattern */test/*
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
|
# exclude all test directories for example use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_PATTERNS =
|
EXCLUDE_PATTERNS =
|
||||||
|
|
||||||
@@ -750,41 +847,49 @@ EXCLUDE_PATTERNS =
|
|||||||
# output. The symbol name can be a fully qualified name, a word, or if the
|
# output. The symbol name can be a fully qualified name, a word, or if the
|
||||||
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
||||||
# AClass::ANamespace, ANamespace::*Test
|
# AClass::ANamespace, ANamespace::*Test
|
||||||
|
#
|
||||||
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
|
# exclude all test directories use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_SYMBOLS =
|
EXCLUDE_SYMBOLS =
|
||||||
|
|
||||||
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
||||||
# directories that contain example code fragments that are included (see
|
# that contain example code fragments that are included (see the \include
|
||||||
# the \include command).
|
# command).
|
||||||
|
|
||||||
EXAMPLE_PATH = doc/examples
|
EXAMPLE_PATH = doc/examples
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||||
# and *.h) to filter out the source-files in the directories. If left
|
# *.h) to filter out the source-files in the directories. If left blank all
|
||||||
# blank all files are included.
|
# files are included.
|
||||||
|
|
||||||
EXAMPLE_PATTERNS = *
|
EXAMPLE_PATTERNS = *
|
||||||
|
|
||||||
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
||||||
# searched for input files to be used with the \include or \dontinclude
|
# searched for input files to be used with the \include or \dontinclude commands
|
||||||
# commands irrespective of the value of the RECURSIVE tag.
|
# irrespective of the value of the RECURSIVE tag.
|
||||||
# Possible values are YES and NO. If left blank NO is used.
|
# The default value is: NO.
|
||||||
|
|
||||||
EXAMPLE_RECURSIVE = NO
|
EXAMPLE_RECURSIVE = NO
|
||||||
|
|
||||||
# The IMAGE_PATH tag can be used to specify one or more files or
|
# The IMAGE_PATH tag can be used to specify one or more files or directories
|
||||||
# directories that contain image that are included in the documentation (see
|
# that contain images that are to be included in the documentation (see the
|
||||||
# the \image command).
|
# \image command).
|
||||||
|
|
||||||
IMAGE_PATH = doc/images
|
IMAGE_PATH = doc/images
|
||||||
|
|
||||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||||
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
# by executing (via popen()) the command:
|
||||||
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
#
|
||||||
# input file. Doxygen will then use the output that the filter program writes
|
# <filter> <input-file>
|
||||||
# to standard output. If FILTER_PATTERNS is specified, this tag will be ignored.
|
#
|
||||||
|
# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
|
||||||
|
# name of an input file. Doxygen will then use the output that the filter
|
||||||
|
# program writes to standard output. If FILTER_PATTERNS is specified, this tag
|
||||||
|
# will be ignored.
|
||||||
|
#
|
||||||
# Note that the filter must not add or remove lines; it is applied before the
|
# 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
|
# code is scanned, but not when the output code is generated. If lines are added
|
||||||
# or removed, the anchors will not be placed correctly.
|
# or removed, the anchors will not be placed correctly.
|
||||||
@@ -793,168 +898,221 @@ INPUT_FILTER =
|
|||||||
|
|
||||||
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
||||||
# basis. Doxygen will compare the file name with each pattern and apply the
|
# basis. Doxygen will compare the file name with each pattern and apply the
|
||||||
# filter if there is a match. The filters are a list of the form:
|
# filter if there is a match. The filters are a list of the form: pattern=filter
|
||||||
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
|
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
|
||||||
# info on how filters are used. If FILTER_PATTERNS is empty or if
|
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
|
||||||
# non of the patterns match the file name, INPUT_FILTER is applied.
|
# patterns match the file name, INPUT_FILTER is applied.
|
||||||
|
|
||||||
FILTER_PATTERNS =
|
FILTER_PATTERNS =
|
||||||
|
|
||||||
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
||||||
# INPUT_FILTER) will be used to filter the input files when producing source
|
# INPUT_FILTER ) will also be used to filter the input files that are used for
|
||||||
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
|
# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
FILTER_SOURCE_FILES = NO
|
FILTER_SOURCE_FILES = NO
|
||||||
|
|
||||||
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
|
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
|
||||||
# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
|
# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
|
||||||
# and it is also possible to disable source filtering for a specific pattern
|
# it is also possible to disable source filtering for a specific pattern using
|
||||||
# using *.ext= (so without naming a filter). This option only has effect when
|
# *.ext= (so without naming a filter).
|
||||||
# FILTER_SOURCE_FILES is enabled.
|
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
|
||||||
|
|
||||||
FILTER_SOURCE_PATTERNS =
|
FILTER_SOURCE_PATTERNS =
|
||||||
|
|
||||||
# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
|
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
|
||||||
# is part of the input, its contents will be placed on the main page
|
# is part of the input, its contents will be placed on the main page
|
||||||
# (index.html). This can be useful if you have a project on for instance GitHub
|
# (index.html). This can be useful if you have a project on for instance GitHub
|
||||||
# and want reuse the introduction page also for the doxygen output.
|
# and want to reuse the introduction page also for the doxygen output.
|
||||||
|
|
||||||
USE_MDFILE_AS_MAINPAGE =
|
USE_MDFILE_AS_MAINPAGE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to source browsing
|
# Configuration options related to source browsing
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
|
# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
|
||||||
# be generated. Documented entities will be cross-referenced with these sources.
|
# generated. Documented entities will be cross-referenced with these sources.
|
||||||
# Note: To get rid of all source code in the generated output, make sure also
|
#
|
||||||
# VERBATIM_HEADERS is set to NO.
|
# Note: To get rid of all source code in the generated output, make sure that
|
||||||
|
# also VERBATIM_HEADERS is set to NO.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SOURCE_BROWSER = NO
|
SOURCE_BROWSER = NO
|
||||||
|
|
||||||
# Setting the INLINE_SOURCES tag to YES will include the body
|
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
|
||||||
# of functions and classes directly in the documentation.
|
# classes and enums directly into the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
INLINE_SOURCES = NO
|
INLINE_SOURCES = NO
|
||||||
|
|
||||||
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
|
# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
|
||||||
# doxygen to hide any special comment blocks from generated source code
|
# special comment blocks from generated source code fragments. Normal C, C++ and
|
||||||
# fragments. Normal C, C++ and Fortran comments will always remain visible.
|
# Fortran comments will always remain visible.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
STRIP_CODE_COMMENTS = YES
|
STRIP_CODE_COMMENTS = YES
|
||||||
|
|
||||||
# If the REFERENCED_BY_RELATION tag is set to YES
|
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
|
||||||
# then for each documented function all documented
|
# function all documented functions referencing it will be listed.
|
||||||
# functions referencing it will be listed.
|
# The default value is: NO.
|
||||||
|
|
||||||
REFERENCED_BY_RELATION = NO
|
REFERENCED_BY_RELATION = NO
|
||||||
|
|
||||||
# If the REFERENCES_RELATION tag is set to YES
|
# If the REFERENCES_RELATION tag is set to YES then for each documented function
|
||||||
# then for each documented function all documented entities
|
# all documented entities called/used by that function will be listed.
|
||||||
# called/used by that function will be listed.
|
# The default value is: NO.
|
||||||
|
|
||||||
REFERENCES_RELATION = NO
|
REFERENCES_RELATION = NO
|
||||||
|
|
||||||
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
|
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
|
||||||
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
|
# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
|
||||||
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
|
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
|
||||||
# link to the source code. Otherwise they will link to the documentation.
|
# link to the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
REFERENCES_LINK_SOURCE = YES
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
|
||||||
# If the USE_HTAGS tag is set to YES then the references to source code
|
# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
|
||||||
# will point to the HTML generated by the htags(1) tool instead of doxygen
|
# source code will show a tooltip with additional information such as prototype,
|
||||||
# built-in source browser. The htags tool is part of GNU's global source
|
# brief description and links to the definition and documentation. Since this
|
||||||
# tagging system (see http://www.gnu.org/software/global/global.html). You
|
# will make the HTML file larger and loading of large files a bit slower, you
|
||||||
# will need version 4.8.6 or higher.
|
# can opt to disable this feature.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag SOURCE_BROWSER is set to YES.
|
||||||
|
|
||||||
|
SOURCE_TOOLTIPS = YES
|
||||||
|
|
||||||
|
# If the USE_HTAGS tag is set to YES then the references to source code will
|
||||||
|
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
|
||||||
|
# source browser. The htags tool is part of GNU's global source tagging system
|
||||||
|
# (see http://www.gnu.org/software/global/global.html). You will need version
|
||||||
|
# 4.8.6 or higher.
|
||||||
|
#
|
||||||
|
# To use it do the following:
|
||||||
|
# - Install the latest version of global
|
||||||
|
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
|
||||||
|
# - Make sure the INPUT points to the root of the source tree
|
||||||
|
# - Run doxygen as normal
|
||||||
|
#
|
||||||
|
# Doxygen will invoke htags (and that will in turn invoke gtags), so these
|
||||||
|
# tools must be available from the command line (i.e. in the search path).
|
||||||
|
#
|
||||||
|
# The result: instead of the source browser generated by doxygen, the links to
|
||||||
|
# source code will now point to the output of htags.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag SOURCE_BROWSER is set to YES.
|
||||||
|
|
||||||
USE_HTAGS = NO
|
USE_HTAGS = NO
|
||||||
|
|
||||||
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
|
# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
|
||||||
# will generate a verbatim copy of the header file for each class for
|
# verbatim copy of the header file for each class for which an include is
|
||||||
# which an include is specified. Set to NO to disable this.
|
# specified. Set to NO to disable this.
|
||||||
|
# See also: Section \class.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
VERBATIM_HEADERS = NO
|
VERBATIM_HEADERS = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the alphabetical class index
|
# Configuration options related to the alphabetical class index
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
|
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
|
||||||
# of all compounds will be generated. Enable this if the project
|
# compounds will be generated. Enable this if the project contains a lot of
|
||||||
# contains a lot of classes, structs, unions or interfaces.
|
# classes, structs, unions or interfaces.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
ALPHABETICAL_INDEX = YES
|
ALPHABETICAL_INDEX = YES
|
||||||
|
|
||||||
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
|
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||||
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
# which the alphabetical index list will be split.
|
||||||
# in which this list will be split (can be a number in the range [1..20])
|
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||||
|
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||||
|
|
||||||
COLS_IN_ALPHA_INDEX = 5
|
COLS_IN_ALPHA_INDEX = 5
|
||||||
|
|
||||||
# In case all classes in a project start with a common prefix, all
|
# In case all classes in a project start with a common prefix, all classes will
|
||||||
# classes will be put under the same header in the alphabetical index.
|
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||||
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
|
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||||
# should be ignored while generating the index headers.
|
# while generating the index headers.
|
||||||
|
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||||
|
|
||||||
IGNORE_PREFIX =
|
IGNORE_PREFIX =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the HTML output
|
# Configuration options related to the HTML output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
|
# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
|
||||||
# generate HTML output.
|
# The default value is: YES.
|
||||||
|
|
||||||
GENERATE_HTML = YES
|
GENERATE_HTML = YES
|
||||||
|
|
||||||
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
|
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
# put in front of it. If left blank `html' will be used as the default path.
|
# it.
|
||||||
|
# The default directory is: html.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_OUTPUT = html
|
HTML_OUTPUT = html
|
||||||
|
|
||||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
|
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||||
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
|
# generated HTML page (for example: .htm, .php, .asp).
|
||||||
# doxygen will generate files with .html extension.
|
# The default value is: .html.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_FILE_EXTENSION = .html
|
HTML_FILE_EXTENSION = .html
|
||||||
|
|
||||||
# The HTML_HEADER tag can be used to specify a personal HTML header for
|
# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
|
||||||
# each generated HTML page. If it is left blank doxygen will generate a
|
# each generated HTML page. If the tag is left blank doxygen will generate a
|
||||||
# standard header. Note that when using a custom header you are responsible
|
# standard header.
|
||||||
# for the proper inclusion of any scripts and style sheets that doxygen
|
#
|
||||||
# needs, which is dependent on the configuration options used.
|
# To get valid HTML the header file that includes any scripts and style sheets
|
||||||
# It is advised to generate a default header using "doxygen -w html
|
# that doxygen needs, which is dependent on the configuration options used (e.g.
|
||||||
# header.html footer.html stylesheet.css YourConfigFile" and then modify
|
# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
|
||||||
# that header. Note that the header is subject to change so you typically
|
# default header using
|
||||||
# have to redo this when upgrading to a newer version of doxygen or when
|
# doxygen -w html new_header.html new_footer.html new_stylesheet.css
|
||||||
# changing the value of configuration settings such as GENERATE_TREEVIEW!
|
# YourConfigFile
|
||||||
|
# and then modify the file new_header.html. See also section "Doxygen usage"
|
||||||
|
# for information on how to generate the default header that doxygen normally
|
||||||
|
# uses.
|
||||||
|
# Note: The header is subject to change so you typically have to regenerate the
|
||||||
|
# default header when upgrading to a newer version of doxygen. For a description
|
||||||
|
# of the possible markers and block names see the documentation.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_HEADER =
|
HTML_HEADER =
|
||||||
|
|
||||||
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||||
# each generated HTML page. If it is left blank doxygen will generate a
|
# generated HTML page. If the tag is left blank doxygen will generate a standard
|
||||||
# standard footer.
|
# footer. See HTML_HEADER for more information on how to generate a default
|
||||||
|
# footer and what special commands can be used inside the footer. See also
|
||||||
|
# section "Doxygen usage" for information on how to generate the default footer
|
||||||
|
# that doxygen normally uses.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_FOOTER =
|
HTML_FOOTER =
|
||||||
|
|
||||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||||
# style sheet that is used by each HTML page. It can be used to
|
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||||
# fine-tune the look of the HTML output. If left blank doxygen will
|
# the HTML output. If left blank doxygen will generate a default style sheet.
|
||||||
# generate a default style sheet. Note that it is recommended to use
|
# See also section "Doxygen usage" for information on how to generate the style
|
||||||
# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
|
# sheet that doxygen normally uses.
|
||||||
# tag will in the future become obsolete.
|
# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
|
||||||
|
# it is more robust and this tag (HTML_STYLESHEET) will in the future become
|
||||||
|
# obsolete.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_STYLESHEET =
|
HTML_STYLESHEET =
|
||||||
|
|
||||||
# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
|
# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
|
||||||
# user-defined cascading style sheet that is included after the standard
|
# defined cascading style sheet that is included after the standard style sheets
|
||||||
# style sheets created by doxygen. Using this option one can overrule
|
# created by doxygen. Using this option one can overrule certain style aspects.
|
||||||
# certain style aspects. This is preferred over using HTML_STYLESHEET
|
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
||||||
# since it does not replace the standard style sheet and is therefor more
|
# standard style sheet and is therefor more robust against future updates.
|
||||||
# robust against future updates. Doxygen will copy the style sheet file to
|
# Doxygen will copy the style sheet file to the output directory. For an example
|
||||||
# the output directory.
|
# see the documentation.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_EXTRA_STYLESHEET =
|
HTML_EXTRA_STYLESHEET =
|
||||||
|
|
||||||
@@ -962,629 +1120,807 @@ HTML_EXTRA_STYLESHEET =
|
|||||||
# other source files which should be copied to the HTML output directory. Note
|
# other source files which should be copied to the HTML output directory. Note
|
||||||
# that these files will be copied to the base HTML output directory. Use the
|
# that these files will be copied to the base HTML output directory. Use the
|
||||||
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
|
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
|
||||||
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
|
# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
|
||||||
# the files will be copied as-is; there are no commands or markers available.
|
# files will be copied as-is; there are no commands or markers available.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_EXTRA_FILES =
|
HTML_EXTRA_FILES =
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||||
# Doxygen will adjust the colors in the style sheet and background images
|
# will adjust the colors in the stylesheet and background images according to
|
||||||
# according to this color. Hue is specified as an angle on a colorwheel,
|
# this color. Hue is specified as an angle on a colorwheel, see
|
||||||
# see http://en.wikipedia.org/wiki/Hue for more information.
|
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
|
||||||
# For instance the value 0 represents red, 60 is yellow, 120 is green,
|
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
|
||||||
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
|
# purple, and 360 is red again.
|
||||||
# The allowed range is 0 to 359.
|
# Minimum value: 0, maximum value: 359, default value: 220.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_COLORSTYLE_HUE = 246
|
HTML_COLORSTYLE_HUE = 246
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
|
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
|
||||||
# the colors in the HTML output. For a value of 0 the output will use
|
# in the HTML output. For a value of 0 the output will use grayscales only. A
|
||||||
# grayscales only. A value of 255 will produce the most vivid colors.
|
# value of 255 will produce the most vivid colors.
|
||||||
|
# Minimum value: 0, maximum value: 255, default value: 100.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_COLORSTYLE_SAT = 79
|
HTML_COLORSTYLE_SAT = 79
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
|
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
|
||||||
# the luminance component of the colors in the HTML output. Values below
|
# luminance component of the colors in the HTML output. Values below 100
|
||||||
# 100 gradually make the output lighter, whereas values above 100 make
|
# gradually make the output lighter, whereas values above 100 make the output
|
||||||
# the output darker. The value divided by 100 is the actual gamma applied,
|
# darker. The value divided by 100 is the actual gamma applied, so 80 represents
|
||||||
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
|
# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
|
||||||
# and 100 does not change the gamma.
|
# change the gamma.
|
||||||
|
# Minimum value: 40, maximum value: 240, default value: 80.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_COLORSTYLE_GAMMA = 75
|
HTML_COLORSTYLE_GAMMA = 75
|
||||||
|
|
||||||
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
|
# 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
|
# page will contain the date and time when the page was generated. Setting this
|
||||||
# this to NO can help when comparing the output of multiple runs.
|
# to NO can help when comparing the output of multiple runs.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_TIMESTAMP = YES
|
HTML_TIMESTAMP = YES
|
||||||
|
|
||||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||||
# documentation will contain sections that can be hidden and shown after the
|
# documentation will contain sections that can be hidden and shown after the
|
||||||
# page has loaded.
|
# page has loaded.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_DYNAMIC_SECTIONS = YES
|
HTML_DYNAMIC_SECTIONS = YES
|
||||||
|
|
||||||
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
|
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
|
||||||
# entries shown in the various tree structured indices initially; the user
|
# shown in the various tree structured indices initially; the user can expand
|
||||||
# can expand and collapse entries dynamically later on. Doxygen will expand
|
# and collapse entries dynamically later on. Doxygen will expand the tree to
|
||||||
# the tree to such a level that at most the specified number of entries are
|
# such a level that at most the specified number of entries are visible (unless
|
||||||
# visible (unless a fully collapsed tree already exceeds this amount).
|
# a fully collapsed tree already exceeds this amount). So setting the number of
|
||||||
# So setting the number of entries 1 will produce a full collapsed tree by
|
# entries 1 will produce a full collapsed tree by default. 0 is a special value
|
||||||
# default. 0 is a special value representing an infinite number of entries
|
# representing an infinite number of entries and will result in a full expanded
|
||||||
# and will result in a full expanded tree by default.
|
# tree by default.
|
||||||
|
# Minimum value: 0, maximum value: 9999, default value: 100.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_INDEX_NUM_ENTRIES = 100
|
HTML_INDEX_NUM_ENTRIES = 100
|
||||||
|
|
||||||
# If the GENERATE_DOCSET tag is set to YES, additional index files
|
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
||||||
# will be generated that can be used as input for Apple's Xcode 3
|
# generated that can be used as input for Apple's Xcode 3 integrated development
|
||||||
# integrated development environment, introduced with OSX 10.5 (Leopard).
|
# environment (see: http://developer.apple.com/tools/xcode/), introduced with
|
||||||
# To create a documentation set, doxygen will generate a Makefile in the
|
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
|
||||||
# HTML output directory. Running make will produce the docset in that
|
# Makefile in the HTML output directory. Running make will produce the docset in
|
||||||
# directory and running "make install" will install the docset in
|
# that directory and running make install will install the docset in
|
||||||
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
|
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
||||||
# it at startup.
|
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
|
||||||
# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
|
|
||||||
# for more information.
|
# for more information.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
GENERATE_DOCSET = NO
|
GENERATE_DOCSET = NO
|
||||||
|
|
||||||
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
|
# This tag determines the name of the docset feed. A documentation feed provides
|
||||||
# feed. A documentation feed provides an umbrella under which multiple
|
# an umbrella under which multiple documentation sets from a single provider
|
||||||
# documentation sets from a single provider (such as a company or product suite)
|
# (such as a company or product suite) can be grouped.
|
||||||
# can be grouped.
|
# The default value is: Doxygen generated docs.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||||
|
|
||||||
# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
|
# This tag specifies a string that should uniquely identify the documentation
|
||||||
# should uniquely identify the documentation set bundle. This should be a
|
# set bundle. This should be a reverse domain-name style string, e.g.
|
||||||
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
|
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
|
||||||
# will append .docset to the name.
|
# The default value is: org.doxygen.Project.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||||
|
|
||||||
# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
|
# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
|
||||||
# identify the documentation publisher. This should be a reverse domain-name
|
# the documentation publisher. This should be a reverse domain-name style
|
||||||
# style string, e.g. com.mycompany.MyDocSet.documentation.
|
# string, e.g. com.mycompany.MyDocSet.documentation.
|
||||||
|
# The default value is: org.doxygen.Publisher.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||||
|
|
||||||
# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
|
# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
|
||||||
|
# The default value is: Publisher.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
DOCSET_PUBLISHER_NAME = Publisher
|
DOCSET_PUBLISHER_NAME = Publisher
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
|
||||||
# will be generated that can be used as input for tools like the
|
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
||||||
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
|
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
||||||
# of the generated HTML documentation.
|
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
|
||||||
|
# Windows.
|
||||||
|
#
|
||||||
|
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
||||||
|
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
|
||||||
|
# files are now used as the Windows 98 help format, and will replace the old
|
||||||
|
# Windows help format (.hlp) on all Windows platforms in the future. Compressed
|
||||||
|
# HTML files also contain an index, a table of contents, and you can search for
|
||||||
|
# words in the documentation. The HTML workshop also contains a viewer for
|
||||||
|
# compressed HTML files.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
GENERATE_HTMLHELP = NO
|
GENERATE_HTMLHELP = NO
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
|
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
|
||||||
# be used to specify the file name of the resulting .chm file. You
|
# file. You can add a path in front of the file if the result should not be
|
||||||
# can add a path in front of the file if the result should not be
|
|
||||||
# written to the html output directory.
|
# written to the html output directory.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
CHM_FILE =
|
CHM_FILE =
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
|
# The HHC_LOCATION tag can be used to specify the location (absolute path
|
||||||
# be used to specify the location (absolute path including file name) of
|
# including file name) of the HTML help compiler ( hhc.exe). If non-empty
|
||||||
# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
|
# doxygen will try to run the HTML help compiler on the generated index.hhp.
|
||||||
# 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 =
|
HHC_LOCATION =
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
|
# The GENERATE_CHI flag controls if a separate .chi index file is generated (
|
||||||
# controls if a separate .chi index file is generated (YES) or that
|
# YES) or that it should be included in the master .chm file ( NO).
|
||||||
# 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
|
GENERATE_CHI = NO
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
|
# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
|
||||||
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
|
# and project file content.
|
||||||
# content.
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
CHM_INDEX_ENCODING =
|
CHM_INDEX_ENCODING =
|
||||||
|
|
||||||
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
|
# The BINARY_TOC flag controls whether a binary table of contents is generated (
|
||||||
# controls whether a binary table of contents is generated (YES) or a
|
# YES) or a normal table of contents ( NO) in the .chm file.
|
||||||
# normal table of contents (NO) in the .chm file.
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
BINARY_TOC = NO
|
BINARY_TOC = NO
|
||||||
|
|
||||||
# The TOC_EXPAND flag can be set to YES to add extra items for group members
|
# The TOC_EXPAND flag can be set to YES to add extra items for group members to
|
||||||
# to the contents of the HTML help documentation and to the tree view.
|
# the table of contents of the HTML help documentation and to the tree view.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
TOC_EXPAND = NO
|
TOC_EXPAND = NO
|
||||||
|
|
||||||
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
|
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
|
||||||
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
|
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
|
||||||
# that can be used as input for Qt's qhelpgenerator to generate a
|
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
|
||||||
# Qt Compressed Help (.qch) of the generated HTML documentation.
|
# (.qch) of the generated HTML documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
GENERATE_QHP = YES
|
GENERATE_QHP = YES
|
||||||
|
|
||||||
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
|
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
|
||||||
# be used to specify the file name of the resulting .qch file.
|
# the file name of the resulting .qch file. The path specified is relative to
|
||||||
# The path specified is relative to the HTML output folder.
|
# the HTML output folder.
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QCH_FILE = pip.qhp
|
QCH_FILE = pip.qhp
|
||||||
|
|
||||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating
|
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||||
# Qt Help Project output. For more information please see
|
# Project output. For more information please see Qt Help Project / Namespace
|
||||||
# http://doc.trolltech.com/qthelpproject.html#namespace
|
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
|
||||||
|
# The default value is: org.doxygen.Project.
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHP_NAMESPACE = PIP
|
QHP_NAMESPACE = PIP
|
||||||
|
|
||||||
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
|
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
||||||
# Qt Help Project output. For more information please see
|
# Help Project output. For more information please see Qt Help Project / Virtual
|
||||||
# http://doc.trolltech.com/qthelpproject.html#virtual-folders
|
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
|
||||||
|
# folders).
|
||||||
|
# The default value is: doc.
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHP_VIRTUAL_FOLDER = doc
|
QHP_VIRTUAL_FOLDER = doc
|
||||||
|
|
||||||
# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
|
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
||||||
# add. For more information please see
|
# filter to add. For more information please see Qt Help Project / Custom
|
||||||
# http://doc.trolltech.com/qthelpproject.html#custom-filters
|
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
|
||||||
|
# filters).
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHP_CUST_FILTER_NAME =
|
QHP_CUST_FILTER_NAME =
|
||||||
|
|
||||||
# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
|
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||||
# custom filter to add. For more information please see
|
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||||
# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
|
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
|
||||||
# Qt Help Project / Custom Filters</a>.
|
# filters).
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHP_CUST_FILTER_ATTRS =
|
QHP_CUST_FILTER_ATTRS =
|
||||||
|
|
||||||
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
||||||
# project's
|
# project's filter section matches. Qt Help Project / Filter Attributes (see:
|
||||||
# filter section matches.
|
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
|
||||||
# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
# Qt Help Project / Filter Attributes</a>.
|
|
||||||
|
|
||||||
QHP_SECT_FILTER_ATTRS =
|
QHP_SECT_FILTER_ATTRS =
|
||||||
|
|
||||||
# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
|
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
||||||
# be used to specify the location of Qt's qhelpgenerator.
|
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
||||||
# If non-empty doxygen will try to run qhelpgenerator on the generated
|
# generated .qhp file.
|
||||||
# .qhp file.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHG_LOCATION = qhelpgenerator
|
QHG_LOCATION = qhelpgenerator
|
||||||
|
|
||||||
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
|
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
|
||||||
# will be generated, which together with the HTML files, form an Eclipse help
|
# generated, together with the HTML files, they form an Eclipse help plugin. To
|
||||||
# plugin. To install this plugin and make it available under the help contents
|
# install this plugin and make it available under the help contents menu in
|
||||||
# menu in Eclipse, the contents of the directory containing the HTML and XML
|
# Eclipse, the contents of the directory containing the HTML and XML files needs
|
||||||
# files needs to be copied into the plugins directory of eclipse. The name of
|
# to be copied into the plugins directory of eclipse. The name of the directory
|
||||||
# the directory within the plugins directory should be the same as
|
# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
|
||||||
# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
|
# After copying Eclipse needs to be restarted before the help appears.
|
||||||
# the help appears.
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
GENERATE_ECLIPSEHELP = NO
|
GENERATE_ECLIPSEHELP = NO
|
||||||
|
|
||||||
# A unique identifier for the eclipse help plugin. When installing the plugin
|
# A unique identifier for the Eclipse help plugin. When installing the plugin
|
||||||
# the directory name containing the HTML and XML files should also have
|
# the directory name containing the HTML and XML files should also have this
|
||||||
# this name.
|
# name. Each documentation set should have its own identifier.
|
||||||
|
# The default value is: org.doxygen.Project.
|
||||||
|
# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
|
||||||
|
|
||||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||||
|
|
||||||
# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
|
# If you want full control over the layout of the generated HTML pages it might
|
||||||
# at top of each HTML page. The value NO (the default) enables the index and
|
# be necessary to disable the index and replace it with your own. The
|
||||||
# the value YES disables it. Since the tabs have the same information as the
|
# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
|
||||||
# navigation tree you can set this option to NO if you already set
|
# of each HTML page. A value of NO enables the index and the value YES disables
|
||||||
# GENERATE_TREEVIEW to YES.
|
# it. Since the tabs in the index contain the same information as the navigation
|
||||||
|
# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
DISABLE_INDEX = NO
|
DISABLE_INDEX = NO
|
||||||
|
|
||||||
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
|
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
|
||||||
# structure should be generated to display hierarchical information.
|
# structure should be generated to display hierarchical information. If the tag
|
||||||
# If the tag value is set to YES, a side panel will be generated
|
# value is set to YES, a side panel will be generated containing a tree-like
|
||||||
# containing a tree-like index structure (just like the one that
|
# index structure (just like the one that is generated for HTML Help). For this
|
||||||
# is generated for HTML Help). For this to work a browser that supports
|
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
|
||||||
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
|
# (i.e. any modern browser). Windows users are probably better off using the
|
||||||
# Windows users are probably better off using the HTML help feature.
|
# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
|
||||||
# Since the tree basically has the same information as the tab index you
|
# further fine-tune the look of the index. As an example, the default style
|
||||||
# could consider to set DISABLE_INDEX to NO when enabling this option.
|
# 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
|
||||||
|
# the same information as the tab index, you could consider setting
|
||||||
|
# DISABLE_INDEX to YES when enabling this option.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
GENERATE_TREEVIEW = YES
|
GENERATE_TREEVIEW = YES
|
||||||
|
|
||||||
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
|
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
|
||||||
# (range [0,1..20]) that doxygen will group on one line in the generated HTML
|
# doxygen will group on one line in the generated HTML documentation.
|
||||||
# documentation. Note that a value of 0 will completely suppress the enum
|
#
|
||||||
# values from appearing in the overview section.
|
# Note that a value of 0 will completely suppress the enum values from appearing
|
||||||
|
# in the overview section.
|
||||||
|
# Minimum value: 0, maximum value: 20, default value: 4.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
ENUM_VALUES_PER_LINE = 4
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
|
||||||
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
|
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
|
||||||
# used to set the initial width (in pixels) of the frame in which the tree
|
# to set the initial width (in pixels) of the frame in which the tree is shown.
|
||||||
# is shown.
|
# Minimum value: 0, maximum value: 1500, default value: 250.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
TREEVIEW_WIDTH = 250
|
TREEVIEW_WIDTH = 250
|
||||||
|
|
||||||
# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
|
# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
|
||||||
# links to external symbols imported via tag files in a separate window.
|
# 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.
|
||||||
|
|
||||||
EXT_LINKS_IN_WINDOW = NO
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
|
||||||
# Use this tag to change the font size of Latex formulas included
|
# Use this tag to change the font size of LaTeX formulas included as images in
|
||||||
# as images in the HTML documentation. The default is 10. Note that
|
# the HTML documentation. When you change the font size after a successful
|
||||||
# when you change the font size after a successful doxygen run you need
|
# doxygen run you need to manually remove any form_*.png images from the HTML
|
||||||
# to manually remove any form_*.png images from the HTML output directory
|
# output directory to force them to be regenerated.
|
||||||
# to force them to be regenerated.
|
# Minimum value: 8, maximum value: 50, default value: 10.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
FORMULA_FONTSIZE = 10
|
FORMULA_FONTSIZE = 10
|
||||||
|
|
||||||
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
|
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
|
||||||
# generated for formulas are transparent PNGs. Transparent PNGs are
|
# generated for formulas are transparent PNGs. Transparent PNGs are not
|
||||||
# not supported properly for IE 6.0, but are supported on all modern browsers.
|
# supported properly for IE 6.0, but are supported on all modern browsers.
|
||||||
# Note that when changing this option you need to delete any form_*.png files
|
#
|
||||||
# in the HTML output before the changes have effect.
|
# Note that when changing this option you need to delete any form_*.png files in
|
||||||
|
# the HTML output directory before the changes have effect.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
FORMULA_TRANSPARENT = YES
|
FORMULA_TRANSPARENT = YES
|
||||||
|
|
||||||
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
|
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
||||||
# (see http://www.mathjax.org) which uses client side Javascript for the
|
# http://www.mathjax.org) which uses client side Javascript for the rendering
|
||||||
# rendering instead of using prerendered bitmaps. Use this if you do not
|
# instead of using prerendered bitmaps. Use this if you do not have LaTeX
|
||||||
# have LaTeX installed or if you want to formulas look prettier in the HTML
|
# installed or if you want to formulas look prettier in the HTML output. When
|
||||||
# output. When enabled you may also need to install MathJax separately and
|
# enabled you may also need to install MathJax separately and configure the path
|
||||||
# configure the path to it using the MATHJAX_RELPATH option.
|
# to it using the MATHJAX_RELPATH option.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
USE_MATHJAX = NO
|
USE_MATHJAX = NO
|
||||||
|
|
||||||
# When MathJax is enabled you can set the default output format to be used for
|
# When MathJax is enabled you can set the default output format to be used for
|
||||||
# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
|
# the MathJax output. See the MathJax site (see:
|
||||||
# SVG. The default value is HTML-CSS, which is slower, but has the best
|
# http://docs.mathjax.org/en/latest/output.html) for more details.
|
||||||
# compatibility.
|
# Possible values are: HTML-CSS (which is slower, but has the best
|
||||||
|
# compatibility), NativeMML (i.e. MathML) and SVG.
|
||||||
|
# The default value is: HTML-CSS.
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_FORMAT = HTML-CSS
|
MATHJAX_FORMAT = HTML-CSS
|
||||||
|
|
||||||
# When MathJax is enabled you need to specify the location relative to the
|
# When MathJax is enabled you need to specify the location relative to the HTML
|
||||||
# HTML output directory using the MATHJAX_RELPATH option. The destination
|
# output directory using the MATHJAX_RELPATH option. The destination directory
|
||||||
# directory should contain the MathJax.js script. For instance, if the mathjax
|
# should contain the MathJax.js script. For instance, if the mathjax directory
|
||||||
# directory is located at the same level as the HTML output directory, then
|
# is located at the same level as the HTML output directory, then
|
||||||
# MATHJAX_RELPATH should be ../mathjax. The default value points to
|
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
|
||||||
# the MathJax Content Delivery Network so you can quickly see the result without
|
# Content Delivery Network so you can quickly see the result without installing
|
||||||
# installing MathJax. However, it is strongly recommended to install a local
|
# MathJax. However, it is strongly recommended to install a local copy of
|
||||||
# copy of MathJax from http://www.mathjax.org before deployment.
|
# MathJax from http://www.mathjax.org before deployment.
|
||||||
|
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||||
|
|
||||||
# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
|
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
||||||
# names that should be enabled during MathJax rendering.
|
# extension names that should be enabled during MathJax rendering. For example
|
||||||
|
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_EXTENSIONS =
|
MATHJAX_EXTENSIONS =
|
||||||
|
|
||||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
|
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||||
# pieces of code that will be used on startup of the MathJax code.
|
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||||
|
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
|
||||||
|
# example see the documentation.
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_CODEFILE =
|
MATHJAX_CODEFILE =
|
||||||
|
|
||||||
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
|
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
|
||||||
# for the HTML output. The underlying search engine uses javascript
|
# the HTML output. The underlying search engine uses javascript and DHTML and
|
||||||
# and DHTML and should work on any modern browser. Note that when using
|
# should work on any modern browser. Note that when using HTML help
|
||||||
# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
|
# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
|
||||||
# (GENERATE_DOCSET) there is already a search function so this one should
|
# there is already a search function so this one should typically be disabled.
|
||||||
# typically be disabled. For large projects the javascript based search engine
|
# For large projects the javascript based search engine can be slow, then
|
||||||
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
|
# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
|
||||||
|
# search using the keyboard; to jump to the search box use <access key> + S
|
||||||
|
# (what the <access key> is depends on the OS and browser, but it is typically
|
||||||
|
# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
|
||||||
|
# key> to jump into the search results window, the results can be navigated
|
||||||
|
# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
|
||||||
|
# the search. The filter options can be selected when the cursor is inside the
|
||||||
|
# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
|
||||||
|
# to select a filter and <Enter> or <escape> to activate or cancel the filter
|
||||||
|
# option.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
SEARCHENGINE = YES
|
SEARCHENGINE = YES
|
||||||
|
|
||||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
# 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.
|
# implemented using a web server instead of a web client using Javascript. There
|
||||||
# There are two flavours of web server based search depending on the
|
# are two flavours of web server based searching depending on the
|
||||||
# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
|
# 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
|
# 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.
|
# enabled the indexing and searching needs to be provided by external tools. See
|
||||||
# See the manual for details.
|
# the section "External Indexing and Searching" for details.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
SERVER_BASED_SEARCH = NO
|
SERVER_BASED_SEARCH = NO
|
||||||
|
|
||||||
# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
|
# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
|
||||||
# script for searching. Instead the search results are written to an XML file
|
# script for searching. Instead the search results are written to an XML file
|
||||||
# which needs to be processed by an external indexer. Doxygen will invoke an
|
# which needs to be processed by an external indexer. Doxygen will invoke an
|
||||||
# external search engine pointed to by the SEARCHENGINE_URL option to obtain
|
# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
|
||||||
# the search results. Doxygen ships with an example indexer (doxyindexer) and
|
# search results.
|
||||||
# search engine (doxysearch.cgi) which are based on the open source search
|
#
|
||||||
# engine library Xapian. See the manual for configuration details.
|
# 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.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
EXTERNAL_SEARCH = NO
|
EXTERNAL_SEARCH = NO
|
||||||
|
|
||||||
# The SEARCHENGINE_URL should point to a search engine hosted by a web server
|
# The SEARCHENGINE_URL should point to a search engine hosted by a web server
|
||||||
# which will returned the search results when EXTERNAL_SEARCH is enabled.
|
# which will return the search results when EXTERNAL_SEARCH is enabled.
|
||||||
# Doxygen ships with an example search engine (doxysearch) which is based on
|
#
|
||||||
# the open source search engine library Xapian. See the manual for configuration
|
# Doxygen ships with an example indexer ( doxyindexer) and search engine
|
||||||
# details.
|
# (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.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
SEARCHENGINE_URL =
|
SEARCHENGINE_URL =
|
||||||
|
|
||||||
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
|
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
|
||||||
# search data is written to a file for indexing by an external tool. With the
|
# search data is written to a file for indexing by an external tool. With the
|
||||||
# SEARCHDATA_FILE tag the name of this file can be specified.
|
# SEARCHDATA_FILE tag the name of this file can be specified.
|
||||||
|
# The default file is: searchdata.xml.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
SEARCHDATA_FILE = searchdata.xml
|
SEARCHDATA_FILE = searchdata.xml
|
||||||
|
|
||||||
# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
|
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
|
||||||
# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
|
# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
|
||||||
# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
|
# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
|
||||||
# projects and redirect the results back to the right project.
|
# projects and redirect the results back to the right project.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
EXTERNAL_SEARCH_ID =
|
EXTERNAL_SEARCH_ID =
|
||||||
|
|
||||||
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
|
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
|
||||||
# projects other than the one defined by this configuration file, but that are
|
# projects other than the one defined by this configuration file, but that are
|
||||||
# all added to the same external search index. Each project needs to have a
|
# all added to the same external search index. Each project needs to have a
|
||||||
# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
|
# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
|
||||||
# of to a relative location where the documentation can be found.
|
# to a relative location where the documentation can be found. The format is:
|
||||||
# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
|
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
EXTRA_SEARCH_MAPPINGS =
|
EXTRA_SEARCH_MAPPINGS =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the LaTeX output
|
# Configuration options related to the LaTeX output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
|
||||||
# generate Latex output.
|
# The default value is: YES.
|
||||||
|
|
||||||
GENERATE_LATEX = NO
|
GENERATE_LATEX = NO
|
||||||
|
|
||||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
# put in front of it. If left blank `latex' will be used as the default path.
|
# it.
|
||||||
|
# The default directory is: latex.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_OUTPUT = latex
|
LATEX_OUTPUT = latex
|
||||||
|
|
||||||
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||||
# invoked. If left blank `latex' will be used as the default command name.
|
# invoked.
|
||||||
# Note that when enabling USE_PDFLATEX this option is only used for
|
#
|
||||||
# generating bitmaps for formulas in the HTML output, but not in the
|
# Note that when enabling USE_PDFLATEX this option is only used for generating
|
||||||
# Makefile that is written to the output directory.
|
# bitmaps for formulas in the HTML output, but not in the Makefile that is
|
||||||
|
# written to the output directory.
|
||||||
|
# The default file is: latex.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_CMD_NAME = latex
|
LATEX_CMD_NAME = latex
|
||||||
|
|
||||||
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
|
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
|
||||||
# generate index for LaTeX. If left blank `makeindex' will be used as the
|
# index for LaTeX.
|
||||||
# default command name.
|
# The default file is: makeindex.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
MAKEINDEX_CMD_NAME = makeindex
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
|
||||||
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
|
||||||
# LaTeX documents. This may be useful for small projects and may help to
|
# documents. This may be useful for small projects and may help to save some
|
||||||
# save some trees in general.
|
# trees in general.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
COMPACT_LATEX = NO
|
COMPACT_LATEX = NO
|
||||||
|
|
||||||
# The PAPER_TYPE tag can be used to set the paper type that is used
|
# The PAPER_TYPE tag can be used to set the paper type that is used by the
|
||||||
# by the printer. Possible values are: a4, letter, legal and
|
# printer.
|
||||||
# executive. If left blank a4 will be used.
|
# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
|
||||||
|
# 14 inches) and executive (7.25 x 10.5 inches).
|
||||||
|
# The default value is: a4.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
PAPER_TYPE = a4
|
PAPER_TYPE = a4
|
||||||
|
|
||||||
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
|
||||||
# packages that should be included in the LaTeX output.
|
# that should be included in the LaTeX output. To get the times font for
|
||||||
|
# instance you can specify
|
||||||
|
# EXTRA_PACKAGES=times
|
||||||
|
# If left blank no extra packages will be included.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
EXTRA_PACKAGES =
|
EXTRA_PACKAGES =
|
||||||
|
|
||||||
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
|
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
|
||||||
# the generated latex document. The header should contain everything until
|
# generated LaTeX document. The header should contain everything until the first
|
||||||
# the first chapter. If it is left blank doxygen will generate a
|
# chapter. If it is left blank doxygen will generate a standard header. See
|
||||||
# standard header. Notice: only use this tag if you know what you are doing!
|
# section "Doxygen usage" for information on how to let doxygen write the
|
||||||
|
# default header to a separate file.
|
||||||
|
#
|
||||||
|
# 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).
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_HEADER =
|
LATEX_HEADER =
|
||||||
|
|
||||||
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
|
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
|
||||||
# the generated latex document. The footer should contain everything after
|
# generated LaTeX document. The footer should contain everything after the last
|
||||||
# the last chapter. If it is left blank doxygen will generate a
|
# chapter. If it is left blank doxygen will generate a standard footer.
|
||||||
# standard footer. Notice: only use this tag if you know what you are doing!
|
#
|
||||||
|
# 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 =
|
LATEX_FOOTER =
|
||||||
|
|
||||||
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
|
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||||
# or other source files which should be copied to the LaTeX output directory.
|
# other source files which should be copied to the LATEX_OUTPUT output
|
||||||
# Note that the files will be copied as-is; there are no commands or markers
|
# directory. Note that the files will be copied as-is; there are no commands or
|
||||||
# available.
|
# markers available.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_EXTRA_FILES =
|
LATEX_EXTRA_FILES =
|
||||||
|
|
||||||
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
|
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
|
||||||
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
|
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
|
||||||
# contain links (just like the HTML output) instead of page references
|
# contain links (just like the HTML output) instead of page references. This
|
||||||
# This makes the output suitable for online browsing using a pdf viewer.
|
# makes the output suitable for online browsing using a PDF viewer.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
PDF_HYPERLINKS = YES
|
PDF_HYPERLINKS = YES
|
||||||
|
|
||||||
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
|
# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||||
# plain latex in the generated Makefile. Set this option to YES to get a
|
# the PDF file directly from the LaTeX files. Set this option to YES to get a
|
||||||
# higher quality PDF documentation.
|
# higher quality PDF documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
USE_PDFLATEX = YES
|
USE_PDFLATEX = YES
|
||||||
|
|
||||||
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
|
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
|
||||||
# command to the generated LaTeX files. This will instruct LaTeX to keep
|
# command to the generated LaTeX files. This will instruct LaTeX to keep running
|
||||||
# running if errors occur, instead of asking the user for help.
|
# if errors occur, instead of asking the user for help. This option is also used
|
||||||
# This option is also used when generating formulas in HTML.
|
# when generating formulas in HTML.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_BATCHMODE = NO
|
LATEX_BATCHMODE = NO
|
||||||
|
|
||||||
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
|
# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
|
||||||
# include the index chapters (such as File Index, Compound Index, etc.)
|
# index chapters (such as File Index, Compound Index, etc.) in the output.
|
||||||
# in the output.
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_HIDE_INDICES = NO
|
LATEX_HIDE_INDICES = NO
|
||||||
|
|
||||||
# If LATEX_SOURCE_CODE is set to YES then doxygen will include
|
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
|
||||||
# source code with syntax highlighting in the LaTeX output.
|
# code with syntax highlighting in the LaTeX output.
|
||||||
# Note that which sources are shown also depends on other settings
|
#
|
||||||
# such as SOURCE_BROWSER.
|
# 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_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_SOURCE_CODE = NO
|
LATEX_SOURCE_CODE = NO
|
||||||
|
|
||||||
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
||||||
# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
|
# bibliography, e.g. plainnat, or ieeetr. See
|
||||||
# http://en.wikipedia.org/wiki/BibTeX for more info.
|
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||||
|
# The default value is: plain.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_BIB_STYLE = plain
|
LATEX_BIB_STYLE = plain
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the RTF output
|
# Configuration options related to the RTF output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
|
# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
|
||||||
# The RTF output is optimized for Word 97 and may not look very pretty with
|
# RTF output is optimized for Word 97 and may not look too pretty with other RTF
|
||||||
# other RTF readers or editors.
|
# readers/editors.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_RTF = NO
|
GENERATE_RTF = NO
|
||||||
|
|
||||||
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
|
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
# put in front of it. If left blank `rtf' will be used as the default path.
|
# it.
|
||||||
|
# The default directory is: rtf.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
RTF_OUTPUT = rtf
|
RTF_OUTPUT = rtf
|
||||||
|
|
||||||
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
|
# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
|
||||||
# RTF documents. This may be useful for small projects and may help to
|
# documents. This may be useful for small projects and may help to save some
|
||||||
# save some trees in general.
|
# trees in general.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
COMPACT_RTF = NO
|
COMPACT_RTF = NO
|
||||||
|
|
||||||
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
|
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
|
||||||
# will contain hyperlink fields. The RTF file will
|
# contain hyperlink fields. The RTF file will contain links (just like the HTML
|
||||||
# contain links (just like the HTML output) instead of page references.
|
# output) instead of page references. This makes the output suitable for online
|
||||||
# This makes the output suitable for online browsing using WORD or other
|
# browsing using Word or some other Word compatible readers that support those
|
||||||
# programs which support those fields.
|
# fields.
|
||||||
# Note: wordpad (write) and others do not support links.
|
#
|
||||||
|
# Note: WordPad (write) and others do not support links.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
RTF_HYPERLINKS = NO
|
RTF_HYPERLINKS = NO
|
||||||
|
|
||||||
# Load style sheet definitions from file. Syntax is similar to doxygen's
|
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
|
||||||
# config file, i.e. a series of assignments. You only have to provide
|
# file, i.e. a series of assignments. You only have to provide replacements,
|
||||||
# replacements, missing definitions are set to their default value.
|
# missing definitions are set to their default value.
|
||||||
|
#
|
||||||
|
# See also section "Doxygen usage" for information on how to generate the
|
||||||
|
# default style sheet that doxygen normally uses.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
RTF_STYLESHEET_FILE =
|
RTF_STYLESHEET_FILE =
|
||||||
|
|
||||||
# Set optional variables used in the generation of an rtf document.
|
# Set optional variables used in the generation of an RTF document. Syntax is
|
||||||
# Syntax is similar to doxygen's config file.
|
# similar to doxygen's config file. A template extensions file can be generated
|
||||||
|
# using doxygen -e rtf extensionFile.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
RTF_EXTENSIONS_FILE =
|
RTF_EXTENSIONS_FILE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the man page output
|
# Configuration options related to the man page output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
|
# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
|
||||||
# generate man pages
|
# classes and files.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_MAN = NO
|
GENERATE_MAN = NO
|
||||||
|
|
||||||
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
|
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
# put in front of it. If left blank `man' will be used as the default path.
|
# it. A directory man3 will be created inside the directory specified by
|
||||||
|
# MAN_OUTPUT.
|
||||||
|
# The default directory is: man.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
MAN_OUTPUT = man
|
MAN_OUTPUT = man
|
||||||
|
|
||||||
# The MAN_EXTENSION tag determines the extension that is added to
|
# The MAN_EXTENSION tag determines the extension that is added to the generated
|
||||||
# the generated man pages (default is the subroutine's section .3)
|
# man pages. In case the manual section does not start with a number, the number
|
||||||
|
# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
|
||||||
|
# optional.
|
||||||
|
# The default value is: .3.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
MAN_EXTENSION = .3
|
MAN_EXTENSION = .3
|
||||||
|
|
||||||
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
|
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
|
||||||
# then it will generate one additional man file for each entity
|
# will generate one additional man file for each entity documented in the real
|
||||||
# documented in the real man page(s). These additional files
|
# man page(s). These additional files only source the real man page, but without
|
||||||
# only source the real man page, but without them the man command
|
# them the man command would be unable to find the correct page.
|
||||||
# would be unable to find the correct page. The default is NO.
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
MAN_LINKS = NO
|
MAN_LINKS = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the XML output
|
# Configuration options related to the XML output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_XML tag is set to YES Doxygen will
|
# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
|
||||||
# generate an XML file that captures the structure of
|
# captures the structure of the code including all documentation.
|
||||||
# the code including all documentation.
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_XML = NO
|
GENERATE_XML = NO
|
||||||
|
|
||||||
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
|
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
# put in front of it. If left blank `xml' will be used as the default path.
|
# it.
|
||||||
|
# The default directory is: xml.
|
||||||
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
XML_OUTPUT = xml
|
XML_OUTPUT = xml
|
||||||
|
|
||||||
# The XML_SCHEMA tag can be used to specify an XML schema,
|
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
|
||||||
# which can be used by a validating XML parser to check the
|
# validating XML parser to check the syntax of the XML files.
|
||||||
# syntax of the XML files.
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
XML_SCHEMA =
|
XML_SCHEMA =
|
||||||
|
|
||||||
# The XML_DTD tag can be used to specify an XML DTD,
|
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
|
||||||
# which can be used by a validating XML parser to check the
|
# validating XML parser to check the syntax of the XML files.
|
||||||
# syntax of the XML files.
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
XML_DTD =
|
XML_DTD =
|
||||||
|
|
||||||
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
|
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||||
# dump the program listings (including syntax highlighting
|
# listings (including syntax highlighting and cross-referencing information) to
|
||||||
# and cross-referencing information) to the XML output. Note that
|
# the XML output. Note that enabling this will significantly increase the size
|
||||||
# enabling this will significantly increase the size of the XML output.
|
# of the XML output.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
XML_PROGRAMLISTING = YES
|
XML_PROGRAMLISTING = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the DOCBOOK output
|
# 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.
|
# that can be used to generate PDF.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_DOCBOOK = NO
|
GENERATE_DOCBOOK = NO
|
||||||
|
|
||||||
# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
|
# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
|
# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
|
||||||
# front of it. If left blank docbook will be used as the default path.
|
# front of it.
|
||||||
|
# The default directory is: docbook.
|
||||||
|
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
|
||||||
|
|
||||||
DOCBOOK_OUTPUT = docbook
|
DOCBOOK_OUTPUT = docbook
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options for the AutoGen Definitions output
|
# Configuration options for the AutoGen Definitions output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
|
# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
|
||||||
# generate an AutoGen Definitions (see autogen.sf.net) file
|
# Definitions (see http://autogen.sf.net) file that captures the structure of
|
||||||
# that captures the structure of the code including all
|
# the code including all documentation. Note that this feature is still
|
||||||
# documentation. Note that this feature is still experimental
|
# experimental and incomplete at the moment.
|
||||||
# and incomplete at the moment.
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_AUTOGEN_DEF = NO
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the Perl module output
|
# Configuration options related to the Perl module output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the GENERATE_PERLMOD tag is set to YES Doxygen will
|
# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
|
||||||
# generate a Perl module file that captures the structure of
|
# file that captures the structure of the code including all documentation.
|
||||||
# the code including all documentation. Note that this
|
#
|
||||||
# feature is still experimental and incomplete at the
|
# Note that this feature is still experimental and incomplete at the moment.
|
||||||
# moment.
|
# The default value is: NO.
|
||||||
|
|
||||||
GENERATE_PERLMOD = NO
|
GENERATE_PERLMOD = NO
|
||||||
|
|
||||||
# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
|
# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
|
||||||
# the necessary Makefile rules, Perl scripts and LaTeX code to be able
|
# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
|
||||||
# to generate PDF and DVI output from the Perl module output.
|
# output from the Perl module output.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||||
|
|
||||||
PERLMOD_LATEX = NO
|
PERLMOD_LATEX = NO
|
||||||
|
|
||||||
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
|
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
|
||||||
# nicely formatted so it can be parsed by a human reader. This is useful
|
# formatted so it can be parsed by a human reader. This is useful if you want to
|
||||||
# if you want to understand what is going on. On the other hand, if this
|
# understand what is going on. On the other hand, if this tag is set to NO the
|
||||||
# tag is set to NO the size of the Perl module output will be much smaller
|
# size of the Perl module output will be much smaller and Perl will parse it
|
||||||
# and Perl will parse it just the same.
|
# just the same.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||||
|
|
||||||
PERLMOD_PRETTY = YES
|
PERLMOD_PRETTY = YES
|
||||||
|
|
||||||
# The names of the make variables in the generated doxyrules.make file
|
# The names of the make variables in the generated doxyrules.make file are
|
||||||
# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
|
# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
|
||||||
# This is useful so different doxyrules.make files included by the same
|
# so different doxyrules.make files included by the same Makefile don't
|
||||||
# Makefile don't overwrite each other's variables.
|
# overwrite each other's variables.
|
||||||
|
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||||
|
|
||||||
PERLMOD_MAKEVAR_PREFIX =
|
PERLMOD_MAKEVAR_PREFIX =
|
||||||
|
|
||||||
@@ -1592,111 +1928,129 @@ PERLMOD_MAKEVAR_PREFIX =
|
|||||||
# Configuration options related to the preprocessor
|
# Configuration options related to the preprocessor
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
|
# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
|
||||||
# evaluate all C-preprocessor directives found in the sources and include
|
# C-preprocessor directives found in the sources and include files.
|
||||||
# files.
|
# The default value is: YES.
|
||||||
|
|
||||||
ENABLE_PREPROCESSING = YES
|
ENABLE_PREPROCESSING = YES
|
||||||
|
|
||||||
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
|
# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
|
||||||
# names in the source code. If set to NO (the default) only conditional
|
# in the source code. If set to NO only conditional compilation will be
|
||||||
# compilation will be performed. Macro expansion can be done in a controlled
|
# performed. Macro expansion can be done in a controlled way by setting
|
||||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
# EXPAND_ONLY_PREDEF to YES.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
MACRO_EXPANSION = YES
|
MACRO_EXPANSION = YES
|
||||||
|
|
||||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
|
||||||
# then the macro expansion is limited to the macros specified with the
|
# the macro expansion is limited to the macros specified with the PREDEFINED and
|
||||||
# PREDEFINED and EXPAND_AS_DEFINED tags.
|
# EXPAND_AS_DEFINED tags.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
EXPAND_ONLY_PREDEF = NO
|
EXPAND_ONLY_PREDEF = NO
|
||||||
|
|
||||||
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
|
# If the SEARCH_INCLUDES tag is set to YES the includes files in the
|
||||||
# pointed to by INCLUDE_PATH will be searched when a #include is found.
|
# 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.
|
||||||
|
|
||||||
SEARCH_INCLUDES = NO
|
SEARCH_INCLUDES = NO
|
||||||
|
|
||||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||||
# contain include files that are not input files but should be processed by
|
# contain include files that are not input files but should be processed by the
|
||||||
# the preprocessor.
|
# preprocessor.
|
||||||
|
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
||||||
|
|
||||||
INCLUDE_PATH =
|
INCLUDE_PATH =
|
||||||
|
|
||||||
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
||||||
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
||||||
# directories. If left blank, the patterns specified with FILE_PATTERNS will
|
# directories. If left blank, the patterns specified with FILE_PATTERNS will be
|
||||||
# be used.
|
# used.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
INCLUDE_FILE_PATTERNS =
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
|
||||||
# The PREDEFINED tag can be used to specify one or more macro names that
|
# The PREDEFINED tag can be used to specify one or more macro names that are
|
||||||
# are defined before the preprocessor is started (similar to the -D option of
|
# defined before the preprocessor is started (similar to the -D option of e.g.
|
||||||
# gcc). The argument of the tag is a list of macros of the form: name
|
# gcc). The argument of the tag is a list of macros of the form: name or
|
||||||
# or name=definition (no spaces). If the definition and the = are
|
# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
|
||||||
# omitted =1 is assumed. To prevent a macro definition from being
|
# is assumed. To prevent a macro definition from being undefined via #undef or
|
||||||
# undefined via #undef or recursively expanded use the := operator
|
# recursively expanded use the := operator instead of the = operator.
|
||||||
# instead of the = operator.
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
PREDEFINED = DOXYGEN \
|
PREDEFINED = DOXYGEN \
|
||||||
PIP_EXPORT
|
PIP_EXPORT
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||||
# this tag can be used to specify a list of macro names that should be expanded.
|
# tag can be used to specify a list of macro names that should be expanded. The
|
||||||
# The macro definition that is found in the sources will be used.
|
# macro definition that is found in the sources will be used. Use the PREDEFINED
|
||||||
# Use the PREDEFINED tag if you want to use a different macro definition that
|
# tag if you want to use a different macro definition that overrules the
|
||||||
# overrules the definition found in the source code.
|
# definition found in the source code.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
|
|
||||||
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
|
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
||||||
# doxygen's preprocessor will remove all references to function-like macros
|
# remove all refrences to function-like macros that are alone on a line, have an
|
||||||
# that are alone on a line, have an all uppercase name, and do not end with a
|
# all uppercase name, and do not end with a semicolon. Such function macros are
|
||||||
# semicolon, because these will confuse the parser if not removed.
|
# 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.
|
||||||
|
|
||||||
SKIP_FUNCTION_MACROS = NO
|
SKIP_FUNCTION_MACROS = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration::additions related to external references
|
# Configuration options related to external references
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# The TAGFILES option can be used to specify one or more tagfiles. For each
|
# The TAGFILES tag can be used to specify one or more tag files. For each tag
|
||||||
# tag file the location of the external documentation should be added. The
|
# file the location of the external documentation should be added. The format of
|
||||||
# format of a tag file without this location is as follows:
|
# a tag file without this location is as follows:
|
||||||
# TAGFILES = file1 file2 ...
|
# TAGFILES = file1 file2 ...
|
||||||
# Adding location for the tag files is done as follows:
|
# Adding location for the tag files is done as follows:
|
||||||
# TAGFILES = file1=loc1 "file2 = loc2" ...
|
# TAGFILES = file1=loc1 "file2 = loc2" ...
|
||||||
# where "loc1" and "loc2" can be relative or absolute paths
|
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
|
||||||
# or URLs. Note that each tag file must have a unique name (where the name does
|
# section "Linking to external documentation" for more information about the use
|
||||||
# NOT include the path). If a tag file is not located in the directory in which
|
# of tag files.
|
||||||
# doxygen is run, you must also specify the path to the tagfile here.
|
# Note: Each tag file must have an 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.
|
||||||
|
|
||||||
TAGFILES =
|
TAGFILES =
|
||||||
|
|
||||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
|
||||||
# a tag file that is based on the input files it reads.
|
# tag file that is based on the input files it reads. See section "Linking to
|
||||||
|
# external documentation" for more information about the usage of tag files.
|
||||||
|
|
||||||
GENERATE_TAGFILE =
|
GENERATE_TAGFILE =
|
||||||
|
|
||||||
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
|
||||||
# in the class index. If set to NO only the inherited external classes
|
# class index. If set to NO only the inherited external classes will be listed.
|
||||||
# will be listed.
|
# The default value is: NO.
|
||||||
|
|
||||||
ALLEXTERNALS = NO
|
ALLEXTERNALS = NO
|
||||||
|
|
||||||
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
|
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
|
||||||
# in the modules index. If set to NO, only the current project's groups will
|
# the modules index. If set to NO, only the current project's groups will be
|
||||||
# be listed.
|
# listed.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
EXTERNAL_GROUPS = YES
|
EXTERNAL_GROUPS = YES
|
||||||
|
|
||||||
# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
|
# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
|
||||||
# in the related pages index. If set to NO, only the current project's
|
# the related pages index. If set to NO, only the current project's pages will
|
||||||
# pages will be listed.
|
# be listed.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
EXTERNAL_PAGES = YES
|
EXTERNAL_PAGES = YES
|
||||||
|
|
||||||
# The PERL_PATH should be the absolute path and name of the perl script
|
# The PERL_PATH should be the absolute path and name of the perl script
|
||||||
# interpreter (i.e. the result of `which perl').
|
# interpreter (i.e. the result of 'which perl').
|
||||||
|
# The default file (with absolute path) is: /usr/bin/perl.
|
||||||
|
|
||||||
PERL_PATH = /usr/bin/perl
|
PERL_PATH = /usr/bin/perl
|
||||||
|
|
||||||
@@ -1704,222 +2058,293 @@ PERL_PATH = /usr/bin/perl
|
|||||||
# Configuration options related to the dot tool
|
# Configuration options related to the dot tool
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
|
# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
|
||||||
# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
|
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
|
||||||
# or super classes. Setting the tag to NO turns the diagrams off. Note that
|
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
|
||||||
# this option also works with HAVE_DOT disabled, but it is recommended to
|
# disabled, but it is recommended to install and use dot, since it yields more
|
||||||
# install and use dot, since it yields more powerful graphs.
|
# powerful graphs.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
CLASS_DIAGRAMS = YES
|
CLASS_DIAGRAMS = YES
|
||||||
|
|
||||||
# You can define message sequence charts within doxygen comments using the \msc
|
# You can define message sequence charts within doxygen comments using the \msc
|
||||||
# command. Doxygen will then run the mscgen tool (see
|
# command. Doxygen will then run the mscgen tool (see:
|
||||||
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
|
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
|
||||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||||
# default search path.
|
# default search path.
|
||||||
|
|
||||||
MSCGEN_PATH =
|
MSCGEN_PATH =
|
||||||
|
|
||||||
# If set to YES, the inheritance and collaboration graphs will hide
|
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||||
# inheritance and usage relations if the target is undocumented
|
# then run dia to produce the diagram and insert it in the documentation. The
|
||||||
# or is not a class.
|
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||||
|
# If left empty dia is assumed to be found in the default search path.
|
||||||
|
|
||||||
|
DIA_PATH =
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
HIDE_UNDOC_RELATIONS = YES
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
|
|
||||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||||
# available from the path. This tool is part of Graphviz, a graph visualization
|
# available from the path. This tool is part of Graphviz (see:
|
||||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||||
# have no effect if this option is set to NO (the default)
|
# Bell Labs. The other options in this section have no effect if this option is
|
||||||
|
# set to NO
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
HAVE_DOT = YES
|
HAVE_DOT = YES
|
||||||
|
|
||||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
|
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||||
# allowed to run in parallel. When set to 0 (the default) doxygen will
|
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||||
# base this on the number of processors available in the system. You can set it
|
# processors available in the system. You can set it explicitly to a value
|
||||||
# explicitly to a value larger than 0 to get control over the balance
|
# larger than 0 to get control over the balance between CPU load and processing
|
||||||
# between CPU load and processing speed.
|
# speed.
|
||||||
|
# Minimum value: 0, maximum value: 32, default value: 0.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_NUM_THREADS = 8
|
DOT_NUM_THREADS = 8
|
||||||
|
|
||||||
# By default doxygen will use the Helvetica font for all dot files that
|
# When you want a differently looking font n the dot files that doxygen
|
||||||
# doxygen generates. When you want a differently looking font you can specify
|
# generates you can specify the font name using DOT_FONTNAME. You need to make
|
||||||
# the font name using DOT_FONTNAME. You need to make sure dot is able to find
|
# sure dot is able to find the font, which can be done by putting it in a
|
||||||
# the font, which can be done by putting it in a standard location or by setting
|
# standard location or by setting the DOTFONTPATH environment variable or by
|
||||||
# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
|
# setting DOT_FONTPATH to the directory containing the font.
|
||||||
# directory containing the font.
|
# The default value is: Helvetica.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_FONTNAME = "DejaVu Sans Mono"
|
DOT_FONTNAME = "DejaVu Sans Mono"
|
||||||
|
|
||||||
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
|
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
|
||||||
# The default size is 10pt.
|
# dot graphs.
|
||||||
|
# Minimum value: 4, maximum value: 24, default value: 10.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_FONTSIZE = 10
|
DOT_FONTSIZE = 10
|
||||||
|
|
||||||
# By default doxygen will tell dot to use the Helvetica font.
|
# By default doxygen will tell dot to use the default font as specified with
|
||||||
# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
|
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
|
||||||
# set the path where dot can find it.
|
# the path where dot can find it using this tag.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_FONTPATH =
|
DOT_FONTPATH =
|
||||||
|
|
||||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
|
||||||
# will generate a graph for each documented class showing the direct and
|
# each documented class showing the direct and indirect inheritance relations.
|
||||||
# indirect inheritance relations. Setting this tag to YES will force the
|
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
|
||||||
# CLASS_DIAGRAMS tag to NO.
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
CLASS_GRAPH = YES
|
CLASS_GRAPH = YES
|
||||||
|
|
||||||
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
|
||||||
# will generate a graph for each documented class showing the direct and
|
# graph for each documented class showing the direct and indirect implementation
|
||||||
# indirect implementation dependencies (inheritance, containment, and
|
# dependencies (inheritance, containment, and class references variables) of the
|
||||||
# class references variables) of the class with other documented classes.
|
# class with other documented classes.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
COLLABORATION_GRAPH = NO
|
COLLABORATION_GRAPH = NO
|
||||||
|
|
||||||
# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
|
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
|
||||||
# will generate a graph for groups, showing the direct groups dependencies
|
# groups, showing the direct groups dependencies.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
GROUP_GRAPHS = NO
|
GROUP_GRAPHS = NO
|
||||||
|
|
||||||
# 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
|
# collaboration diagrams in a style similar to the OMG's Unified Modeling
|
||||||
# Language.
|
# Language.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
UML_LOOK = NO
|
UML_LOOK = NO
|
||||||
|
|
||||||
# If the UML_LOOK tag is enabled, the fields and methods are shown inside
|
# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
|
||||||
# the class node. If there are many fields or methods and many nodes the
|
# class node. If there are many fields or methods and many nodes the graph may
|
||||||
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
|
# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
|
||||||
# threshold limits the number of items for each type to make the size more
|
# number of items for each type to make the size more manageable. Set this to 0
|
||||||
# manageable. Set this to 0 for no limit. Note that the threshold may be
|
# for no limit. Note that the threshold may be exceeded by 50% before the limit
|
||||||
# exceeded by 50% before the limit is enforced.
|
# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
|
||||||
|
# but if the number exceeds 15, the total amount of fields shown is limited to
|
||||||
|
# 10.
|
||||||
|
# Minimum value: 0, maximum value: 100, default value: 10.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
UML_LIMIT_NUM_FIELDS = 12
|
UML_LIMIT_NUM_FIELDS = 12
|
||||||
|
|
||||||
# If set to YES, the inheritance and collaboration graphs will show the
|
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
|
||||||
# relations between templates and their instances.
|
# collaboration graphs will show the relations between templates and their
|
||||||
|
# instances.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
TEMPLATE_RELATIONS = NO
|
TEMPLATE_RELATIONS = NO
|
||||||
|
|
||||||
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
|
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
|
||||||
# tags are set to YES then doxygen will generate a graph for each documented
|
# YES then doxygen will generate a graph for each documented file showing the
|
||||||
# file showing the direct and indirect include dependencies of the file with
|
# direct and indirect include dependencies of the file with other documented
|
||||||
# other documented files.
|
# files.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
INCLUDE_GRAPH = NO
|
INCLUDE_GRAPH = NO
|
||||||
|
|
||||||
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
|
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
|
||||||
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
|
# set to YES then doxygen will generate a graph for each documented file showing
|
||||||
# documented header file showing the documented files that directly or
|
# the direct and indirect include dependencies of the file with other documented
|
||||||
# indirectly include this file.
|
# files.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
INCLUDED_BY_GRAPH = NO
|
INCLUDED_BY_GRAPH = NO
|
||||||
|
|
||||||
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
|
# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
|
||||||
# doxygen will generate a call dependency graph for every global function
|
# dependency graph for every global function or class method.
|
||||||
# or class method. 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
|
# Note that enabling this option will significantly increase the time of a run.
|
||||||
# for selected functions only using the \callgraph command.
|
# So in most cases it will be better to enable call graphs for selected
|
||||||
|
# functions only using the \callgraph command.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
CALL_GRAPH = NO
|
CALL_GRAPH = NO
|
||||||
|
|
||||||
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
|
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
|
||||||
# doxygen will generate a caller dependency graph for every global function
|
# dependency graph for every global function or class method.
|
||||||
# or class method. Note that enabling this option will significantly increase
|
#
|
||||||
# the time of a run. So in most cases it will be better to enable caller
|
# Note that enabling this option will significantly increase the time of a run.
|
||||||
# graphs for selected functions only using the \callergraph command.
|
# So in most cases it will be better to enable caller graphs for selected
|
||||||
|
# functions only using the \callergraph command.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
CALLER_GRAPH = NO
|
CALLER_GRAPH = NO
|
||||||
|
|
||||||
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
|
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
|
||||||
# will generate a graphical hierarchy of all classes instead of a textual one.
|
# hierarchy of all classes instead of a textual one.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
GRAPHICAL_HIERARCHY = YES
|
GRAPHICAL_HIERARCHY = YES
|
||||||
|
|
||||||
# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
|
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
|
||||||
# then doxygen will show the dependencies a directory has on other directories
|
# dependencies a directory has on other directories in a graphical way. The
|
||||||
# in a graphical way. The dependency relations are determined by the #include
|
# dependency relations are determined by the #include relations between the
|
||||||
# relations between the files in the directories.
|
# files in the directories.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DIRECTORY_GRAPH = YES
|
DIRECTORY_GRAPH = YES
|
||||||
|
|
||||||
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
||||||
# generated by dot. Possible values are svg, png, jpg, or gif.
|
# generated by dot.
|
||||||
# If left blank png will be used. If you choose svg you need to set
|
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
||||||
# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
|
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
||||||
# visible in IE 9+ (other browsers do not have this requirement).
|
# requirement).
|
||||||
|
# Possible values are: png, jpg, gif and svg.
|
||||||
|
# The default value is: png.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_IMAGE_FORMAT = svg
|
DOT_IMAGE_FORMAT = svg
|
||||||
|
|
||||||
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
|
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
|
||||||
# enable generation of interactive SVG images that allow zooming and panning.
|
# enable generation of interactive SVG images that allow zooming and panning.
|
||||||
# Note that this requires a modern browser other than Internet Explorer.
|
#
|
||||||
# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
|
# Note that this requires a modern browser other than Internet Explorer. Tested
|
||||||
# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
|
# and working are Firefox, Chrome, Safari, and Opera.
|
||||||
# visible. Older versions of IE do not have SVG support.
|
# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
|
||||||
|
# the SVG files visible. Older versions of IE do not have SVG support.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
INTERACTIVE_SVG = YES
|
INTERACTIVE_SVG = YES
|
||||||
|
|
||||||
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
# The DOT_PATH tag can be used to specify the path where the dot tool can be
|
||||||
# found. If left blank, it is assumed the dot tool can be found in the path.
|
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_PATH =
|
DOT_PATH =
|
||||||
|
|
||||||
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain dot files that are included in the documentation (see the
|
# contain dot files that are included in the documentation (see the \dotfile
|
||||||
# \dotfile command).
|
# command).
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOTFILE_DIRS =
|
DOTFILE_DIRS =
|
||||||
|
|
||||||
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain msc files that are included in the documentation (see the
|
# contain msc files that are included in the documentation (see the \mscfile
|
||||||
# \mscfile command).
|
# command).
|
||||||
|
|
||||||
MSCFILE_DIRS =
|
MSCFILE_DIRS =
|
||||||
|
|
||||||
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
|
# The DIAFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# nodes that will be shown in the graph. If the number of nodes in a graph
|
# contain dia files that are included in the documentation (see the \diafile
|
||||||
# becomes larger than this value, doxygen will truncate the graph, which is
|
# command).
|
||||||
# visualized by representing a node as a red box. Note that doxygen if the
|
|
||||||
# number of direct children of the root node in a graph is already larger than
|
DIAFILE_DIRS =
|
||||||
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
|
|
||||||
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
|
# 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
|
||||||
|
# by representing a node as a red box. Note that doxygen if the number of direct
|
||||||
|
# children of the root node in a graph is already larger than
|
||||||
|
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
|
||||||
|
# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
|
||||||
|
# Minimum value: 0, maximum value: 10000, default value: 50.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_GRAPH_MAX_NODES = 50
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
|
|
||||||
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
|
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
|
||||||
# graphs generated by dot. A depth value of 3 means that only nodes reachable
|
# generated by dot. A depth value of 3 means that only nodes reachable from the
|
||||||
# from the root by following a path via at most 3 edges will be shown. Nodes
|
# root by following a path via at most 3 edges will be shown. Nodes that lay
|
||||||
# that lay further from the root node will be omitted. Note that setting this
|
# further from the root node will be omitted. Note that setting this option to 1
|
||||||
# option to 1 or 2 may greatly reduce the computation time needed for large
|
# or 2 may greatly reduce the computation time needed for large code bases. Also
|
||||||
# code bases. Also note that the size of a graph can be further restricted by
|
# note that the size of a graph can be further restricted by
|
||||||
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
|
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
|
||||||
|
# Minimum value: 0, maximum value: 1000, default value: 0.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
MAX_DOT_GRAPH_DEPTH = 0
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
|
||||||
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
|
||||||
# background. This is disabled by default, because dot on Windows does not
|
# background. This is disabled by default, because dot on Windows does not seem
|
||||||
# seem to support this out of the box. Warning: Depending on the platform used,
|
# to support this out of the box.
|
||||||
# enabling this option may lead to badly anti-aliased labels on the edges of
|
#
|
||||||
# a graph (i.e. they become hard to read).
|
# Warning: Depending on the platform used, enabling this option may lead to
|
||||||
|
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
|
||||||
|
# read).
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_TRANSPARENT = NO
|
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 allow dot to generate multiple output
|
||||||
# files in one run (i.e. multiple -o and -T options on the command line). This
|
# 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)
|
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
|
||||||
# support this, this feature is disabled by default.
|
# this, this feature is disabled by default.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_MULTI_TARGETS = NO
|
DOT_MULTI_TARGETS = NO
|
||||||
|
|
||||||
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
|
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
|
||||||
# generate a legend page explaining the meaning of the various boxes and
|
# explaining the meaning of the various boxes and arrows in the dot generated
|
||||||
# arrows in the dot generated graphs.
|
# graphs.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
GENERATE_LEGEND = YES
|
GENERATE_LEGEND = YES
|
||||||
|
|
||||||
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
|
# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
|
||||||
# remove the intermediate dot files that are used to generate
|
# files that are used to generate the various graphs.
|
||||||
# the various graphs.
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_CLEANUP = YES
|
DOT_CLEANUP = YES
|
||||||
|
|||||||
519
ifaddrs_3rd.c
519
ifaddrs_3rd.c
@@ -1,519 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2013, Kenneth MacKay
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__ANDROID__) || defined(_ANDROID_) || defined(ANDROID)
|
|
||||||
|
|
||||||
#include "ifaddrs_3rd.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/if_arp.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <linux/netlink.h>
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
|
|
||||||
typedef struct NetlinkList {
|
|
||||||
struct NetlinkList * m_next;
|
|
||||||
struct nlmsghdr * m_data;
|
|
||||||
unsigned int m_size;
|
|
||||||
} NetlinkList;
|
|
||||||
|
|
||||||
static int netlink_socket(void) {
|
|
||||||
int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
||||||
if (l_socket < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
memset(&l_addr, 0, sizeof(l_addr));
|
|
||||||
l_addr.nl_family = AF_NETLINK;
|
|
||||||
if (bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0) {
|
|
||||||
close(l_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return l_socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int netlink_send(int p_socket, int p_request) {
|
|
||||||
char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
|
|
||||||
memset(l_buffer, 0, sizeof(l_buffer));
|
|
||||||
struct nlmsghdr * l_hdr = (struct nlmsghdr *)l_buffer;
|
|
||||||
struct rtgenmsg * l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
|
|
||||||
|
|
||||||
l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
|
|
||||||
l_hdr->nlmsg_type = p_request;
|
|
||||||
l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
|
|
||||||
l_hdr->nlmsg_pid = 0;
|
|
||||||
l_hdr->nlmsg_seq = p_socket;
|
|
||||||
l_msg->rtgen_family = AF_UNSPEC;
|
|
||||||
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
memset(&l_addr, 0, sizeof(l_addr));
|
|
||||||
l_addr.nl_family = AF_NETLINK;
|
|
||||||
return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int netlink_recv(int p_socket, void * p_buffer, size_t p_len) {
|
|
||||||
struct msghdr l_msg;
|
|
||||||
struct iovec l_iov = { p_buffer, p_len };
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
int l_result;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
l_msg.msg_name = (void *)&l_addr;
|
|
||||||
l_msg.msg_namelen = sizeof(l_addr);
|
|
||||||
l_msg.msg_iov = &l_iov;
|
|
||||||
l_msg.msg_iovlen = 1;
|
|
||||||
l_msg.msg_control = NULL;
|
|
||||||
l_msg.msg_controllen = 0;
|
|
||||||
l_msg.msg_flags = 0;
|
|
||||||
int l_result = recvmsg(p_socket, &l_msg, 0);
|
|
||||||
|
|
||||||
if (l_result < 0) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_msg.msg_flags & MSG_TRUNC) {
|
|
||||||
// buffer was too small
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return l_result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nlmsghdr * getNetlinkResponse(int p_socket, int * p_size, int * p_done) {
|
|
||||||
size_t l_size = 4096;
|
|
||||||
void * l_buffer = NULL;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
free(l_buffer);
|
|
||||||
l_buffer = malloc(l_size);
|
|
||||||
|
|
||||||
int l_read = netlink_recv(p_socket, l_buffer, l_size);
|
|
||||||
*p_size = l_read;
|
|
||||||
if (l_read == -2) {
|
|
||||||
free(l_buffer);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (l_read >= 0) {
|
|
||||||
pid_t l_pid = getpid();
|
|
||||||
struct nlmsghdr * l_hdr;
|
|
||||||
for (l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) {
|
|
||||||
if ((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_hdr->nlmsg_type == NLMSG_DONE) {
|
|
||||||
*p_done = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_hdr->nlmsg_type == NLMSG_ERROR) {
|
|
||||||
free(l_buffer);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_size *= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NetlinkList * newListItem(struct nlmsghdr * p_data, unsigned int p_size) {
|
|
||||||
NetlinkList * l_item = malloc(sizeof(NetlinkList));
|
|
||||||
l_item->m_next = NULL;
|
|
||||||
l_item->m_data = p_data;
|
|
||||||
l_item->m_size = p_size;
|
|
||||||
return l_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void freeResultList(NetlinkList * p_list) {
|
|
||||||
NetlinkList * l_cur;
|
|
||||||
while (p_list) {
|
|
||||||
l_cur = p_list;
|
|
||||||
p_list = p_list->m_next;
|
|
||||||
free(l_cur->m_data);
|
|
||||||
free(l_cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NetlinkList * getResultList(int p_socket, int p_request) {
|
|
||||||
if (netlink_send(p_socket, p_request) < 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList * l_list = NULL;
|
|
||||||
NetlinkList * l_end = NULL;
|
|
||||||
int l_size;
|
|
||||||
int l_done = 0;
|
|
||||||
while (!l_done) {
|
|
||||||
struct nlmsghdr * l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
|
|
||||||
if (!l_hdr) {
|
|
||||||
// error
|
|
||||||
freeResultList(l_list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList * l_item = newListItem(l_hdr, l_size);
|
|
||||||
if (!l_list) {
|
|
||||||
l_list = l_item;
|
|
||||||
} else {
|
|
||||||
l_end->m_next = l_item;
|
|
||||||
}
|
|
||||||
l_end = l_item;
|
|
||||||
}
|
|
||||||
return l_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t maxSize(size_t a, size_t b) {
|
|
||||||
return (a > b ? a : b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t calcAddrLen(sa_family_t p_family, int p_dataSize) {
|
|
||||||
switch (p_family) {
|
|
||||||
case AF_INET:
|
|
||||||
return sizeof(struct sockaddr_in);
|
|
||||||
case AF_INET6:
|
|
||||||
return sizeof(struct sockaddr_in6);
|
|
||||||
case AF_PACKET:
|
|
||||||
return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
|
|
||||||
default:
|
|
||||||
return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void makeSockaddr(sa_family_t p_family, struct sockaddr * p_dest, void * p_data, size_t p_size) {
|
|
||||||
switch (p_family) {
|
|
||||||
case AF_INET:
|
|
||||||
memcpy(&((struct sockaddr_in *)p_dest)->sin_addr, p_data, p_size);
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
memcpy(&((struct sockaddr_in6 *)p_dest)->sin6_addr, p_data, p_size);
|
|
||||||
break;
|
|
||||||
case AF_PACKET:
|
|
||||||
memcpy(((struct sockaddr_ll *)p_dest)->sll_addr, p_data, p_size);
|
|
||||||
((struct sockaddr_ll *)p_dest)->sll_halen = p_size;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
memcpy(p_dest->sa_data, p_data, p_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p_dest->sa_family = p_family;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addToEnd(struct ifaddrs ** p_resultList, struct ifaddrs * p_entry) {
|
|
||||||
if (!*p_resultList) {
|
|
||||||
*p_resultList = p_entry;
|
|
||||||
} else {
|
|
||||||
struct ifaddrs * l_cur = *p_resultList;
|
|
||||||
while (l_cur->ifa_next) {
|
|
||||||
l_cur = l_cur->ifa_next;
|
|
||||||
}
|
|
||||||
l_cur->ifa_next = p_entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interpretLink(struct nlmsghdr * p_hdr, struct ifaddrs ** p_links, struct ifaddrs ** p_resultList) {
|
|
||||||
struct ifinfomsg * l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
|
|
||||||
|
|
||||||
size_t l_nameSize = 0;
|
|
||||||
size_t l_addrSize = 0;
|
|
||||||
size_t l_dataSize = 0;
|
|
||||||
|
|
||||||
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
|
||||||
struct rtattr * l_rta;
|
|
||||||
for (l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) {
|
|
||||||
void * l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch (l_rta->rta_type) {
|
|
||||||
case IFLA_ADDRESS:
|
|
||||||
case IFLA_BROADCAST:
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
|
|
||||||
break;
|
|
||||||
case IFLA_IFNAME:
|
|
||||||
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
|
|
||||||
break;
|
|
||||||
case IFLA_STATS:
|
|
||||||
l_dataSize += NLMSG_ALIGN(l_rtaSize);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ifaddrs * l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize + l_dataSize);
|
|
||||||
memset(l_entry, 0, sizeof(struct ifaddrs));
|
|
||||||
l_entry->ifa_name = "";
|
|
||||||
|
|
||||||
char * l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
|
|
||||||
char * l_addr = l_name + l_nameSize;
|
|
||||||
char * l_data = l_addr + l_addrSize;
|
|
||||||
|
|
||||||
l_entry->ifa_flags = l_info->ifi_flags;
|
|
||||||
|
|
||||||
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
|
||||||
for (l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) {
|
|
||||||
void * l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch (l_rta->rta_type) {
|
|
||||||
case IFLA_ADDRESS:
|
|
||||||
case IFLA_BROADCAST: {
|
|
||||||
size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
|
|
||||||
makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
|
||||||
((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
|
|
||||||
((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
|
|
||||||
if (l_rta->rta_type == IFLA_ADDRESS) {
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
} else {
|
|
||||||
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
l_addr += NLMSG_ALIGN(l_addrLen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IFLA_IFNAME:
|
|
||||||
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
|
||||||
l_name[l_rtaDataSize] = '\0';
|
|
||||||
l_entry->ifa_name = l_name;
|
|
||||||
break;
|
|
||||||
case IFLA_STATS:
|
|
||||||
memcpy(l_data, l_rtaData, l_rtaDataSize);
|
|
||||||
l_entry->ifa_data = l_data;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addToEnd(p_resultList, l_entry);
|
|
||||||
p_links[l_info->ifi_index - 1] = l_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interpretAddr(struct nlmsghdr * p_hdr, struct ifaddrs ** p_links, struct ifaddrs ** p_resultList) {
|
|
||||||
struct ifaddrmsg * l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
|
|
||||||
|
|
||||||
size_t l_nameSize = 0;
|
|
||||||
size_t l_addrSize = 0;
|
|
||||||
|
|
||||||
int l_addedNetmask = 0;
|
|
||||||
|
|
||||||
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
|
||||||
struct rtattr * l_rta;
|
|
||||||
for (l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) {
|
|
||||||
void * l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
if (l_info->ifa_family == AF_PACKET) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (l_rta->rta_type) {
|
|
||||||
case IFA_ADDRESS:
|
|
||||||
case IFA_LOCAL:
|
|
||||||
if ((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask) {
|
|
||||||
// make room for netmask
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
|
||||||
l_addedNetmask = 1;
|
|
||||||
}
|
|
||||||
case IFA_BROADCAST:
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
|
||||||
break;
|
|
||||||
case IFA_LABEL:
|
|
||||||
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ifaddrs * l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
|
|
||||||
memset(l_entry, 0, sizeof(struct ifaddrs));
|
|
||||||
l_entry->ifa_name = p_links[l_info->ifa_index - 1]->ifa_name;
|
|
||||||
|
|
||||||
char * l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
|
|
||||||
char * l_addr = l_name + l_nameSize;
|
|
||||||
|
|
||||||
l_entry->ifa_flags = l_info->ifa_flags | p_links[l_info->ifa_index - 1]->ifa_flags;
|
|
||||||
|
|
||||||
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
|
||||||
for (l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) {
|
|
||||||
void * l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch (l_rta->rta_type) {
|
|
||||||
case IFA_ADDRESS:
|
|
||||||
case IFA_BROADCAST:
|
|
||||||
case IFA_LOCAL: {
|
|
||||||
size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
|
|
||||||
makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
|
||||||
if (l_info->ifa_family == AF_INET6) {
|
|
||||||
if (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData)) {
|
|
||||||
((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_rta->rta_type == IFA_ADDRESS) {
|
|
||||||
// apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address
|
|
||||||
if (l_entry->ifa_addr) {
|
|
||||||
l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
|
|
||||||
} else {
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
} else if (l_rta->rta_type == IFA_LOCAL) {
|
|
||||||
if (l_entry->ifa_addr) {
|
|
||||||
l_entry->ifa_dstaddr = l_entry->ifa_addr;
|
|
||||||
}
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
} else {
|
|
||||||
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
l_addr += NLMSG_ALIGN(l_addrLen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IFA_LABEL:
|
|
||||||
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
|
||||||
l_name[l_rtaDataSize] = '\0';
|
|
||||||
l_entry->ifa_name = l_name;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6)) {
|
|
||||||
unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
|
|
||||||
unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
|
|
||||||
char l_mask[16] = {0};
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < (l_prefix / 8); ++i) {
|
|
||||||
l_mask[i] = 0xff;
|
|
||||||
}
|
|
||||||
l_mask[i] = 0xff << (8 - (l_prefix % 8));
|
|
||||||
|
|
||||||
makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
|
|
||||||
l_entry->ifa_netmask = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
addToEnd(p_resultList, l_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interpret(int p_socket, NetlinkList * p_netlinkList, struct ifaddrs ** p_links, struct ifaddrs ** p_resultList) {
|
|
||||||
pid_t l_pid = getpid();
|
|
||||||
for (; p_netlinkList; p_netlinkList = p_netlinkList->m_next) {
|
|
||||||
unsigned int l_nlsize = p_netlinkList->m_size;
|
|
||||||
struct nlmsghdr * l_hdr;
|
|
||||||
for (l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) {
|
|
||||||
if ((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_hdr->nlmsg_type == NLMSG_DONE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_hdr->nlmsg_type == RTM_NEWLINK) {
|
|
||||||
interpretLink(l_hdr, p_links, p_resultList);
|
|
||||||
} else if (l_hdr->nlmsg_type == RTM_NEWADDR) {
|
|
||||||
interpretAddr(l_hdr, p_links, p_resultList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned countLinks(int p_socket, NetlinkList * p_netlinkList) {
|
|
||||||
unsigned l_links = 0;
|
|
||||||
pid_t l_pid = getpid();
|
|
||||||
for (; p_netlinkList; p_netlinkList = p_netlinkList->m_next) {
|
|
||||||
unsigned int l_nlsize = p_netlinkList->m_size;
|
|
||||||
struct nlmsghdr * l_hdr;
|
|
||||||
for (l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) {
|
|
||||||
if ((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_hdr->nlmsg_type == NLMSG_DONE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_hdr->nlmsg_type == RTM_NEWLINK) {
|
|
||||||
++l_links;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return l_links;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getifaddrs(struct ifaddrs ** ifap) {
|
|
||||||
if (!ifap) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*ifap = NULL;
|
|
||||||
|
|
||||||
int l_socket = netlink_socket();
|
|
||||||
if (l_socket < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList * l_linkResults = getResultList(l_socket, RTM_GETLINK);
|
|
||||||
if (!l_linkResults) {
|
|
||||||
close(l_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList * l_addrResults = getResultList(l_socket, RTM_GETADDR);
|
|
||||||
if (!l_addrResults) {
|
|
||||||
close(l_socket);
|
|
||||||
freeResultList(l_linkResults);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults);
|
|
||||||
struct ifaddrs * l_links[l_numLinks];
|
|
||||||
memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *));
|
|
||||||
|
|
||||||
interpret(l_socket, l_linkResults, l_links, ifap);
|
|
||||||
interpret(l_socket, l_addrResults, l_links, ifap);
|
|
||||||
|
|
||||||
freeResultList(l_linkResults);
|
|
||||||
freeResultList(l_addrResults);
|
|
||||||
close(l_socket);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeifaddrs(struct ifaddrs * ifa) {
|
|
||||||
struct ifaddrs * l_cur;
|
|
||||||
while (ifa) {
|
|
||||||
l_cur = ifa;
|
|
||||||
ifa = ifa->ifa_next;
|
|
||||||
free(l_cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1995, 1999
|
|
||||||
* Berkeley Software Design, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__ANDROID__) || defined(_ANDROID_) || defined(ANDROID)
|
|
||||||
|
|
||||||
#ifndef _IFADDRS_H_
|
|
||||||
#define _IFADDRS_H_
|
|
||||||
|
|
||||||
struct ifaddrs {
|
|
||||||
struct ifaddrs *ifa_next;
|
|
||||||
char *ifa_name;
|
|
||||||
unsigned int ifa_flags;
|
|
||||||
struct sockaddr *ifa_addr;
|
|
||||||
struct sockaddr *ifa_netmask;
|
|
||||||
struct sockaddr *ifa_dstaddr;
|
|
||||||
void *ifa_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
|
|
||||||
* to be included it must be included before this header file.
|
|
||||||
*/
|
|
||||||
#ifndef ifa_broadaddr
|
|
||||||
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
extern int getifaddrs(struct ifaddrs **ifap);
|
|
||||||
extern void freeifaddrs(struct ifaddrs *ifa);
|
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
60
main.cpp
60
main.cpp
@@ -44,36 +44,34 @@ class ElementD: public PIObject {
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
#include "pip.h"
|
#include "pip.h"
|
||||||
#include <QVector>
|
#include "pivariant.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test::PIVariant<> * pv;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Test::PIVariant<T> newVariant(const T & v) {return Test::PIVariant<T>(v);}
|
||||||
|
template <typename T>
|
||||||
|
Test::PIVariant<T> * castVariant(Test::__PIVariantBase * v, const T & t) {return static_cast<Test::PIVariant<T> * >(v);}
|
||||||
|
*/
|
||||||
|
#include "picode.h"
|
||||||
|
|
||||||
|
#define S(a, b) a#b
|
||||||
|
|
||||||
int main (int argc, char * argv[]) {
|
int main (int argc, char * argv[]) {
|
||||||
PITimer tm;
|
//piCout << (S(1,2));
|
||||||
std::vector<int> sv;
|
//(1,2));
|
||||||
PIVector<int> pv;
|
//CodeParser cd;
|
||||||
QVector<int> qv;
|
//cd.parseFile("test.cpp");
|
||||||
pv.reserve(256);
|
//piCout << v.toType<float>();
|
||||||
for (int s = 1; s <= 20; ++s) {
|
//piCout << v.toType<float>().toType<PIString>();
|
||||||
int cnt = s * 1000000;
|
//PIFile::remove("ki");
|
||||||
piCout << "********";
|
/*PIConfig conf("protocols_commod.conf");
|
||||||
piCout << cnt << "insertion:";
|
piCout << conf.allTree();
|
||||||
sv.clear();
|
conf.setValue("rmd.123", 456);*/
|
||||||
pv.clear();
|
piCout << PIString("1.1").toFloat();
|
||||||
qv.clear();
|
piCout << PIString("1,1").toFloat();
|
||||||
tm.reset();
|
}
|
||||||
for (int i = 0; i < cnt; ++i) {
|
|
||||||
sv.push_back(i);
|
|
||||||
}
|
|
||||||
piCout << "stl:" << tm.elapsed_m();
|
|
||||||
tm.reset();
|
|
||||||
for (int i = 0; i < cnt; ++i) {
|
|
||||||
pv.push_back(i);
|
|
||||||
}
|
|
||||||
piCout << "pip:" << tm.elapsed_m();
|
|
||||||
tm.reset();
|
|
||||||
for (int i = 0; i < cnt; ++i) {
|
|
||||||
qv.append(i);
|
|
||||||
}
|
|
||||||
piCout << " qt:" << tm.elapsed_m();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
cmake .
|
|
||||||
make $@
|
|
||||||
cp -vf *.h /usr/include/
|
|
||||||
cp -vf lib*.so /usr/lib/
|
|
||||||
1
make_lib.bat
Executable file
1
make_lib.bat
Executable file
@@ -0,0 +1 @@
|
|||||||
|
cmake_mgw -DLIB= && make install
|
||||||
304
pibinarylog.cpp
Normal file
304
pibinarylog.cpp
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Class for write binary data to logfile, and read or playback this data
|
||||||
|
Copyright (C) 2014 Andrey Bychkov work.a.b@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pibinarylog.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class PIBinaryLog
|
||||||
|
* \brief Class for read and write binary data to logfile, and playback this data in realtime
|
||||||
|
*
|
||||||
|
* \section PIBinaryLog_sec0 Synopsis
|
||||||
|
* Binary Log is a file with simle header, where you can read and write some binary data.
|
||||||
|
* Any written data include special header with ID, size and timestamp.
|
||||||
|
* This header provides separation different messages from the one file by choosing different IDs.
|
||||||
|
* With \a filterID or special functions, like \a readBinLog() you can choose IDs what you want to read.
|
||||||
|
* With function \a writeBinLog() or \a setDefaultID() you can choose ID that mark you data.
|
||||||
|
* By default ID = 1, and \a filterID is empty, that mean you read any ID without filtering.
|
||||||
|
* ThreadedRead provide you playback data, with delay that you write data.
|
||||||
|
* You can choose realtime playbak or variable speed play back by set \a PlayMode.
|
||||||
|
*
|
||||||
|
* \section PIBinaryLog_sec1 Basic usage
|
||||||
|
* This class provide all functions of \a PIIODevice, such \a open(), \a close(),
|
||||||
|
* \a read() ,\a write(), and threaded read/write.
|
||||||
|
* function \a setLogDir() need to set directory for BinLog files
|
||||||
|
* function \a createNewFile() need to create new binlog file
|
||||||
|
* function \a restart() need start from the begining of binlog file
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
PIBinaryLog::PIBinaryLog() {
|
||||||
|
binlog_sig[0] = 'B';
|
||||||
|
binlog_sig[1] = 'I';
|
||||||
|
binlog_sig[2] = 'N';
|
||||||
|
binlog_sig[3] = 'L';
|
||||||
|
binlog_sig[4] = 'O';
|
||||||
|
binlog_sig[5] = 'G';
|
||||||
|
setThreadedReadBufferSize(65536);
|
||||||
|
is_started = rapid_start = false;
|
||||||
|
playspeed = 1.0f;
|
||||||
|
default_id = 1;
|
||||||
|
playmode = PlayVariableSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIBinaryLog::openDevice() {
|
||||||
|
lastrecord.timestamp = PISystemTime();
|
||||||
|
lastrecord.id = 0;
|
||||||
|
is_started = false;
|
||||||
|
is_thread_ok = true;
|
||||||
|
if (mode_ == ReadWrite) {
|
||||||
|
piCoutObj << "ReadWrite mode not supported, use WriteOnly or ReadOnly";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!file.open(path_, mode_))
|
||||||
|
return false;
|
||||||
|
setName(path_);
|
||||||
|
if (mode_ == WriteOnly) {
|
||||||
|
file.resize(0);
|
||||||
|
if (!writeFileHeader()) {
|
||||||
|
piCoutObj << "Can't write binlog file header";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is_started = true;
|
||||||
|
}
|
||||||
|
if (mode_ == ReadOnly) {
|
||||||
|
if (file.isEmpty()) {
|
||||||
|
piCoutObj << "File is null";
|
||||||
|
fileError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!checkFileHeader()) {
|
||||||
|
fileError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isEmpty()) piCoutObj << "Empty BinLog file";
|
||||||
|
// startlogtime = currentSystemTime();
|
||||||
|
play_time = 0;
|
||||||
|
// nextrecord = readsRecord();
|
||||||
|
if (!rapid_start) is_started = true;
|
||||||
|
}
|
||||||
|
startlogtime = currentSystemTime();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIBinaryLog::closeDevice() {
|
||||||
|
if (canWrite() && isEmpty()) {
|
||||||
|
file.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||||
|
is_thread_ok = false;
|
||||||
|
PISystemTime pt;
|
||||||
|
double delay;
|
||||||
|
switch (playmode) {
|
||||||
|
case PlayRealTime:
|
||||||
|
pt = currentSystemTime() - startlogtime;
|
||||||
|
// if (real_speedX > 0)
|
||||||
|
// for (int i=0; i<real_speedX-1; i++) pt += pt;
|
||||||
|
// piCout << pt << lastrecord.timestamp << lastrecord.timestamp - pt;
|
||||||
|
if (is_started) {
|
||||||
|
if (lastrecord.timestamp > pt)
|
||||||
|
(lastrecord.timestamp - pt).sleep();
|
||||||
|
} else {
|
||||||
|
startlogtime = currentSystemTime() - lastrecord.timestamp;
|
||||||
|
is_started = true;
|
||||||
|
}
|
||||||
|
// int delay = piRoundd(lastread_timestamp.toMilliseconds() - (currentSystemTime() - startlogtime).toMilliseconds());
|
||||||
|
break;
|
||||||
|
case PlayVariableSpeed:
|
||||||
|
delay = lastrecord.timestamp.toMilliseconds() - play_time;
|
||||||
|
delay /= playspeed;
|
||||||
|
if (is_started) {
|
||||||
|
if (delay > 0)
|
||||||
|
PISystemTime::fromMilliseconds(delay).sleep();
|
||||||
|
} else is_started = true;
|
||||||
|
play_time = lastrecord.timestamp.toMilliseconds();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool res = PIIODevice::threadedRead(readed, size);
|
||||||
|
is_thread_ok = true;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIBinaryLog::createNewFile() {
|
||||||
|
if (!file.close()) return PIString();
|
||||||
|
if (open(logdir + "/" + fileprefix + currentDateTime().toString("yyyy_MM_dd__hh_mm_ss.binlog"), PIIODevice::WriteOnly))
|
||||||
|
return file.path();
|
||||||
|
piCoutObj << "Can't create new file, maybe LogDir is invalid.";
|
||||||
|
return PIString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIBinaryLog::writeBinLog(int id, const void *data, int size) {
|
||||||
|
if (size <= 0 || !canWrite()) return -1;
|
||||||
|
PIByteArray logdata;
|
||||||
|
logdata << id << size << (currentSystemTime() - startlogtime) << PIByteArray::RawData(data, size);
|
||||||
|
int res = file.write(logdata.data(), logdata.size());
|
||||||
|
file.flush();
|
||||||
|
if (res > 0) return size;
|
||||||
|
else return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray PIBinaryLog::readBinLog(int id) {
|
||||||
|
if (!canRead()) return PIByteArray();
|
||||||
|
BinLogRecord br = readRecord();
|
||||||
|
if (br.id == -1) {
|
||||||
|
piCoutObj << "End of BinLog file";
|
||||||
|
fileEnd();
|
||||||
|
return PIByteArray();
|
||||||
|
}
|
||||||
|
if (id == 0 && br.id > 0) return br.data;
|
||||||
|
while (br.id != id && !isEnd()) br = readRecord();
|
||||||
|
if (br.id == -1) {
|
||||||
|
piCoutObj << "End of BinLog file";
|
||||||
|
fileEnd();
|
||||||
|
return PIByteArray();
|
||||||
|
}
|
||||||
|
if (br.id == id) return br.data;
|
||||||
|
piCoutObj << "Can't find record with id =" << id;
|
||||||
|
return PIByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIBinaryLog::readBinLog(int id, void *read_to, int max_size) {
|
||||||
|
if (max_size <= 0 || read_to == 0) return -1;
|
||||||
|
PIByteArray ba = readBinLog(id);
|
||||||
|
if (ba.isEmpty()) return -1;
|
||||||
|
int sz = piMini(max_size, ba.size());
|
||||||
|
memcpy(read_to, ba.data(), sz);
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int PIBinaryLog::read(void *read_to, int max_size) {
|
||||||
|
// piCoutObj << "read";
|
||||||
|
if (lastrecord.id == -1 || isEnd()) return 0;
|
||||||
|
if(!is_thread_ok && lastrecord.id > 0) return lastrecord.data.size();
|
||||||
|
if (!canRead()) return -1;
|
||||||
|
if (max_size <= 0 || read_to == 0) return -1;
|
||||||
|
BinLogRecord br;
|
||||||
|
br.id = 0;
|
||||||
|
if (filterID.isEmpty()) br = readRecord();
|
||||||
|
else {
|
||||||
|
while (!filterID.contains(br.id) && !isEnd()) br = readRecord();
|
||||||
|
}
|
||||||
|
if (br.id == -1) {
|
||||||
|
fileEnd();
|
||||||
|
piCoutObj << "End of BinLog file";
|
||||||
|
//stopThreadedRead();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (br.id <= 0) {
|
||||||
|
piCoutObj << "Read record error";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int sz = piMini(max_size, br.data.size());
|
||||||
|
memcpy(read_to, br.data.data(), sz);
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIBinaryLog::restart()
|
||||||
|
{
|
||||||
|
bool th = isRunning();
|
||||||
|
if (th) stopThreadedRead();
|
||||||
|
if (!canRead()) return;
|
||||||
|
lastrecord.timestamp = PISystemTime();
|
||||||
|
lastrecord.id = 0;
|
||||||
|
is_thread_ok = true;
|
||||||
|
if (rapid_start) is_started = false;
|
||||||
|
else is_started = true;
|
||||||
|
play_time = 0;
|
||||||
|
file.seekToBegin();
|
||||||
|
checkFileHeader();
|
||||||
|
startlogtime = currentSystemTime();
|
||||||
|
if (th) startThreadedRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIBinaryLog::writeFileHeader() {
|
||||||
|
if (file.write(&binlog_sig, PIBINARYLOG_SIGNATURE_SIZE) <= 0) return false;
|
||||||
|
uchar version = PIBINARYLOG_VERSION;
|
||||||
|
if (file.write(&version, 1) <= 0) return false;
|
||||||
|
file.flush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIBinaryLog::checkFileHeader() {
|
||||||
|
uchar read_sig[PIBINARYLOG_SIGNATURE_SIZE];
|
||||||
|
for (int i=0; i<PIBINARYLOG_SIGNATURE_SIZE; i++) read_sig[i] = 0;
|
||||||
|
if (file.read(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) return false;
|
||||||
|
bool correct = true;
|
||||||
|
for (int i=0; i<PIBINARYLOG_SIGNATURE_SIZE; i++)
|
||||||
|
if (read_sig[i] != binlog_sig[i]) correct = false;
|
||||||
|
if (!correct) {
|
||||||
|
piCoutObj << "BinLogFile signature is corrupted or invalid file";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uchar read_version = 0;
|
||||||
|
if (file.read(&read_version, 1) < 0) return false;
|
||||||
|
if (read_version == PIBINARYLOG_VERSION) return true;
|
||||||
|
if (read_version == 0)
|
||||||
|
piCoutObj << "BinLogFile has invalid version";
|
||||||
|
if (read_version < PIBINARYLOG_VERSION)
|
||||||
|
piCoutObj << "BinLogFile has too old verion";
|
||||||
|
if (read_version > PIBINARYLOG_VERSION)
|
||||||
|
piCoutObj << "BinLogFile has too newest version";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIBinaryLog::BinLogRecord PIBinaryLog::readRecord() {
|
||||||
|
// piCoutObj << "readRecord";
|
||||||
|
PIByteArray ba;
|
||||||
|
BinLogRecord br;
|
||||||
|
lastrecord.id = 0;
|
||||||
|
lastrecord.data.clear();
|
||||||
|
lastrecord.timestamp = PISystemTime();
|
||||||
|
ba.resize(sizeof(BinLogRecord) - sizeof(PIByteArray));
|
||||||
|
if(file.read(ba.data(), ba.size_s()) > 0) {
|
||||||
|
ba >> br.id >> br.size >> br.timestamp;
|
||||||
|
// piCoutObj << "read" << br.id << br.size << br.timestamp;
|
||||||
|
} else {
|
||||||
|
br.id = -1;
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
if (br.id > 0 && br.size > 0) {
|
||||||
|
ba.resize(br.size);
|
||||||
|
if(file.read(ba.data(), ba.size_s()) > 0) br.data = ba;
|
||||||
|
else br.id = 0;
|
||||||
|
} else br.id = 0;
|
||||||
|
lastrecord = br;
|
||||||
|
if (br.id == 0) fileError();
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
173
pibinarylog.h
Normal file
173
pibinarylog.h
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
/*! \file pibinarylog.h
|
||||||
|
* \brief Binary log
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Class for write binary data to logfile, and read or playback this data
|
||||||
|
Copyright (C) 2014 Andrey Bychkov work.a.b@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIBINARYLOG_H
|
||||||
|
#define PIBINARYLOG_H
|
||||||
|
|
||||||
|
#include "pifile.h"
|
||||||
|
|
||||||
|
#define PIBINARYLOG_VERSION 0x31
|
||||||
|
#define PIBINARYLOG_SIGNATURE_SIZE 6
|
||||||
|
|
||||||
|
|
||||||
|
class PIBinaryLog: public PIIODevice
|
||||||
|
{
|
||||||
|
PIOBJECT(PIBinaryLog)
|
||||||
|
public:
|
||||||
|
PIBinaryLog();
|
||||||
|
~PIBinaryLog() {closeDevice();}
|
||||||
|
|
||||||
|
//! \brief Play modes for \a PIBinaryLog
|
||||||
|
enum PlayMode {
|
||||||
|
PlayRealTime /*! Play in system real time */ ,
|
||||||
|
PlayVariableSpeed /*! Play in software time with speed, set by \a setSpeed. Set by default */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! Current \a PlayMode
|
||||||
|
PlayMode playMode() const {return playmode;}
|
||||||
|
|
||||||
|
//! Current directory where billogs wiil be saved
|
||||||
|
const PIString & logDir() const {return logdir;}
|
||||||
|
|
||||||
|
//! Returns current file prefix
|
||||||
|
const PIString & filePrefix() const {return fileprefix;}
|
||||||
|
|
||||||
|
//! Current LogDir, returns directory where billogs wiil be saved
|
||||||
|
int dafaultID() const {return default_id;}
|
||||||
|
|
||||||
|
//! Returns current play speed
|
||||||
|
float speed() const {return playspeed;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Set \a PlayMode
|
||||||
|
void setPlayMode(PlayMode mode) {playmode = mode;}
|
||||||
|
|
||||||
|
//! Set path to directory where binlogs will be saved
|
||||||
|
void setLogDir(const PIString & path) {logdir = path;}
|
||||||
|
|
||||||
|
//! Set file prefix, used to
|
||||||
|
void setFilePrefix(const PIString & prefix) {fileprefix = prefix;}
|
||||||
|
|
||||||
|
//! Set defaultID, used in \a write function
|
||||||
|
void setDefaultID(int id) {default_id = id;}
|
||||||
|
|
||||||
|
// /** \brief Set play speed multiplyer, used only in \a PlayMode = \a PlayRealTime default value 1x.
|
||||||
|
// * If "speedX" > 0 than it use as speed increase by X times, else as speed decrease by X times.
|
||||||
|
// * While is running this function does nothing and returns false. If "speedX" is set, returns true.*/
|
||||||
|
// bool setRealSpeedX(int speedX) {if (speedX == 0 || isRunning()) return false; real_speedX = speedX; return true;}
|
||||||
|
// //! Returns current play speed multiplyer
|
||||||
|
// float realSpeedX() const {return real_speedX;}
|
||||||
|
//! Set play speed, used only in \a PlayMode = \a PlayVariableSpeed, default value 1.0
|
||||||
|
void setSpeed(float speed) {playspeed = speed;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Write one record to BinLog file, with ID = id, id must be greather than 0
|
||||||
|
int writeBinLog(int id, PIByteArray data) {return writeBinLog(id, data.data(), data.size_s());}
|
||||||
|
|
||||||
|
int writeBinLog(int id, const void * data, int size);
|
||||||
|
|
||||||
|
//! Read one record from BinLog file, with ID = id, if id = 0 than any id will be readed
|
||||||
|
PIByteArray readBinLog(int id = 0);
|
||||||
|
|
||||||
|
int readBinLog(int id, void *read_to, int max_size);
|
||||||
|
|
||||||
|
//! Return true, if position at the end of BinLog file
|
||||||
|
bool isEnd() {if (!opened_) return true; return file.isEnd();}
|
||||||
|
|
||||||
|
//! Returns if BinLog file is empty
|
||||||
|
bool isEmpty() {return (file.size() <= PIBINARYLOG_SIGNATURE_SIZE + 1);}
|
||||||
|
|
||||||
|
int lastReadedID() const {return lastrecord.id;}
|
||||||
|
|
||||||
|
//! Read one message from binlog file, with ID contains in "filterID" or any ID, if "filterID" is empty
|
||||||
|
int read(void *read_to, int max_size);
|
||||||
|
|
||||||
|
//! Write one record to BinLog file, with ID = "defaultID"
|
||||||
|
int write(const void * data, int size) {return writeBinLog(default_id, data, size);}
|
||||||
|
|
||||||
|
//! Array of ID, that BinLog can read from binlog file, when use \a read function, or in \a ThreadedRead
|
||||||
|
PIVector<int> filterID;
|
||||||
|
|
||||||
|
//! If "RapidStart" enabled, than BinLog \a ThreadedRead starts without delay for first record, e.g. first record will be readed immediately
|
||||||
|
void setRapidStart(bool enabled = false) {rapid_start = enabled;}
|
||||||
|
|
||||||
|
//! Go to begin of BinLog file
|
||||||
|
void restart();
|
||||||
|
|
||||||
|
|
||||||
|
//! \handlers
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! \fn PIString createNewFile()
|
||||||
|
//! \brief Open device
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \events
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! \fn void fileEnd()
|
||||||
|
//! \brief Create new binlog file in \a logDir, if successful returns filename, else returns empty string.
|
||||||
|
//! Filename is like \a filePrefix + "yyyy_MM_dd__hh_mm_ss.binlog"
|
||||||
|
|
||||||
|
//! \fn void fileError()
|
||||||
|
//! \brief Raise on file creation error
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
EVENT_HANDLER(PIString, createNewFile);
|
||||||
|
EVENT(fileEnd)
|
||||||
|
EVENT(fileError)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool openDevice();
|
||||||
|
bool closeDevice();
|
||||||
|
bool threadedRead(uchar *readed, int size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct BinLogRecord {
|
||||||
|
int id;
|
||||||
|
int size;
|
||||||
|
PISystemTime timestamp;
|
||||||
|
PIByteArray data;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool writeFileHeader();
|
||||||
|
bool checkFileHeader();
|
||||||
|
BinLogRecord readRecord();
|
||||||
|
|
||||||
|
PIFile file;
|
||||||
|
PIString logdir, fileprefix;
|
||||||
|
BinLogRecord lastrecord;
|
||||||
|
PISystemTime startlogtime;
|
||||||
|
//BinLogRecord nextrecord;
|
||||||
|
PlayMode playmode;
|
||||||
|
double play_time; //milliseconds
|
||||||
|
float playspeed;
|
||||||
|
int default_id;
|
||||||
|
//int real_speedX; // in X
|
||||||
|
bool is_started, rapid_start, is_thread_ok;
|
||||||
|
uchar binlog_sig[PIBINARYLOG_SIGNATURE_SIZE];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PIBINARYLOG_H
|
||||||
1
pichar.h
1
pichar.h
@@ -155,6 +155,7 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(PIChar)
|
||||||
|
|
||||||
//! Output operator to \c std::ostream
|
//! Output operator to \c std::ostream
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIChar & v) {s << v.toCharPtr(); return s;}
|
||||||
|
|||||||
189
picode.cpp
Normal file
189
picode.cpp
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Packets extractor
|
||||||
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "picode.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PIString CodeParser::Macro::expand(const PIStringList & arg_vals, bool * ok) const {
|
||||||
|
if (args.size() != arg_vals.size()) {
|
||||||
|
piCout << ("Error: in expansion of macro \"" + name + "(" + args.join(", ") + ")\": expect")
|
||||||
|
<< args.size() << "arguments but takes" << arg_vals.size() << "!";
|
||||||
|
if (ok != 0) *ok = false;
|
||||||
|
return PIString();
|
||||||
|
}
|
||||||
|
PIString ret = value;
|
||||||
|
for (int i = 0; i < args.size_s(); ++i) {
|
||||||
|
const PIString & an(args[i]), av(arg_vals[i]);
|
||||||
|
int ind(-1);
|
||||||
|
while ((ind = ret.find(an, ind + 1)) >= 0) {
|
||||||
|
PIChar ppc(0), pc(0), nc(0);
|
||||||
|
if (ind > 1) ppc = ret[ind - 2];
|
||||||
|
if (ind > 0) pc = ret[ind - 1];
|
||||||
|
if (ind + an.size_s() < ret.size_s()) nc = ret[ind + an.size_s()];
|
||||||
|
if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars
|
||||||
|
ind--;
|
||||||
|
ret.replace(ind, an.size_s() + 1, "\"" + av + "\"");
|
||||||
|
ind -= an.size_s() - av.size_s() - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (_isCChar(pc) || _isCChar(nc)) continue;
|
||||||
|
ret.replace(ind, an.size_s(), av);
|
||||||
|
ind -= an.size_s() - av.size_s();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.replaceAll("##", "");
|
||||||
|
if (ok != 0) *ok = true;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CodeParser::CodeParser() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CodeParser::parseFile(const PIString & file) {
|
||||||
|
//piCout << "parse" << file << "...";
|
||||||
|
PIFile f(file, PIIODevice::ReadOnly);
|
||||||
|
if (!f.isOpened()) {
|
||||||
|
piCout << ("Error: can`t open file \"" + file + "\"!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PIString fc = f.readAll();
|
||||||
|
return parseFileContent(fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CodeParser::clear() {
|
||||||
|
defines.clear();
|
||||||
|
typedefs.clear();
|
||||||
|
tree.clear();
|
||||||
|
entities.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CodeParser::parseFileContent(PIString & fc) {
|
||||||
|
bool mlc = false, cc = false;
|
||||||
|
int mls = 0, ole = -1, ccs = 0;
|
||||||
|
char c;
|
||||||
|
PIString pfc, line, ccmn;
|
||||||
|
PIMap<PIString, PIString> cchars;
|
||||||
|
|
||||||
|
/// Remove comments, join multiline "" and replace "" to $n (cchars)
|
||||||
|
fc.replaceAll("\r\n", "\n");
|
||||||
|
fc.replaceAll("\r", "\n");
|
||||||
|
for (int i = 0; i < fc.size_s() - 1; ++i) {
|
||||||
|
c = fc[i].toAscii();
|
||||||
|
if (c == '"') {
|
||||||
|
if (i > 0) if (fc[i - 1] == '\\') continue;
|
||||||
|
cc = !cc;
|
||||||
|
if (cc) ccs = i;
|
||||||
|
if (!cc) {
|
||||||
|
ccmn = "$" + PIString::fromNumber(cchars.size());
|
||||||
|
cchars[ccmn] = fc.mid(ccs, i - ccs + 1);
|
||||||
|
fc.replace(ccs, i - ccs + 1, ccmn);
|
||||||
|
i = ccs - 1 + ccmn.size_s();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i > 0) {
|
||||||
|
if (c == '\\' && fc[i - 1] != '\\') {fc.cutMid(i, 2); --i;}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cc) continue;
|
||||||
|
if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
|
||||||
|
if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
|
||||||
|
if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;}
|
||||||
|
if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i + 1); --i; continue;}
|
||||||
|
}
|
||||||
|
while (!fc.isEmpty()) {
|
||||||
|
line = fc.takeLine().trimmed();
|
||||||
|
if (line.left(1) == "#") {
|
||||||
|
if (!parseDirective(line.cutLeft(1).trim()))
|
||||||
|
return false;
|
||||||
|
} else pfc << line << "\n";
|
||||||
|
}
|
||||||
|
bool replaced = true;
|
||||||
|
int replaced_cnt = 0;
|
||||||
|
while (replaced) {
|
||||||
|
if (replaced_cnt >= 64) {
|
||||||
|
piCout << "Error: recursive macros detected!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
replaced_cnt++;
|
||||||
|
replaced = false;
|
||||||
|
piForeachC (Define & d, defines) {
|
||||||
|
int ind(-1);
|
||||||
|
while ((ind = pfc.find(d.first, ind + 1)) >= 0) {
|
||||||
|
PIChar pc(0), nc(0);
|
||||||
|
if (ind > 0) pc = pfc[ind - 1];
|
||||||
|
if (ind + d.first.size_s() < pfc.size_s()) nc = pfc[ind + d.first.size_s()];
|
||||||
|
if (_isCChar(pc) || _isCChar(nc)) continue;
|
||||||
|
pfc.replace(ind, d.first.size_s(), d.second);
|
||||||
|
ind -= d.first.size_s() - d.second.size_s();
|
||||||
|
replaced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
piForeachC (Macro & m, macros) {
|
||||||
|
int ind(-1);
|
||||||
|
while ((ind = pfc.find(m.name, ind + 1)) >= 0) {
|
||||||
|
PIChar pc(0), nc(0);
|
||||||
|
if (ind > 0) pc = pfc[ind - 1];
|
||||||
|
if (ind + m.name.size_s() < pfc.size_s()) nc = pfc[ind + m.name.size_s()];
|
||||||
|
if (_isCChar(pc) || _isCChar(nc)) continue;
|
||||||
|
PIString ret, range; bool ok(false);
|
||||||
|
range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")");
|
||||||
|
ret = m.expand(range.split(",").trim(), &ok);
|
||||||
|
//piCout << "range" << ret;
|
||||||
|
if (!ok) return false;
|
||||||
|
int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind;
|
||||||
|
pfc.replace(ind, rlen, ret);
|
||||||
|
ind -= rlen - ret.size_s();
|
||||||
|
replaced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
piCout << pfc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CodeParser::parseDirective(PIString d) {
|
||||||
|
if (d.isEmpty()) return true;
|
||||||
|
PIString dname = d.takeCWord();
|
||||||
|
if (dname == "include") {
|
||||||
|
d.replaceAll("<", "\"").replaceAll(">", "\"");
|
||||||
|
return parseFile(d.takeRange("\"", "\""));
|
||||||
|
}
|
||||||
|
if (dname == "define") {
|
||||||
|
PIString mname = d.takeCWord();
|
||||||
|
if (d.left(1) == "(") { // macro
|
||||||
|
PIStringList args = d.takeRange("(", ")").split(",").trim();
|
||||||
|
macros << Macro(mname, d.trim(), args);
|
||||||
|
} else { // define
|
||||||
|
defines << Define(mname, d.trim());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
80
picode.h
Normal file
80
picode.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*! \file pipacketextractor.h
|
||||||
|
* \brief Packets extractor
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Packets extractor
|
||||||
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CODE_H
|
||||||
|
#define CODE_H
|
||||||
|
|
||||||
|
#include "pifile.h"
|
||||||
|
|
||||||
|
inline bool _isCChar(const PIChar & c) {return (c.isAlpha() || (c == '_'));}
|
||||||
|
inline bool _isCChar(const PIString & c) {if (c.isEmpty()) return false; return _isCChar(c[0]);}
|
||||||
|
|
||||||
|
class CodeParser {
|
||||||
|
public:
|
||||||
|
CodeParser();
|
||||||
|
|
||||||
|
bool parseFile(const PIString & file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void clear();
|
||||||
|
bool parseFileContent(PIString & fc);
|
||||||
|
bool parseDirective(PIString d);
|
||||||
|
|
||||||
|
enum Visibility {Global, Public, Protected, Private};
|
||||||
|
typedef PIPair<PIString, PIString> Define;
|
||||||
|
typedef PIPair<PIString, PIString> Typedef;
|
||||||
|
struct Macro {
|
||||||
|
Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) {
|
||||||
|
name = n;
|
||||||
|
value = v;
|
||||||
|
args = a;
|
||||||
|
}
|
||||||
|
PIString expand(const PIStringList & arg_vals, bool * ok = 0) const;
|
||||||
|
PIString name;
|
||||||
|
PIString value;
|
||||||
|
PIStringList args;
|
||||||
|
};
|
||||||
|
struct Entity {
|
||||||
|
Entity() {
|
||||||
|
visibility = Global;
|
||||||
|
size = 0;
|
||||||
|
parent = 0;
|
||||||
|
}
|
||||||
|
PIString type;
|
||||||
|
PIString name;
|
||||||
|
PIString file;
|
||||||
|
Visibility visibility;
|
||||||
|
int size;
|
||||||
|
Entity * parent;
|
||||||
|
PIVector<Entity * > children;
|
||||||
|
};
|
||||||
|
|
||||||
|
PIVector<Define> defines;
|
||||||
|
PIVector<Macro> macros;
|
||||||
|
PIVector<Typedef> typedefs;
|
||||||
|
PIVector<Entity> entities;
|
||||||
|
PIVector<Entity * > tree;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PIPACKETEXTRACTOR_H
|
||||||
62
piconfig.cpp
62
piconfig.cpp
@@ -29,6 +29,22 @@
|
|||||||
* some values and write new.
|
* some values and write new.
|
||||||
* \image html piconfig.png
|
* \image html piconfig.png
|
||||||
*
|
*
|
||||||
|
* %PIConfig supports also INI-style files with sections "[section]".
|
||||||
|
* In this case line with section name interpret as prefix to the next
|
||||||
|
* lines. For example, these configs are equal:
|
||||||
|
* \code
|
||||||
|
* ser.device = /dev/ttyS0
|
||||||
|
* ser.speed = 115200
|
||||||
|
* debug = true
|
||||||
|
* \endcode
|
||||||
|
* \code
|
||||||
|
* [ser]
|
||||||
|
* device = /dev/ttyS0
|
||||||
|
* speed = 115200
|
||||||
|
* []
|
||||||
|
* debug = true
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
* \section PIConfig_sec1 Concepts
|
* \section PIConfig_sec1 Concepts
|
||||||
* Each node of internal tree has type PIConfig::Entry. %PIConfig
|
* Each node of internal tree has type PIConfig::Entry. %PIConfig
|
||||||
* has one root element \a rootEntry(). Any entry of configuration file is a
|
* has one root element \a rootEntry(). Any entry of configuration file is a
|
||||||
@@ -422,13 +438,30 @@ void PIConfig::removeEntry(Branch & b, PIConfig::Entry * e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIConfig::getPrefixFromLine(PIString line, bool * exists) {
|
||||||
|
line.trim();
|
||||||
|
if (line.left(1) == "#") {if (exists) *exists = false; return PIString();}
|
||||||
|
int ci = line.find("#");
|
||||||
|
if (ci >= 0) line.cutRight(line.size() - ci);
|
||||||
|
if (line.find("=") >= 0) {if (exists) *exists = false; return PIString();}
|
||||||
|
if (line.find("[") >= 0 && line.find("]") >= 0) {
|
||||||
|
if (exists) *exists = true;
|
||||||
|
return line.takeRange('[', ']').trim();
|
||||||
|
}
|
||||||
|
if (exists) *exists = false;
|
||||||
|
return PIString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConfig::writeAll() {
|
void PIConfig::writeAll() {
|
||||||
//cout << this << " write < " << size() << endl;
|
//cout << this << " write < " << size() << endl;
|
||||||
clear();
|
PIFile::clear();
|
||||||
//*this << "1234567894132456798\n"; return;
|
//*this << "1234567894132456798\n"; return;
|
||||||
//writeEntry(&root);
|
//writeEntry(&root);
|
||||||
buildFullNames(&root);
|
buildFullNames(&root);
|
||||||
Branch b = allLeaves();
|
Branch b = allLeaves();
|
||||||
|
PIString prefix, tprefix;
|
||||||
|
bool isPrefix;
|
||||||
//for (int i = 0; i < b.size_s(); ++i)
|
//for (int i = 0; i < b.size_s(); ++i)
|
||||||
// cout << b[i]->_name << " = " << b[i]->_value << endl;
|
// cout << b[i]->_name << " = " << b[i]->_value << endl;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
@@ -437,16 +470,28 @@ void PIConfig::writeAll() {
|
|||||||
if (j >= 0 && j < b.size_s()) {
|
if (j >= 0 && j < b.size_s()) {
|
||||||
if (b[j]->_line == i) {
|
if (b[j]->_line == i) {
|
||||||
b[j]->buildLine();
|
b[j]->buildLine();
|
||||||
*this << b[j]->_all << '\n';
|
*this << (b[j]->_all).cutLeft(prefix.size()) << '\n';
|
||||||
//cout << this << " " << b[j]->_all << endl;
|
//cout << this << " " << b[j]->_all << endl;
|
||||||
++j;
|
++j;
|
||||||
} else {
|
} else {
|
||||||
*this << other[i];
|
*this << other[i];
|
||||||
|
tprefix = getPrefixFromLine(other[i], &isPrefix);
|
||||||
|
if (isPrefix) {
|
||||||
|
prefix = tprefix;
|
||||||
|
if (!prefix.isEmpty())
|
||||||
|
prefix += delim;
|
||||||
|
}
|
||||||
if (i < other.size_s() - 1) *this << '\n';
|
if (i < other.size_s() - 1) *this << '\n';
|
||||||
//cout << this << " " << other[i] << endl;
|
//cout << this << " " << other[i] << endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*this << other[i];
|
*this << other[i];
|
||||||
|
tprefix = getPrefixFromLine(other[i], &isPrefix);
|
||||||
|
if (isPrefix) {
|
||||||
|
prefix = tprefix;
|
||||||
|
if (!prefix.isEmpty())
|
||||||
|
prefix += delim;
|
||||||
|
}
|
||||||
if (i < other.size_s() - 1) *this << '\n';
|
if (i < other.size_s() - 1) *this << '\n';
|
||||||
//cout << this << " " << other[i] << endl;
|
//cout << this << " " << other[i] << endl;
|
||||||
}
|
}
|
||||||
@@ -458,6 +503,7 @@ void PIConfig::writeAll() {
|
|||||||
|
|
||||||
|
|
||||||
void PIConfig::readAll() {
|
void PIConfig::readAll() {
|
||||||
|
root.deleteBranch();
|
||||||
root.clear();
|
root.clear();
|
||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
@@ -475,11 +521,11 @@ bool PIConfig::entryExists(const Entry * e, const PIString & name) const {
|
|||||||
|
|
||||||
|
|
||||||
void PIConfig::parse() {
|
void PIConfig::parse() {
|
||||||
PIString src, str, tab, comm, all, name, type;
|
PIString src, str, tab, comm, all, name, type, prefix, tprefix;
|
||||||
PIStringList tree;
|
PIStringList tree;
|
||||||
Entry * entry, * te, * ce;
|
Entry * entry, * te, * ce;
|
||||||
int ind, sind;
|
int ind, sind;
|
||||||
bool isNew;
|
bool isNew, isPrefix;
|
||||||
if (!isOpened()) return;
|
if (!isOpened()) return;
|
||||||
seekToBegin();
|
seekToBegin();
|
||||||
other.clear();
|
other.clear();
|
||||||
@@ -487,6 +533,12 @@ void PIConfig::parse() {
|
|||||||
while (!isEnd()) {
|
while (!isEnd()) {
|
||||||
other.push_back(PIString());
|
other.push_back(PIString());
|
||||||
src = str = readLine();
|
src = str = readLine();
|
||||||
|
tprefix = getPrefixFromLine(src, &isPrefix);
|
||||||
|
if (isPrefix) {
|
||||||
|
prefix = tprefix;
|
||||||
|
if (!prefix.isEmpty())
|
||||||
|
prefix += delim;
|
||||||
|
}
|
||||||
tab = str.left(str.find(str.trimmed().left(1)));
|
tab = str.left(str.find(str.trimmed().left(1)));
|
||||||
str.trim();
|
str.trim();
|
||||||
//cout << endl << str << endl << endl;
|
//cout << endl << str << endl << endl;
|
||||||
@@ -505,7 +557,7 @@ void PIConfig::parse() {
|
|||||||
comm = "";
|
comm = "";
|
||||||
}
|
}
|
||||||
//name = str.left(ind).trimmed();
|
//name = str.left(ind).trimmed();
|
||||||
tree = str.left(ind).trimmed().split(delim);
|
tree = (prefix + str.left(ind).trimmed()).split(delim);
|
||||||
name = tree.back();
|
name = tree.back();
|
||||||
tree.pop_back();
|
tree.pop_back();
|
||||||
entry = &root;
|
entry = &root;
|
||||||
|
|||||||
13
piconfig.h
13
piconfig.h
@@ -61,7 +61,7 @@ public:
|
|||||||
//! Contructs and read configuration file at path "path" in mode "mode"
|
//! Contructs and read configuration file at path "path" in mode "mode"
|
||||||
PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
|
|
||||||
~PIConfig() {/*piForeach (Entry * i, root._children) deleteEntry(i); close();*/}
|
~PIConfig() {root.deleteBranch(); close();}
|
||||||
|
|
||||||
class Entry;
|
class Entry;
|
||||||
|
|
||||||
@@ -70,6 +70,7 @@ public:
|
|||||||
friend class PIConfig;
|
friend class PIConfig;
|
||||||
friend class Entry;
|
friend class Entry;
|
||||||
friend std::ostream & operator <<(std::ostream & s, const Branch & v);
|
friend std::ostream & operator <<(std::ostream & s, const Branch & v);
|
||||||
|
friend PICout operator <<(PICout s, const Branch & v);
|
||||||
public:
|
public:
|
||||||
Branch() {;}
|
Branch() {;}
|
||||||
|
|
||||||
@@ -85,12 +86,13 @@ public:
|
|||||||
bool isEntryExists(const PIString & name) const {piForeachC (Entry * i, *this) if (entryExists(i, name)) return true; return false;}
|
bool isEntryExists(const PIString & name) const {piForeachC (Entry * i, *this) if (entryExists(i, name)) return true; return false;}
|
||||||
int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;}
|
int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;}
|
||||||
|
|
||||||
void clear() {piForeach (Entry * i, *this) delete i; PIVector<Entry * >::clear();}
|
//void clear() {piForeach (Entry * i, *this) delete i; PIVector<Entry * >::clear();}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool entryExists(const Entry * e, const PIString & name) const;
|
bool entryExists(const Entry * e, const PIString & name) const;
|
||||||
void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}}
|
void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}}
|
||||||
void coutt(std::ostream & s, const PIString & p) const {piForeachC (Entry * i, *this) i->coutt(s, p);}
|
void coutt(std::ostream & s, const PIString & p) const {piForeachC (Entry * i, *this) i->coutt(s, p);}
|
||||||
|
void piCoutt(PICout s, const PIString & p) const {piForeachC (Entry * i, *this) i->piCoutt(s, p);}
|
||||||
|
|
||||||
static Entry _empty;
|
static Entry _empty;
|
||||||
PIString delim;
|
PIString delim;
|
||||||
@@ -296,6 +298,8 @@ public:
|
|||||||
void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;}
|
void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;}
|
||||||
void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;}
|
void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;}
|
||||||
void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->coutt(s, nl);}
|
void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->coutt(s, nl);}
|
||||||
|
void piCoutt(PICout s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << NewLine; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->piCoutt(s, nl);}
|
||||||
|
void deleteBranch() {piForeach (Entry * i, _children) {i->deleteBranch(); delete i;}}
|
||||||
|
|
||||||
static Entry _empty;
|
static Entry _empty;
|
||||||
Entry * _parent;
|
Entry * _parent;
|
||||||
@@ -432,6 +436,8 @@ public:
|
|||||||
void removeEntry(const PIString & name, bool write = true);
|
void removeEntry(const PIString & name, bool write = true);
|
||||||
void removeEntry(uint number, bool write = true);
|
void removeEntry(uint number, bool write = true);
|
||||||
|
|
||||||
|
//! Remove all tree and file content
|
||||||
|
void clear() {PIFile::clear(); parse();}
|
||||||
|
|
||||||
//! Parse file and build internal tree
|
//! Parse file and build internal tree
|
||||||
void readAll();
|
void readAll();
|
||||||
@@ -454,6 +460,7 @@ private:
|
|||||||
Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);}
|
Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);}
|
||||||
void removeEntry(Branch & b, Entry * e);
|
void removeEntry(Branch & b, Entry * e);
|
||||||
void deleteEntry(Entry * e) {piForeach (Entry * i, e->_children) deleteEntry(i); delete e;}
|
void deleteEntry(Entry * e) {piForeach (Entry * i, e->_children) deleteEntry(i); delete e;}
|
||||||
|
PIString getPrefixFromLine(PIString line, bool * exists);
|
||||||
void parse();
|
void parse();
|
||||||
|
|
||||||
int centry;
|
int centry;
|
||||||
@@ -467,6 +474,8 @@ private:
|
|||||||
|
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIConfig::Branch & v) {v.coutt(s, ""); return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIConfig::Branch & v) {v.coutt(s, ""); return s;}
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIConfig::Entry & v) {s << v.value(); return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIConfig::Entry & v) {s << v.value(); return s;}
|
||||||
|
inline PICout operator <<(PICout s, const PIConfig::Branch & v) {s.setControl(0, true); v.piCoutt(s, ""); s.restoreControl(); return s;}
|
||||||
|
inline PICout operator <<(PICout s, const PIConfig::Entry & v) {s << v.value(); return s;}
|
||||||
|
|
||||||
|
|
||||||
/** \relatesalso PIConfig \relatesalso PIIODevice
|
/** \relatesalso PIConfig \relatesalso PIIODevice
|
||||||
|
|||||||
@@ -53,17 +53,18 @@ PIConsole::PIConsole(bool startNow, KBFunc slot): PIThread() {
|
|||||||
setPriority(piLow);
|
setPriority(piLow);
|
||||||
needLockRun(true);
|
needLockRun(true);
|
||||||
ret_func = slot;
|
ret_func = slot;
|
||||||
num_format = 0;
|
num_format = systime_format = 0;
|
||||||
vid = 0;
|
vid = 0;
|
||||||
cur_tab = width = height = pwidth = pheight = max_y = 0;
|
cur_tab = width = height = pwidth = pheight = max_y = 0;
|
||||||
def_align = Nothing;
|
def_align = Nothing;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
ulcoord.X = ulcoord.Y = 0;
|
ulcoord.X = 0;
|
||||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
GetConsoleScreenBufferInfo(hOut, &sbi);
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
||||||
dattr = sbi.wAttributes;
|
dattr = sbi.wAttributes;
|
||||||
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
||||||
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
|
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
|
||||||
|
ulcoord.Y = sbi.srWindow.Top;
|
||||||
GetConsoleMode(hOut, &smode);
|
GetConsoleMode(hOut, &smode);
|
||||||
GetConsoleCursorInfo(hOut, &curinfo);
|
GetConsoleCursorInfo(hOut, &curinfo);
|
||||||
#endif
|
#endif
|
||||||
@@ -217,11 +218,14 @@ void PIConsole::stop(bool clear) {
|
|||||||
|
|
||||||
|
|
||||||
PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
|
PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
|
||||||
|
num_format = systime_format = 0;
|
||||||
if (f[PIConsole::Dec]) num_format = 0;
|
if (f[PIConsole::Dec]) num_format = 0;
|
||||||
if (f[PIConsole::Hex]) num_format = 1;
|
if (f[PIConsole::Hex]) num_format = 1;
|
||||||
if (f[PIConsole::Oct]) num_format = 2;
|
if (f[PIConsole::Oct]) num_format = 2;
|
||||||
if (f[PIConsole::Bin]) num_format = 4;
|
if (f[PIConsole::Bin]) num_format = 4;
|
||||||
if (f[PIConsole::Scientific]) num_format = 3;
|
if (f[PIConsole::Scientific]) num_format = 3;
|
||||||
|
if (f[PIConsole::SystemTimeSplit]) systime_format = 0;
|
||||||
|
if (f[PIConsole::SystemTimeSeconds]) systime_format = 1;
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
WORD attr = 0;
|
WORD attr = 0;
|
||||||
@@ -298,33 +302,48 @@ PIString PIConsole::fstr(PIFlags<PIConsole::Format> f) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define siprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 2)); break; default: return printf("%hd", x); break;}
|
|
||||||
#define iprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 4)); break; default: return printf("%d", x); break;}
|
|
||||||
#define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%ld", x); break;}
|
|
||||||
#define lliprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%lld", x); break;}
|
|
||||||
#define cuprint(x) switch (num_format) {case (1): return printf("0x%.2X", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 1)); break; default: return printf("%u", x); break;}
|
|
||||||
#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 2)); break; default: return printf("%hu", x); break;}
|
|
||||||
#define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; case (4): return printf("%s", toBin(&x, 4)); break; default: return printf("%u", x); break;}
|
|
||||||
#define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%lu", x); break;}
|
|
||||||
#define lluprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; case (4): return printf("%s", toBin(&x, sizeof(x))); break; default: return printf("%llu", x); break;}
|
|
||||||
#define fprint(x) switch (num_format) {case (3): return printf("%e", x); break; default: return printf("%.5g", x); break;}
|
|
||||||
#define dprint(x) switch (num_format) {case (3): return printf("%le", x); break; default: return printf("%.5lg", x); break;}
|
|
||||||
|
|
||||||
inline int PIConsole::couts(const PIString & v) {return printf("%s", v.data());}
|
inline int PIConsole::couts(const PIString & v) {return printf("%s", v.data());}
|
||||||
inline int PIConsole::couts(const char * v) {return printf("%s", v);}
|
inline int PIConsole::couts(const char * v) {return printf("%s", v);}
|
||||||
inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));}
|
inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));}
|
||||||
inline int PIConsole::couts(const char v) {return printf("%c", v);}
|
inline int PIConsole::couts(const char v) {return printf("%c", v);}
|
||||||
inline int PIConsole::couts(const short v) {siprint(v);}
|
inline int PIConsole::couts(const short v) {
|
||||||
inline int PIConsole::couts(const int v) {iprint(v);}
|
switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hd", v); break;}
|
||||||
inline int PIConsole::couts(const long v) {liprint(v);}
|
}
|
||||||
inline int PIConsole::couts(const llong v) {lliprint(v);}
|
inline int PIConsole::couts(const int v) {
|
||||||
inline int PIConsole::couts(const uchar v) {cuprint(v);}
|
switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%d", v); break;}
|
||||||
inline int PIConsole::couts(const ushort v) {suprint(v);}
|
}
|
||||||
inline int PIConsole::couts(const uint v) {uprint(v);}
|
inline int PIConsole::couts(const long v) {
|
||||||
inline int PIConsole::couts(const ulong v) {luprint(v);}
|
switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%ld", v); break;}
|
||||||
inline int PIConsole::couts(const ullong v) {lluprint(v);}
|
}
|
||||||
inline int PIConsole::couts(const float v) {fprint(v);}
|
inline int PIConsole::couts(const llong v) {
|
||||||
inline int PIConsole::couts(const double v) {dprint(v);}
|
switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lld", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const uchar v) {
|
||||||
|
switch (num_format) {case (1): return printf("0x%.2X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 1)); break; default: return printf("%u", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const ushort v) {
|
||||||
|
switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hu", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const uint v) {
|
||||||
|
switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%u", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const ulong v) {
|
||||||
|
switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lu", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const ullong v) {
|
||||||
|
switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%llu", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const float v) {
|
||||||
|
switch (num_format) {case (3): return printf("%e", v); break; default: return printf("%.5g", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const double v) {
|
||||||
|
switch (num_format) {case (3): return printf("%le", v); break; default: return printf("%.5lg", v); break;}
|
||||||
|
}
|
||||||
|
inline int PIConsole::couts(const PISystemTime & v) {
|
||||||
|
switch (systime_format) {case (1): return printf("%.6lg", v.toSeconds()); break;
|
||||||
|
default: return couts(v.seconds) + printf(" s, ") + couts(v.nanoseconds) + printf(" ns"); break;}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConsole::begin() {
|
void PIConsole::begin() {
|
||||||
@@ -405,6 +424,7 @@ void PIConsole::run() {
|
|||||||
case 11: clen = printValue(ptr != 0 ? *(const uchar*)ptr : uchar(0), tv.format); break;
|
case 11: clen = printValue(ptr != 0 ? *(const uchar*)ptr : uchar(0), tv.format); break;
|
||||||
case 12: clen = printValue(ptr != 0 ? *(const llong*)ptr : 0l, tv.format); break;
|
case 12: clen = printValue(ptr != 0 ? *(const llong*)ptr : 0l, tv.format); break;
|
||||||
case 13: clen = printValue(ptr != 0 ? *(const ullong*)ptr: 0ull, tv.format); break;
|
case 13: clen = printValue(ptr != 0 ? *(const ullong*)ptr: 0ull, tv.format); break;
|
||||||
|
case 20: clen = printValue(ptr != 0 ? *(const PISystemTime*)ptr: PISystemTime(), tv.format); break;
|
||||||
case 14: clen = printValue(bitsValue(ptr, tv.bitFrom, tv.bitCount), tv.format); break;
|
case 14: clen = printValue(bitsValue(ptr, tv.bitFrom, tv.bitCount), tv.format); break;
|
||||||
}
|
}
|
||||||
if (clen + tv.offset < (uint)col_wid) {
|
if (clen + tv.offset < (uint)col_wid) {
|
||||||
@@ -605,6 +625,8 @@ void PIConsole::addVariable(const PIString & name, const llong * ptr, int col, P
|
|||||||
ADD_VAR_BODY tv.type = 12; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
|
ADD_VAR_BODY tv.type = 12; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
|
||||||
void PIConsole::addVariable(const PIString & name, const ullong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
void PIConsole::addVariable(const PIString & name, const ullong * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||||
ADD_VAR_BODY tv.type = 13; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
|
ADD_VAR_BODY tv.type = 13; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
|
||||||
|
void PIConsole::addVariable(const PIString & name, const PISystemTime * ptr, int col, PIFlags<PIConsole::Format> format) {
|
||||||
|
ADD_VAR_BODY tv.type = 20; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);}
|
||||||
/** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
|
/** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
|
||||||
* \details This function add to column "column" next lines:
|
* \details This function add to column "column" next lines:
|
||||||
* * "protocol <name>"
|
* * "protocol <name>"
|
||||||
@@ -751,6 +773,7 @@ inline int PIConsole::printValue(const ushort value, PIFlags<PIConsole::Format>
|
|||||||
inline int PIConsole::printValue(const uint value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
inline int PIConsole::printValue(const uint value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||||
inline int PIConsole::printValue(const ulong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
inline int PIConsole::printValue(const ulong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||||
inline int PIConsole::printValue(const ullong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
inline int PIConsole::printValue(const ullong value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||||
|
inline int PIConsole::printValue(const PISystemTime & value, PIFlags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
piconsole.h
13
piconsole.h
@@ -76,7 +76,9 @@ public:
|
|||||||
Hex /** Hexadecimal base for integers */ = 0x2000000,
|
Hex /** Hexadecimal base for integers */ = 0x2000000,
|
||||||
Oct /** Octal base for integers */ = 0x4000000,
|
Oct /** Octal base for integers */ = 0x4000000,
|
||||||
Bin /** Binary base for integers */ = 0x8000000,
|
Bin /** Binary base for integers */ = 0x8000000,
|
||||||
Scientific /** Scientific representation of floats */ = 0x10000000
|
Scientific /** Scientific representation of floats */ = 0x10000000,
|
||||||
|
SystemTimeSplit /** PISystemTime split representation (* s, * ns) */ = 0x20000000,
|
||||||
|
SystemTimeSeconds /** PISystemTime seconds representation (*.* s) */ = 0x40000000
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Column labels alignment
|
//! Column labels alignment
|
||||||
@@ -131,6 +133,9 @@ public:
|
|||||||
//! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
|
//! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
|
||||||
void addVariable(const PIString & name, const double * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const double * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
|
|
||||||
|
//! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format"
|
||||||
|
void addVariable(const PIString & name, const PISystemTime * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
|
|
||||||
void addVariable(const PIString & name, const PIProtocol * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const PIProtocol * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
void addVariable(const PIString & name, const PIDiagnostics * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const PIDiagnostics * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
@@ -234,7 +239,7 @@ public:
|
|||||||
void toUpperLeft() {SetConsoleCursorPosition(hOut, ulcoord);}
|
void toUpperLeft() {SetConsoleCursorPosition(hOut, ulcoord);}
|
||||||
void moveRight(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(n));}
|
void moveRight(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(n));}
|
||||||
void moveLeft(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(-n));}
|
void moveLeft(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(-n));}
|
||||||
void moveTo(int x = 0, int y = 0) {ccoord.X = x; ccoord.Y = y; SetConsoleCursorPosition(hOut, ccoord);}
|
void moveTo(int x = 0, int y = 0) {ccoord.X = x; ccoord.Y = ulcoord.Y + y; SetConsoleCursorPosition(hOut, ccoord);}
|
||||||
void clearScreen() {toUpperLeft(); FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written);
|
void clearScreen() {toUpperLeft(); FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written);
|
||||||
FillConsoleOutputCharacter(hOut, ' ', width * (height + 1), ulcoord, &written);}
|
FillConsoleOutputCharacter(hOut, ' ', width * (height + 1), ulcoord, &written);}
|
||||||
void clearScreenLower() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width * height - width * ccoord.Y + ccoord.X, ccoord, &written);
|
void clearScreenLower() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width * height - width * ccoord.Y + ccoord.X, ccoord, &written);
|
||||||
@@ -321,6 +326,7 @@ private:
|
|||||||
inline int printValue(const uint value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const uint value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const ulong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const ulong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
inline int printValue(const ullong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
inline int printValue(const ullong value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
|
inline int printValue(const PISystemTime & value, PIFlags<PIConsole::Format> format = PIConsole::Normal);
|
||||||
static void key_event(char key, void * t);
|
static void key_event(char key, void * t);
|
||||||
|
|
||||||
struct Variable {
|
struct Variable {
|
||||||
@@ -406,6 +412,7 @@ private:
|
|||||||
inline int couts(const ullong v);
|
inline int couts(const ullong v);
|
||||||
inline int couts(const float v);
|
inline int couts(const float v);
|
||||||
inline int couts(const double v);
|
inline int couts(const double v);
|
||||||
|
inline int couts(const PISystemTime & v);
|
||||||
|
|
||||||
struct RemoteClient;
|
struct RemoteClient;
|
||||||
|
|
||||||
@@ -433,7 +440,7 @@ private:
|
|||||||
PIKbdListener * listener;
|
PIKbdListener * listener;
|
||||||
Alignment def_align;
|
Alignment def_align;
|
||||||
KBFunc ret_func;
|
KBFunc ret_func;
|
||||||
int width, height, pwidth, pheight, ret, col_wid, num_format;
|
int width, height, pwidth, pheight, ret, col_wid, num_format, systime_format;
|
||||||
uint max_y;
|
uint max_y;
|
||||||
int vid;
|
int vid;
|
||||||
uint cur_tab, col_cnt;
|
uint cur_tab, col_cnt;
|
||||||
|
|||||||
@@ -27,8 +27,25 @@
|
|||||||
#define PICONTAINERS_H
|
#define PICONTAINERS_H
|
||||||
|
|
||||||
#include "pivector.h"
|
#include "pivector.h"
|
||||||
|
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
class PIP_EXPORT PIPair {
|
||||||
|
public:
|
||||||
|
PIPair() {first = Type0(); second = Type1();}
|
||||||
|
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
||||||
|
Type0 first;
|
||||||
|
Type1 second;
|
||||||
|
};
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {s << "(" << v.first << ", " << v.second << ")"; return s;}
|
||||||
|
template<typename Type0, typename Type1>
|
||||||
|
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
#include "pistack.h"
|
#include "pistack.h"
|
||||||
#include "piqueue.h"
|
#include "piqueue.h"
|
||||||
|
#include "pimap.h"
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
/*! \def piForeach(i,c)
|
/*! \def piForeach(i,c)
|
||||||
@@ -295,73 +312,4 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename Type0, typename Type1>
|
|
||||||
class PIP_EXPORT PIPair {
|
|
||||||
public:
|
|
||||||
PIPair() {first = Type0(); second = Type1();}
|
|
||||||
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
|
||||||
Type0 first;
|
|
||||||
Type1 second;
|
|
||||||
};
|
|
||||||
template<typename Type0, typename Type1>
|
|
||||||
inline bool operator <(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {return value0.first < value1.first;}
|
|
||||||
template<typename Type0, typename Type1>
|
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {s << "(" << v.first << ", " << v.second << ")"; return s;}
|
|
||||||
template<typename Type0, typename Type1>
|
|
||||||
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Key, typename Type>
|
|
||||||
class PIP_EXPORT PIMap: public map<Key, Type> {
|
|
||||||
typedef PIMap<Key, Type> _CMap;
|
|
||||||
typedef map<Key, Type> _stlc;
|
|
||||||
typedef std::pair<Key, Type> _stlpair;
|
|
||||||
public:
|
|
||||||
PIMap() {;}
|
|
||||||
PIMap(const Key & key_, const Type & value_) {insert(key_, value_);}
|
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
|
||||||
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
|
||||||
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
|
||||||
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
|
||||||
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
|
||||||
Type & value(const Key & key_) {typename _stlc::iterator it = _stlc::find(key_); if (it == _stlc::end()) it->second = Type(); return it->second;}
|
|
||||||
Type & at(const Key & key_) {return value(key_);}
|
|
||||||
Type value(const Key & key_) const {return _stlc::find(key_)->second;}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Key, typename Type>
|
|
||||||
class PIP_EXPORT PIMultiMap: public multimap<Key, Type> {
|
|
||||||
typedef PIMultiMap<Key, Type> _CMultiMap;
|
|
||||||
typedef multimap<Key, Type> _stlc;
|
|
||||||
typedef std::pair<Key, Type> _stlpair;
|
|
||||||
public:
|
|
||||||
PIMultiMap() {;}
|
|
||||||
PIMultiMap(const Key & key_, const Type & value_) {insert(key_, value_);}
|
|
||||||
_CMultiMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
|
||||||
_CMultiMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
|
||||||
bool isEmpty() const {return _stlc::empty();}
|
|
||||||
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
|
||||||
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
|
||||||
PIVector<Key> keys(Type value_) const {
|
|
||||||
PIVector<Key> ret;
|
|
||||||
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
|
|
||||||
if (i->second == value_)
|
|
||||||
ret << i->first;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Type & value(const Key & key_) {return _stlc::find(key_)->second;}
|
|
||||||
Type value(const Key & key_) const {return _stlc::find(key_)->second;}
|
|
||||||
PIVector<Type> values(const Key & key_) const {
|
|
||||||
std::pair<typename _stlc::const_iterator, typename _stlc::const_iterator> range = _stlc::equal_range(key_);
|
|
||||||
PIVector<Type> ret;
|
|
||||||
for (typename _stlc::const_iterator i = range.first; i != range.second; ++i)
|
|
||||||
ret << i->second;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Type & operator [](const Key & key_) {if (!contains(key_)) return _stlc::insert(_stlpair(key_, Type()))->second; return _stlc::find(key_)->second;}
|
|
||||||
Type operator [](const Key & key_) const {return _stlc::find(key_)->second;}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PICONTAINERS_H
|
#endif // PICONTAINERS_H
|
||||||
|
|||||||
131
piethernet.cpp
131
piethernet.cpp
@@ -53,7 +53,7 @@ PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) {
|
|||||||
ip_ = ip_s = "";
|
ip_ = ip_s = "";
|
||||||
port_ = port_s = 0;
|
port_ = port_s = 0;
|
||||||
sock = sock_s = -1;
|
sock = sock_s = -1;
|
||||||
connected_ = false;
|
connected_ = connecting_ = false;
|
||||||
params = PIEthernet::ReuseAddress;
|
params = PIEthernet::ReuseAddress;
|
||||||
server_thread_.setData(this);
|
server_thread_.setData(this);
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
@@ -69,7 +69,7 @@ PIEthernet::PIEthernet(PIEthernet::Type type, const PIString & ip_port, const PI
|
|||||||
ip_s = "";
|
ip_s = "";
|
||||||
port_s = 0;
|
port_s = 0;
|
||||||
sock = sock_s = -1;
|
sock = sock_s = -1;
|
||||||
connected_ = false;
|
connected_ = connecting_ = false;
|
||||||
params = params_;
|
params = params_;
|
||||||
server_thread_.setData(this);
|
server_thread_.setData(this);
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
@@ -88,6 +88,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
|||||||
server_thread_.setData(this);
|
server_thread_.setData(this);
|
||||||
params = PIEthernet::ReuseAddress;
|
params = PIEthernet::ReuseAddress;
|
||||||
init_ = opened_ = connected_ = true;
|
init_ = opened_ = connected_ = true;
|
||||||
|
connecting_ = false;
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +134,11 @@ bool PIEthernet::init() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
|
timeval to;
|
||||||
|
to.tv_sec = 10;
|
||||||
|
to.tv_usec = 0;
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to));
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &to, sizeof(to));
|
||||||
if (params[PIEthernet::ReuseAddress]) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));
|
if (params[PIEthernet::ReuseAddress]) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));
|
||||||
if (params[PIEthernet::Broadcast]) setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &so, sizeof(so));
|
if (params[PIEthernet::Broadcast]) setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &so, sizeof(so));
|
||||||
#else
|
#else
|
||||||
@@ -300,7 +306,9 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
|||||||
|
|
||||||
|
|
||||||
bool PIEthernet::connect() {
|
bool PIEthernet::connect() {
|
||||||
if (sock == -1) return false;
|
connecting_ = true;
|
||||||
|
return true;
|
||||||
|
/*if (sock == -1) return false;
|
||||||
memset(&addr_, 0, sizeof(addr_));
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
parseAddress(path_, &ip_, &port_);
|
parseAddress(path_, &ip_, &port_);
|
||||||
addr_.sin_port = htons(port_);
|
addr_.sin_port = htons(port_);
|
||||||
@@ -315,7 +323,7 @@ bool PIEthernet::connect() {
|
|||||||
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
opened_ = connected_;
|
opened_ = connected_;
|
||||||
if (connected_) connected();
|
if (connected_) connected();
|
||||||
return connected_;
|
return connected_;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -330,6 +338,7 @@ bool PIEthernet::listen() {
|
|||||||
#ifdef QNX
|
#ifdef QNX
|
||||||
addr_.sin_len = sizeof(addr_);
|
addr_.sin_len = sizeof(addr_);
|
||||||
#endif
|
#endif
|
||||||
|
opened_ = false;
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
while ((bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) && (tries < 10)) {
|
while ((bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) && (tries < 10)) {
|
||||||
init();
|
init();
|
||||||
@@ -343,6 +352,7 @@ bool PIEthernet::listen() {
|
|||||||
piCoutObj << "Can`t listen on "<< ip_ << ":" << port_ << ", " << ethErrorString();
|
piCoutObj << "Can`t listen on "<< ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
opened_ = true;
|
||||||
//piCoutObj << "listen on " << ip_ << ":" << port_;
|
//piCoutObj << "listen on " << ip_ << ":" << port_;
|
||||||
server_thread_.start(server_func);
|
server_thread_.start(server_func);
|
||||||
return true;
|
return true;
|
||||||
@@ -353,7 +363,7 @@ int PIEthernet::read(void * read_to, int max_size) {
|
|||||||
//cout << "read " << sock << endl;
|
//cout << "read " << sock << endl;
|
||||||
if (sock == -1) init();
|
if (sock == -1) init();
|
||||||
if (sock == -1 || read_to == 0) return -1;
|
if (sock == -1 || read_to == 0) return -1;
|
||||||
int rs = 0, s = 0;
|
int rs = 0, s = 0, lerr = 0;
|
||||||
sockaddr_in client_addr;
|
sockaddr_in client_addr;
|
||||||
socklen_t slen = sizeof(client_addr);
|
socklen_t slen = sizeof(client_addr);
|
||||||
//piCoutObj << "read from " << ip_ << ":" << port_ << endl;
|
//piCoutObj << "read from " << ip_ << ":" << port_ << endl;
|
||||||
@@ -370,7 +380,51 @@ int PIEthernet::read(void * read_to, int max_size) {
|
|||||||
closeSocket(s);
|
closeSocket(s);
|
||||||
return rs;
|
return rs;
|
||||||
case TCP_Client:
|
case TCP_Client:
|
||||||
|
if (connecting_) {
|
||||||
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
|
parseAddress(path_, &ip_, &port_);
|
||||||
|
addr_.sin_port = htons(port_);
|
||||||
|
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||||
|
addr_.sin_family = AF_INET;
|
||||||
|
#ifdef QNX
|
||||||
|
addr_.sin_len = sizeof(addr_);
|
||||||
|
#endif
|
||||||
|
//piCoutObj << "connect to " << ip << ":" << port_;
|
||||||
|
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||||
|
if (!connected_)
|
||||||
|
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
|
opened_ = connected_;
|
||||||
|
if (connected_) {
|
||||||
|
connecting_ = false;
|
||||||
|
connected();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!connected_) return -1;
|
if (!connected_) return -1;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
rs = recv(sock, (char * )read_to, max_size, 0);
|
||||||
|
#else
|
||||||
|
rs = recv(sock, read_to, max_size, MSG_DONTWAIT);
|
||||||
|
#endif
|
||||||
|
if (rs <= 0) {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
lerr = WSAGetLastError();
|
||||||
|
if (lerr == WSAEWOULDBLOCK) {
|
||||||
|
piMSleep(1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
lerr = errno;
|
||||||
|
if (lerr == EAGAIN || lerr == EWOULDBLOCK) {
|
||||||
|
piMSleep(1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (connected_) disconnected(rs < 0);
|
||||||
|
connected_ = false;
|
||||||
|
//piCoutObj << "eth" << path_ << "disconnected";
|
||||||
|
}
|
||||||
|
if (rs > 0) received(read_to, rs);
|
||||||
|
return rs;
|
||||||
case UDP:
|
case UDP:
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
rs = recv(sock, (char * )read_to, max_size, 0);
|
rs = recv(sock, (char * )read_to, max_size, 0);
|
||||||
@@ -378,11 +432,6 @@ int PIEthernet::read(void * read_to, int max_size) {
|
|||||||
rs = recv(sock, read_to, max_size, 0);
|
rs = recv(sock, read_to, max_size, 0);
|
||||||
#endif
|
#endif
|
||||||
//piCout << "eth" << path_ << "read return" << rs << errno;
|
//piCout << "eth" << path_ << "read return" << rs << errno;
|
||||||
if (rs <= 0 && type_ == TCP_Client) {
|
|
||||||
connected_ = false;
|
|
||||||
if (connected_) disconnected(rs < 0);
|
|
||||||
//piCoutObj << "eth" << path_ << "disconnected";
|
|
||||||
}
|
|
||||||
if (rs > 0) received(read_to, rs);
|
if (rs > 0) received(read_to, rs);
|
||||||
return rs;
|
return rs;
|
||||||
//return ::read(sock, read_to, max_size);
|
//return ::read(sock, read_to, max_size);
|
||||||
@@ -435,6 +484,26 @@ int PIEthernet::write(const void * data, int max_size) {
|
|||||||
#endif
|
#endif
|
||||||
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
||||||
case TCP_Client:
|
case TCP_Client:
|
||||||
|
if (connecting_) {
|
||||||
|
memset(&addr_, 0, sizeof(addr_));
|
||||||
|
parseAddress(path_, &ip_, &port_);
|
||||||
|
addr_.sin_port = htons(port_);
|
||||||
|
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||||
|
addr_.sin_family = AF_INET;
|
||||||
|
#ifdef QNX
|
||||||
|
addr_.sin_len = sizeof(addr_);
|
||||||
|
#endif
|
||||||
|
//piCoutObj << "connect to " << ip << ":" << port_;
|
||||||
|
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||||
|
if (!connected_)
|
||||||
|
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||||
|
opened_ = connected_;
|
||||||
|
if (connected_) {
|
||||||
|
connecting_ = false;
|
||||||
|
connected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!connected_) return -1;
|
||||||
return ::send(sock, (const char *)data, max_size, 0);
|
return ::send(sock, (const char *)data, max_size, 0);
|
||||||
default: break;
|
default: break;
|
||||||
//return ::read(sock, read_to, max_size);
|
//return ::read(sock, read_to, max_size);
|
||||||
@@ -475,9 +544,9 @@ bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
|
|||||||
|
|
||||||
|
|
||||||
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||||
#ifdef WINDOWS
|
|
||||||
PIEthernet::InterfaceList il;
|
PIEthernet::InterfaceList il;
|
||||||
Interface ci;
|
Interface ci;
|
||||||
|
#ifdef WINDOWS
|
||||||
PIP_ADAPTER_INFO pAdapterInfo, pAdapter = 0;
|
PIP_ADAPTER_INFO pAdapterInfo, pAdapter = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||||
@@ -524,7 +593,6 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret;
|
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret;
|
||||||
if (pAdapterInfo)
|
if (pAdapterInfo)
|
||||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||||
return il;
|
|
||||||
#else
|
#else
|
||||||
/*# ifdef QNX
|
/*# ifdef QNX
|
||||||
PIStringList il, sl;
|
PIStringList il, sl;
|
||||||
@@ -560,8 +628,34 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
}
|
}
|
||||||
return sl;
|
return sl;
|
||||||
# endif*/
|
# endif*/
|
||||||
PIEthernet::InterfaceList il;
|
# ifdef ANDROID
|
||||||
Interface ci;
|
struct ifconf ifc;
|
||||||
|
int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||||
|
ifc.ifc_len = 256;
|
||||||
|
ifc.ifc_buf = new char[ifc.ifc_len];
|
||||||
|
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
|
||||||
|
piCout << "[PIEthernet] Can`t get interfaces:" << errorString();
|
||||||
|
delete ifc.ifc_buf;
|
||||||
|
return il;
|
||||||
|
}
|
||||||
|
int icnt = ifc.ifc_len / sizeof(ifreq);
|
||||||
|
PIStringList inl;
|
||||||
|
struct ifreq ir;
|
||||||
|
for (int i = 0; i < icnt; ++i) {
|
||||||
|
PIString in(ifc.ifc_req[i].ifr_name);
|
||||||
|
if (in.isEmpty()) continue;
|
||||||
|
ci.name = in;
|
||||||
|
strcpy(ir.ifr_name, in.data());
|
||||||
|
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0)
|
||||||
|
ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||||
|
if (ioctl(s, SIOCGIFADDR, &ir) >= 0)
|
||||||
|
ci.address = getSockAddr(&ir.ifr_addr);
|
||||||
|
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0)
|
||||||
|
ci.netmask = getSockAddr(&ir.ifr_addr);
|
||||||
|
il << ci;
|
||||||
|
}
|
||||||
|
delete ifc.ifc_buf;
|
||||||
|
# else
|
||||||
struct ifaddrs * ret;
|
struct ifaddrs * ret;
|
||||||
int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||||
if (getifaddrs(&ret) == 0) {
|
if (getifaddrs(&ret) == 0) {
|
||||||
@@ -574,7 +668,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
ci.address = getSockAddr(ret->ifa_addr);
|
ci.address = getSockAddr(ret->ifa_addr);
|
||||||
ci.netmask = getSockAddr(ret->ifa_netmask);
|
ci.netmask = getSockAddr(ret->ifa_netmask);
|
||||||
ci.mac.clear();
|
ci.mac.clear();
|
||||||
#ifdef QNX
|
# ifdef QNX
|
||||||
int fd = ::open((PIString("/dev/io-net/") + ci.name).data(), O_RDONLY);
|
int fd = ::open((PIString("/dev/io-net/") + ci.name).data(), O_RDONLY);
|
||||||
if (fd != 0) {
|
if (fd != 0) {
|
||||||
nic_config_t nic;
|
nic_config_t nic;
|
||||||
@@ -582,7 +676,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
::close(fd);
|
::close(fd);
|
||||||
ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6));
|
ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6));
|
||||||
}
|
}
|
||||||
#else
|
# else
|
||||||
# ifdef MAC_OS
|
# ifdef MAC_OS
|
||||||
PIString req = PIString(ifconfigPath) + " " + ci.name + " | grep ether";
|
PIString req = PIString(ifconfigPath) + " " + ci.name + " | grep ether";
|
||||||
FILE * fp = popen(req.data(), "r");
|
FILE * fp = popen(req.data(), "r");
|
||||||
@@ -602,7 +696,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
# endif
|
||||||
ci.flags = 0;
|
ci.flags = 0;
|
||||||
if (ret->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive;
|
if (ret->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive;
|
||||||
if (ret->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning;
|
if (ret->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning;
|
||||||
@@ -624,8 +718,9 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
} else
|
} else
|
||||||
piCout << "[PIEthernet] Can`t get interfaces:" << errorString();
|
piCout << "[PIEthernet] Can`t get interfaces:" << errorString();
|
||||||
if (s != -1) ::close(s);
|
if (s != -1) ::close(s);
|
||||||
return il;
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
return il;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
piethernet.h
12
piethernet.h
@@ -37,7 +37,7 @@ public:
|
|||||||
PIEthernet();
|
PIEthernet();
|
||||||
|
|
||||||
//! \brief Type of %PIEthernet
|
//! \brief Type of %PIEthernet
|
||||||
enum Type {
|
enum PIP_EXPORT Type {
|
||||||
UDP /** UDP - User Datagram Protocol */ ,
|
UDP /** UDP - User Datagram Protocol */ ,
|
||||||
TCP_Client /** TCP client - allow connection to TCP server */ ,
|
TCP_Client /** TCP client - allow connection to TCP server */ ,
|
||||||
TCP_Server /** TCP server - receive connections from TCP clients */ ,
|
TCP_Server /** TCP server - receive connections from TCP clients */ ,
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Parameters of %PIEthernet
|
//! \brief Parameters of %PIEthernet
|
||||||
enum Parameters {
|
enum PIP_EXPORT Parameters {
|
||||||
ReuseAddress /** Rebind address if there is already binded */ = 0x1,
|
ReuseAddress /** Rebind address if there is already binded */ = 0x1,
|
||||||
Broadcast /** Broadcast send */ = 0x2
|
Broadcast /** Broadcast send */ = 0x2
|
||||||
};
|
};
|
||||||
@@ -182,7 +182,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Flags of network interface
|
//! Flags of network interface
|
||||||
enum InterfaceFlag {
|
enum PIP_EXPORT InterfaceFlag {
|
||||||
ifActive /** Is active */ = 0x1,
|
ifActive /** Is active */ = 0x1,
|
||||||
ifRunning /** Is running */ = 0x2,
|
ifRunning /** Is running */ = 0x2,
|
||||||
ifBroadcast /** Support broadcast */ = 0x4,
|
ifBroadcast /** Support broadcast */ = 0x4,
|
||||||
@@ -196,7 +196,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Network interface descriptor
|
//! Network interface descriptor
|
||||||
struct Interface {
|
struct PIP_EXPORT Interface {
|
||||||
|
|
||||||
//! System index
|
//! System index
|
||||||
int index;
|
int index;
|
||||||
@@ -243,7 +243,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Array of \a Interface with some features
|
//! Array of \a Interface with some features
|
||||||
class InterfaceList: public PIVector<PIEthernet::Interface> {
|
class PIP_EXPORT InterfaceList: public PIVector<PIEthernet::Interface> {
|
||||||
public:
|
public:
|
||||||
InterfaceList(): PIVector<PIEthernet::Interface>() {}
|
InterfaceList(): PIVector<PIEthernet::Interface>() {}
|
||||||
|
|
||||||
@@ -323,7 +323,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
int sock, sock_s, port_, port_s, port_c, wrote;
|
int sock, sock_s, port_, port_s, port_c, wrote;
|
||||||
bool connected_;
|
bool connected_, connecting_;
|
||||||
sockaddr_in addr_, saddr_;
|
sockaddr_in addr_, saddr_;
|
||||||
PIString ip_, ip_s, ip_c;
|
PIString ip_, ip_s, ip_c;
|
||||||
PIThread server_thread_;
|
PIThread server_thread_;
|
||||||
|
|||||||
14
pifile.cpp
14
pifile.cpp
@@ -42,19 +42,27 @@
|
|||||||
|
|
||||||
|
|
||||||
bool PIFile::openDevice() {
|
bool PIFile::openDevice() {
|
||||||
if (opened_) close();
|
close();
|
||||||
if (path_.isEmpty()) return false;
|
if (path_.isEmpty()) return false;
|
||||||
//cout << "fopen " << path_.data() << ": " << strType(mode_).data() << endl;
|
//piCout << "fopen " << path_.data() << ": " << strType(mode_).data() << fd;
|
||||||
fd = fopen(path_.data(), strType(mode_).data());
|
fd = fopen(path_.data(), strType(mode_).data());
|
||||||
opened_ = (fd != 0);
|
opened_ = (fd != 0);
|
||||||
|
#ifndef WINDOWS
|
||||||
|
if (opened_) fcntl(fileno(fd), F_SETFL, O_NONBLOCK);
|
||||||
|
#endif
|
||||||
seekToBegin();
|
seekToBegin();
|
||||||
|
//piCout << "open file" << fd << opened_;
|
||||||
return opened_;
|
return opened_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIFile::closeDevice() {
|
bool PIFile::closeDevice() {
|
||||||
|
//piCout << "close file" << fd << opened_;
|
||||||
if (!opened_ || fd == 0) return true;
|
if (!opened_ || fd == 0) return true;
|
||||||
return (fclose(fd) == 0);
|
bool cs = (fclose(fd) == 0);
|
||||||
|
if (cs) fd = 0;
|
||||||
|
//piCout << "closed file" << fd << opened_;
|
||||||
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ PIInit::PIInit() {
|
|||||||
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
|
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
|
||||||
#else
|
#else
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
setlocale(LC_NUMERIC, "C");
|
||||||
#endif
|
#endif
|
||||||
#ifdef MAC_OS
|
#ifdef MAC_OS
|
||||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &__pi_mac_clock);
|
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &__pi_mac_clock);
|
||||||
|
|||||||
75
piincludes.h
75
piincludes.h
@@ -27,7 +27,7 @@
|
|||||||
#define PIINCLUDES_H
|
#define PIINCLUDES_H
|
||||||
|
|
||||||
//! Version of PIP in hex - 0x##(Major)##(Minor)##(Revision)
|
//! Version of PIP in hex - 0x##(Major)##(Minor)##(Revision)
|
||||||
#define PIP_VERSION 0x000307
|
#define PIP_VERSION 0x000308
|
||||||
|
|
||||||
//! Major value of PIP version
|
//! Major value of PIP version
|
||||||
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
|
#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
#define PIP_VERSION_REVISION PIP_VERSION & 0xFF
|
||||||
|
|
||||||
//! Suffix of PIP version
|
//! Suffix of PIP version
|
||||||
#define PIP_VERSION_SUFFIX ""
|
#define PIP_VERSION_SUFFIX "_beta"
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
|
|
||||||
@@ -269,6 +269,9 @@ extern PIMonitor piMonitor;
|
|||||||
//! Macro used for infinite wait
|
//! Macro used for infinite wait
|
||||||
#define FOREVER_WAIT FOREVER msleep(1);
|
#define FOREVER_WAIT FOREVER msleep(1);
|
||||||
|
|
||||||
|
//! Macro used for infinite wait
|
||||||
|
#define WAIT_FOREVER FOREVER msleep(1);
|
||||||
|
|
||||||
typedef long long llong;
|
typedef long long llong;
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
typedef unsigned short int ushort;
|
typedef unsigned short int ushort;
|
||||||
@@ -303,6 +306,23 @@ typedef std::basic_string<wchar_t> wstring;
|
|||||||
* \details Example:\n \snippet piincludes.cpp swap */
|
* \details Example:\n \snippet piincludes.cpp swap */
|
||||||
template<typename T> inline void piSwap(T & f, T & s) {T t = f; f = s; s = t;}
|
template<typename T> inline void piSwap(T & f, T & s) {T t = f; f = s; s = t;}
|
||||||
|
|
||||||
|
/*! \brief Templated function for swap two values without "="
|
||||||
|
* \details Example:\n \snippet piincludes.cpp swapBinary */
|
||||||
|
template<typename T> inline void piSwapBinary(T & f, T & s) {
|
||||||
|
static size_t j = (sizeof(T) / sizeof(size_t)), bs = j * sizeof(size_t), bf = sizeof(T);
|
||||||
|
size_t i = 0;
|
||||||
|
for (i = 0; i < j; ++i) {
|
||||||
|
((size_t*)(&f))[i] ^= ((size_t*)(&s))[i];
|
||||||
|
((size_t*)(&s))[i] ^= ((size_t*)(&f))[i];
|
||||||
|
((size_t*)(&f))[i] ^= ((size_t*)(&s))[i];
|
||||||
|
}
|
||||||
|
for (i = bs; i < bf; ++i) {
|
||||||
|
((uchar*)(&f))[i] ^= ((uchar*)(&s))[i];
|
||||||
|
((uchar*)(&s))[i] ^= ((uchar*)(&f))[i];
|
||||||
|
((uchar*)(&f))[i] ^= ((uchar*)(&s))[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Templated function return round of float falue
|
/*! \brief Templated function return round of float falue
|
||||||
* \details Round is the nearest integer value \n
|
* \details Round is the nearest integer value \n
|
||||||
* There are some macros:
|
* There are some macros:
|
||||||
@@ -413,6 +433,44 @@ template<typename T> inline T piMax(const T & f, const T & s, const T & t) {retu
|
|||||||
* \snippet piincludes.cpp clamp */
|
* \snippet piincludes.cpp clamp */
|
||||||
template<typename T> inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));}
|
template<typename T> inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));}
|
||||||
|
|
||||||
|
/// Function inverse byte order in memory block
|
||||||
|
inline void piLetobe(void * data, int size) {
|
||||||
|
for (int i = 0; i < size / 2; i++)
|
||||||
|
piSwap<uchar>(((uchar*)data)[size - i - 1], ((uchar*)data)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Templated function that inverse byte order of value "v"
|
||||||
|
template<typename T> inline void piLetobe(T * v) {piLetobe(v, sizeof(T));}
|
||||||
|
|
||||||
|
/*! \brief Templated function that returns "v" with inversed byte order
|
||||||
|
* \details This function used to convert values between little and big endian \n
|
||||||
|
* There are some macros:
|
||||||
|
* - \c piLetobes for "ushort"
|
||||||
|
* - \c piLetobei for "uint"
|
||||||
|
* - \c piLetobel for "ulong"
|
||||||
|
* - \c piLetobell for "ullong"
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \snippet piincludes.cpp letobe */
|
||||||
|
template<typename T> inline T piLetobe(const T & v) {T tv(v); piLetobe(&tv, sizeof(T)); return tv;}
|
||||||
|
|
||||||
|
// specialization
|
||||||
|
template<> inline ushort piLetobe(const ushort & v) {return (v << 8) | (v >> 8);}
|
||||||
|
template<> inline uint piLetobe(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||||
|
|
||||||
|
__attribute__((deprecated)) inline ushort letobe_s(const ushort & v) {return (v << 8) | (v >> 8);}
|
||||||
|
__attribute__((deprecated)) inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
|
||||||
|
/// \deprecated \brief Use \a piLetobe() instead of this function
|
||||||
|
ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);}
|
||||||
|
|
||||||
|
/// \deprecated \brief Use \a piLetobe() instead of this function
|
||||||
|
uint letobe_i(uint v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define piRoundf piRound<float>
|
#define piRoundf piRound<float>
|
||||||
#define piRoundd piRound<double>
|
#define piRoundd piRound<double>
|
||||||
#define piFloorf piFloor<float>
|
#define piFloorf piFloor<float>
|
||||||
@@ -443,6 +501,10 @@ template<typename T> inline T piClamp(const T & v, const T & min, const T & max)
|
|||||||
#define piClampll piClamp<llong>
|
#define piClampll piClamp<llong>
|
||||||
#define piClampf piClamp<float>
|
#define piClampf piClamp<float>
|
||||||
#define piClampd piClamp<double>
|
#define piClampd piClamp<double>
|
||||||
|
#define piLetobes piLetobe<ushort>
|
||||||
|
#define piLetobei piLetobe<uint>
|
||||||
|
#define piLetobel piLetobe<ulong>
|
||||||
|
#define piLetobell piLetobe<ullong>
|
||||||
|
|
||||||
extern bool isPIInit;
|
extern bool isPIInit;
|
||||||
|
|
||||||
@@ -472,13 +534,6 @@ inline int random() {return rand();}
|
|||||||
inline double round(const double & v) {return floor(v + 0.5);}
|
inline double round(const double & v) {return floor(v + 0.5);}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);}
|
|
||||||
inline uint letobe_i(uint v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
|
||||||
//inline ullong letobe_ll(ullong v) {return (v >> 56) | ((v >> 40) & 0xFF00L) | ((v >> 24) & 0xFF0000L) | ((v >> 8) & 0xFF000000L) | ((v << 8) & 0xFF00000000L) | ((v << 24) & 0xFF0000000000L) | ((v << 40) & 0xFF000000000000L) | ((v << 56) & 0xFF00000000000000L);}
|
|
||||||
inline void letobe_s(ushort * v) {*v = letobe_s(*v);}
|
|
||||||
inline void letobe_i(uint * v) {*v = letobe_i(*v);}
|
|
||||||
//inline void letobe_ll(ullong * v) {*v = letobe_ll(*v);}
|
|
||||||
inline bool atob(const string & str) {return str == "1" ? true : false;}
|
inline bool atob(const string & str) {return str == "1" ? true : false;}
|
||||||
inline string btos(const bool num) {return num ? "0" : "1";}
|
inline string btos(const bool num) {return num ? "0" : "1";}
|
||||||
inline string itos(const int num) {
|
inline string itos(const int num) {
|
||||||
@@ -755,7 +810,7 @@ public:
|
|||||||
PICout operator <<(const string & v) {space(); quote(); std::cout << v; quote(); return *this;}
|
PICout operator <<(const string & v) {space(); quote(); std::cout << v; quote(); return *this;}
|
||||||
|
|
||||||
//! Output operator for boolean values
|
//! Output operator for boolean values
|
||||||
PICout operator <<(const bool v) {space(); std::cout << v; return *this;}
|
PICout operator <<(const bool v) {space(); std::cout << (v ? "true" : "false"); return *this;}
|
||||||
|
|
||||||
//! Output operator for <tt>"char"</tt> values
|
//! Output operator for <tt>"char"</tt> values
|
||||||
PICout operator <<(const char v) {space(); std::cout << v; return *this;}
|
PICout operator <<(const char v) {space(); std::cout << v; return *this;}
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ PIIODevice::PIIODevice(): PIThread() {
|
|||||||
buffer_tr.resize(4096);
|
buffer_tr.resize(4096);
|
||||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||||
CONNECT(void, &write_thread, started, this, write_func);
|
CONNECT(void, &write_thread, started, this, write_func);
|
||||||
|
created();
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +112,7 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode type, bool
|
|||||||
buffer_tr.resize(4096);
|
buffer_tr.resize(4096);
|
||||||
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
CONNECT2(void, void * , int, &timer, timeout, this, check_start);
|
||||||
CONNECT(void, &write_thread, started, this, write_func);
|
CONNECT(void, &write_thread, started, this, write_func);
|
||||||
|
created();
|
||||||
if (initNow) init();
|
if (initNow) init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#ifndef PIIODEVICE_H
|
#ifndef PIIODEVICE_H
|
||||||
#define PIIODEVICE_H
|
#define PIIODEVICE_H
|
||||||
|
|
||||||
|
#include "pivariant.h"
|
||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
|
|
||||||
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
// function executed from threaded read, pass ThreadedReadData, readedData, sizeOfData
|
||||||
@@ -248,6 +249,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
//! Function executed from the end of constructor
|
||||||
|
virtual void created() {;}
|
||||||
|
|
||||||
//! Function executed before first \a openDevice() or from constructor
|
//! Function executed before first \a openDevice() or from constructor
|
||||||
virtual bool init() {return true;}
|
virtual bool init() {return true;}
|
||||||
|
|
||||||
|
|||||||
382
pimap.h
Normal file
382
pimap.h
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
/*! \file pimap.h
|
||||||
|
* \brief Associative array with custom types of key and value
|
||||||
|
*
|
||||||
|
* This file declares PIMap
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Dynamic array of any type
|
||||||
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIMAP_H
|
||||||
|
#define PIMAP_H
|
||||||
|
|
||||||
|
#include "pivector.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 // !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void piQuickSort(T * a, ssize_t N) {
|
||||||
|
if (N < 1) return;
|
||||||
|
ssize_t i = 0, j = N;
|
||||||
|
T & p(a[N >> 1]);
|
||||||
|
do {
|
||||||
|
while (a[i] < p) i++;
|
||||||
|
while (a[j] > p) j--;
|
||||||
|
if (i <= j) {
|
||||||
|
if (i != j) {
|
||||||
|
//piCout << "swap" << i << j << a[i] << a[j];
|
||||||
|
piSwapBinary<T>(a[i], a[j]);
|
||||||
|
}
|
||||||
|
i++; j--;
|
||||||
|
}
|
||||||
|
} while (i <= j);
|
||||||
|
if (j > 0) piQuickSort(a, j);
|
||||||
|
if (N > i) piQuickSort(a + i, N - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Key, typename T>
|
||||||
|
class PIMap {
|
||||||
|
public:
|
||||||
|
PIMap() {;}
|
||||||
|
PIMap(const PIMap<Key, T> & other) {;}
|
||||||
|
~PIMap() {;}
|
||||||
|
|
||||||
|
PIMap<Key, T> & operator =(const PIMap<Key, T> & other) {
|
||||||
|
if (this == &other) return *this;
|
||||||
|
clear();
|
||||||
|
pim_content = other.pim_content;
|
||||||
|
pim_index = other.pim_index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef T mapped_type;
|
||||||
|
typedef Key key_type;
|
||||||
|
typedef PIPair<Key, T> value_type;
|
||||||
|
|
||||||
|
class const_iterator {
|
||||||
|
friend class PIMap<Key, T>;
|
||||||
|
private:
|
||||||
|
const_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||||
|
const PIMap<Key, T> * parent;
|
||||||
|
ssize_t pos;
|
||||||
|
public:
|
||||||
|
const_iterator(): parent(0) {}
|
||||||
|
const PIMap<Key, T>::value_type operator *() const {return parent->_pair(pos);}
|
||||||
|
void operator ++() {++pos;}
|
||||||
|
void operator ++(int) {++pos;}
|
||||||
|
void operator --() {--pos;}
|
||||||
|
void operator --(int) {--pos;}
|
||||||
|
bool operator ==(const const_iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const const_iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
|
class const_reverse_iterator {
|
||||||
|
friend class PIMap<Key, T>;
|
||||||
|
private:
|
||||||
|
const_reverse_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||||
|
const PIMap<Key, T> * parent;
|
||||||
|
ssize_t pos;
|
||||||
|
public:
|
||||||
|
const_reverse_iterator(): parent(0) {}
|
||||||
|
const PIMap<Key, T>::value_type operator *() const {return parent->_pair(pos);}
|
||||||
|
void operator ++() {--pos;}
|
||||||
|
void operator ++(int) {--pos;}
|
||||||
|
void operator --() {++pos;}
|
||||||
|
void operator --(int) {++pos;}
|
||||||
|
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
|
||||||
|
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
|
||||||
|
};
|
||||||
|
|
||||||
|
// iterator begin() {return iterator(this, 0);}
|
||||||
|
// iterator end() {return iterator(this, size());}
|
||||||
|
const_iterator begin() const {return const_iterator(this, 0);}
|
||||||
|
const_iterator end() const {return const_iterator(this, size());}
|
||||||
|
// reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);}
|
||||||
|
// reverse_iterator rend() {return reverse_iterator(this, -1);}
|
||||||
|
const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);}
|
||||||
|
const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
||||||
|
|
||||||
|
size_t size() const {return pim_content.size();}
|
||||||
|
int size_s() const {return pim_content.size_s();}
|
||||||
|
size_t length() const {return pim_content.size();}
|
||||||
|
bool isEmpty() const {return (pim_content.size() == 0);}
|
||||||
|
|
||||||
|
T & operator [](const Key & key) {
|
||||||
|
bool f(false);
|
||||||
|
ssize_t i = _find(key, f);
|
||||||
|
if (f) return pim_content[pim_index[i].index];
|
||||||
|
pim_content.push_back(T());
|
||||||
|
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
|
||||||
|
return pim_content.back();
|
||||||
|
}
|
||||||
|
const T operator [](const Key & key) const {bool f(false); ssize_t i = _find(key, f); if (f) return pim_content[pim_index[i].index]; return T();}
|
||||||
|
|
||||||
|
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content && pim_index == t.pim_index);}
|
||||||
|
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content || pim_index != t.pim_index);}
|
||||||
|
bool contains(const Key & key) const {bool f(false); _find(key, f); return f;}
|
||||||
|
//int etries(const T & v) const {int ec = 0; for (size_t i = 0; i < pim_size; ++i) if (v == pim_data[i]) ++ec; return ec;}
|
||||||
|
|
||||||
|
PIMap<Key, T> & reserve(size_t new_size) {pim_content.reserve(new_size); pim_index.reserve(new_size); return *this;}
|
||||||
|
|
||||||
|
//PIMap<Key, T> & removeAll(const T & v) {for (llong i = 0; i < pim_size; ++i) if (pim_data[i] == v) {remove(i); --i;} return *this;}
|
||||||
|
PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;}
|
||||||
|
PIMap<Key, T> & clear() {pim_content.clear(); pim_index.clear(); return *this;}
|
||||||
|
|
||||||
|
void swap(PIMap<Key, T> & other) {
|
||||||
|
piSwapBinary<PIVector<T> >(pim_content, other.pim_content);
|
||||||
|
piSwapBinary<PIVector<MapIndex> >(pim_index, other.pim_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
PIMap<Key, T> & insert(const Key & key, const T & value) {
|
||||||
|
//MapIndex * i = _find(key);
|
||||||
|
bool f(false);
|
||||||
|
ssize_t i = _find(key, f);
|
||||||
|
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
|
||||||
|
if (f) {
|
||||||
|
pim_content[pim_index[i].index] = value;
|
||||||
|
} else {
|
||||||
|
pim_content.push_back(value);
|
||||||
|
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
|
||||||
|
//_sort();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//const T value(const Key & key, const T & default_ = T()) const {MapIndex * i = _find(key); if (i == 0) return default_; return pim_content[i->index];}
|
||||||
|
const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];}
|
||||||
|
|
||||||
|
void dump() {
|
||||||
|
piCout << "PIMap" << size() << "entries" << NewLine << "content:";
|
||||||
|
for (size_t i = 0; i < pim_content.size(); ++i)
|
||||||
|
piCout << Tab << i << ":" << pim_content[i];
|
||||||
|
piCout << "index:";
|
||||||
|
for (size_t i = 0; i < pim_index.size(); ++i)
|
||||||
|
piCout << Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct MapIndex {
|
||||||
|
MapIndex(Key k = Key(), size_t i = 0): key(k), index(i) {;}
|
||||||
|
Key key;
|
||||||
|
size_t index;
|
||||||
|
//bool operator <(const MapIndex & s) const {return key < s.key;}
|
||||||
|
//bool operator >(const MapIndex & s) const {return key > s.key;}
|
||||||
|
};
|
||||||
|
|
||||||
|
ssize_t binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
|
||||||
|
ssize_t mid;
|
||||||
|
while (first <= last) {
|
||||||
|
mid = (first + last) / 2;
|
||||||
|
if (key > pim_index[mid].key) first = mid + 1;
|
||||||
|
else if (key < pim_index[mid].key) last = mid - 1;
|
||||||
|
else {
|
||||||
|
found = true;
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = false;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
void _sort() {piQuickSort<MapIndex>(pim_index.data(), pim_index.size_s() - 1);}
|
||||||
|
ssize_t _find(const Key & k, bool & found) const {
|
||||||
|
/*for (size_t i = 0; i < pim_index.size(); ++i)
|
||||||
|
if (pim_index[i].key == k) {
|
||||||
|
return (MapIndex * )&(pim_index[i]);
|
||||||
|
}
|
||||||
|
return 0;*/
|
||||||
|
//piCout << "find for" << k << pim_index.size_s();
|
||||||
|
if (pim_index.isEmpty()) {
|
||||||
|
found = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//piCout << k << ret << found;
|
||||||
|
return binarySearch(0, pim_index.size_s() - 1, k, found);
|
||||||
|
}
|
||||||
|
void _remove(ssize_t i) {
|
||||||
|
//if (i >= pim_index.size()) return;
|
||||||
|
size_t ci = pim_index[i].index, bi = pim_index.size() - 1;
|
||||||
|
pim_index.remove(i);
|
||||||
|
for (size_t i = 0; i < pim_index.size(); ++i)
|
||||||
|
if (pim_index[i].index == bi) {
|
||||||
|
pim_index[i].index = ci;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
piSwapBinary<T>(pim_content[ci], pim_content.back());
|
||||||
|
pim_content.resize(pim_index.size());
|
||||||
|
}
|
||||||
|
const value_type _pair(ssize_t index) const {
|
||||||
|
if (index < 0 || index >= pim_index.size())
|
||||||
|
return value_type();
|
||||||
|
//piCout << "_pair" << index << pim_index[index].index;
|
||||||
|
return value_type(pim_index[index].key, pim_content[pim_index[index].index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PIVector<T> pim_content;
|
||||||
|
PIVector<MapIndex> pim_index;
|
||||||
|
};
|
||||||
|
//template <typename Key, typename T> bool operator <(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key < s.key;}
|
||||||
|
//template <typename Key, typename T> bool operator >(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key > s.key;}
|
||||||
|
|
||||||
|
|
||||||
|
#define __PIMAP_SIMPLE_FUNCTIONS__(T)
|
||||||
|
/* template<> inline PIMap<Key, T>::~PIMap() {dealloc(); _reset();} \
|
||||||
|
template<> inline PIMap<Key, T> & PIMap<Key, T>::push_back(const T & v) {alloc(pim_size + 1); pim_data[pim_size - 1] = v; return *this;} \
|
||||||
|
template<> inline PIMap<Key, T> & PIMap<Key, T>::fill(const T & f) { \
|
||||||
|
for (size_t i = 0; i < pim_size; ++i) \
|
||||||
|
pim_data[i] = f; \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
template<> inline PIMap<Key, T> & PIMap<Key, T>::resize(size_t new_size, const T & f) { \
|
||||||
|
if (new_size < pim_size) \
|
||||||
|
pim_size = new_size; \
|
||||||
|
if (new_size > pim_size) { \
|
||||||
|
size_t os = pim_size; \
|
||||||
|
alloc(new_size); \
|
||||||
|
for (size_t i = os; i < new_size; ++i) pim_data[i] = f; \
|
||||||
|
} \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
template<> inline PIMap<Key, T> & PIMap<Key, T>::insert(size_t index, const T & v) { \
|
||||||
|
alloc(pim_size + 1); \
|
||||||
|
if (index < pim_size - 1) { \
|
||||||
|
size_t os = pim_size - index - 1; \
|
||||||
|
memmove(&(pim_data[index + 1]), &(pim_data[index]), os * sizeof(T)); \
|
||||||
|
} \
|
||||||
|
pim_data[index] = v; \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
template<> inline PIMap<Key, T> & PIMap<Key, T>::remove(size_t index, size_t count) { \
|
||||||
|
if (index + count >= pim_size) { \
|
||||||
|
resize(index); \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
size_t os = pim_size - index - count; \
|
||||||
|
memmove(&(pim_data[index]), &(pim_data[index + count]), os * sizeof(T)); \
|
||||||
|
pim_size -= count; \
|
||||||
|
return *this; \
|
||||||
|
}*/
|
||||||
|
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(char)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(uchar)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(short)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(ushort)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(int)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(uint)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(long)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(ulong)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(llong)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(ullong)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(float)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(double)
|
||||||
|
__PIMAP_SIMPLE_FUNCTIONS__(ldouble)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Key, typename Type>
|
||||||
|
class PIP_EXPORT PIMap: public map<Key, Type> {
|
||||||
|
typedef PIMap<Key, Type> _CMap;
|
||||||
|
typedef map<Key, Type> _stlc;
|
||||||
|
typedef std::pair<Key, Type> _stlpair;
|
||||||
|
public:
|
||||||
|
PIMap() {;}
|
||||||
|
PIMap(const Key & key_, const Type & value_) {insert(key_, value_);}
|
||||||
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
|
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
||||||
|
int size_s() const {return static_cast<int>(_stlc::size());}
|
||||||
|
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
||||||
|
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||||
|
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
||||||
|
Type & value(const Key & key_) {typename _stlc::iterator it = _stlc::find(key_); if (it == _stlc::end()) it->second = Type(); return it->second;}
|
||||||
|
Type & at(const Key & key_) {return value(key_);}
|
||||||
|
Type value(const Key & key_) const {return _stlc::find(key_)->second;}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Key, typename Type>
|
||||||
|
class PIP_EXPORT PIMultiMap: public multimap<Key, Type> {
|
||||||
|
typedef PIMultiMap<Key, Type> _CMultiMap;
|
||||||
|
typedef multimap<Key, Type> _stlc;
|
||||||
|
typedef std::pair<Key, Type> _stlpair;
|
||||||
|
public:
|
||||||
|
PIMultiMap() {;}
|
||||||
|
PIMultiMap(const Key & key_, const Type & value_) {insert(key_, value_);}
|
||||||
|
_CMultiMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
|
||||||
|
_CMultiMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
|
||||||
|
bool isEmpty() const {return _stlc::empty();}
|
||||||
|
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
|
||||||
|
Key key(Type value_) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return Key();}
|
||||||
|
PIVector<Key> keys(Type value_) const {
|
||||||
|
PIVector<Key> ret;
|
||||||
|
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
|
||||||
|
if (i->second == value_)
|
||||||
|
ret << i->first;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Type & value(const Key & key_) {typename _stlc::iterator i = _stlc::find(key_); if (i == _stlc::end()) return Type(); return i->second;}
|
||||||
|
Type value(const Key & key_) const {typename _stlc::const_iterator i = _stlc::find(key_); if (i == _stlc::end()) return Type(); return i->second;}
|
||||||
|
PIVector<Type> values(const Key & key_) const {
|
||||||
|
std::pair<typename _stlc::const_iterator, typename _stlc::const_iterator> range = _stlc::equal_range(key_);
|
||||||
|
PIVector<Type> ret;
|
||||||
|
for (typename _stlc::const_iterator i = range.first; i != range.second; ++i)
|
||||||
|
ret << i->second;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Type & operator [](const Key & key_) {if (!contains(key_)) return _stlc::insert(_stlpair(key_, Type()))->second; return _stlc::find(key_)->second;}
|
||||||
|
Type operator [](const Key & key_) const {return _stlc::find(key_)->second;}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define __PIMAP_SIMPLE_FUNCTIONS__(T)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Key, typename Type>
|
||||||
|
inline std::ostream & operator <<(std::ostream & s, const PIMap<Key, Type> & v) {
|
||||||
|
s << "{";
|
||||||
|
bool first = true;
|
||||||
|
for (typename PIMap<Key, Type>::const_iterator i = v.begin(); i != v.end(); i++) {
|
||||||
|
if (!first)
|
||||||
|
s << ", ";
|
||||||
|
first = false;
|
||||||
|
s << i->first << ": " << i->second;
|
||||||
|
}
|
||||||
|
s << "}";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Key, typename Type>
|
||||||
|
inline PICout operator <<(PICout s, const PIMap<Key, Type> & v) {
|
||||||
|
s.space();
|
||||||
|
s.setControl(0, true);
|
||||||
|
s << "{";
|
||||||
|
bool first = true;
|
||||||
|
for (typename PIMap<Key, Type>::const_iterator i = v.begin(); i != v.end(); i++) {
|
||||||
|
if (!first)
|
||||||
|
s << ", ";
|
||||||
|
first = false;
|
||||||
|
s << i->first << ": " << i->second;
|
||||||
|
}
|
||||||
|
s << "}";
|
||||||
|
s.restoreControl();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PIMAP_H
|
||||||
23
pimath.h
23
pimath.h
@@ -94,6 +94,11 @@ const complexd complexd_i(0., 1.);
|
|||||||
const complexd complexd_0(0.);
|
const complexd complexd_0(0.);
|
||||||
const complexd complexd_1(1.);
|
const complexd complexd_1(1.);
|
||||||
|
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(complexi)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(complexf)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(complexd)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(complexld)
|
||||||
|
|
||||||
const double deg2rad = M_PI_180;
|
const double deg2rad = M_PI_180;
|
||||||
const double rad2deg = M_180_PI;
|
const double rad2deg = M_180_PI;
|
||||||
|
|
||||||
@@ -194,7 +199,7 @@ public:
|
|||||||
Type at(uint index) const {return c[index];}
|
Type at(uint index) const {return c[index];}
|
||||||
Type & operator [](uint index) {return c[index];}
|
Type & operator [](uint index) {return c[index];}
|
||||||
Type operator [](uint index) const {return c[index];}
|
Type operator [](uint index) const {return c[index];}
|
||||||
_CVector & operator =(const _CVector & v) {c = v.c; return *this;}
|
_CVector & operator =(const _CVector & v) {memcpy(&c, &(v.c), sizeof(Type) * Size); return *this;}
|
||||||
bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;}
|
bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;}
|
||||||
bool operator !=(const _CVector & v) const {return !(*this == c);}
|
bool operator !=(const _CVector & v) const {return !(*this == c);}
|
||||||
void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];}
|
void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];}
|
||||||
@@ -222,8 +227,10 @@ public:
|
|||||||
PIMathVectorT<Size1, Type1> turnTo() {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;}
|
PIMathVectorT<Size1, Type1> turnTo() {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resize(uint size, const Type & new_value = Type()) {c.resize(size, new_value);}
|
void resize(uint size, const Type & new_value = Type()) {s = size; for (int i = 0; i < s; ++i) c[i] = new_value;}
|
||||||
PIVector<Type> c;
|
|
||||||
|
int s;
|
||||||
|
Type c[Size];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -291,9 +298,8 @@ public:
|
|||||||
|
|
||||||
Type & at(uint col, uint row) {return m[col][row];}
|
Type & at(uint col, uint row) {return m[col][row];}
|
||||||
Type at(uint col, uint row) const {return m[col][row];}
|
Type at(uint col, uint row) const {return m[col][row];}
|
||||||
PIVector<Type> & operator [](uint col) {return m[col];}
|
Type * operator [](uint col) {return m[col];}
|
||||||
PIVector<Type> operator [](uint col) const {return m[col];}
|
void operator =(const _CMatrix & sm) {memcpy(&m, &(sm.m), sizeof(Type) * Cols * Rows);}
|
||||||
void operator =(const _CMatrix & sm) {m = sm.m;}
|
|
||||||
bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;}
|
bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;}
|
||||||
bool operator !=(const _CMatrix & sm) const {return !(*this == sm);}
|
bool operator !=(const _CMatrix & sm) const {return !(*this == sm);}
|
||||||
void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];}
|
void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];}
|
||||||
@@ -408,8 +414,9 @@ public:
|
|||||||
_CMatrixI transposed() {_CMatrixI tm; PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;}
|
_CMatrixI transposed() {_CMatrixI tm; PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resize(uint cols, uint rows, const Type & new_value = Type()) {m.resize(cols); PIMM_FOR_C(i) m[i].resize(rows, new_value);}
|
void resize(uint cols_, uint rows_, const Type & new_value = Type()) {c_ = cols_; r_ = rows_; PIMM_FOR_WB(c, r) m[c][r] = new_value;}
|
||||||
PIVector<PIVector<Type> > m;
|
int c_, r_;
|
||||||
|
Type m[Cols][Rows];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
67
piobject.h
67
piobject.h
@@ -25,7 +25,7 @@
|
|||||||
#ifndef PIOBJECT_H
|
#ifndef PIOBJECT_H
|
||||||
#define PIOBJECT_H
|
#define PIOBJECT_H
|
||||||
|
|
||||||
#include "pistring.h"
|
#include "pivariant.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
@@ -35,38 +35,38 @@
|
|||||||
#define PIOBJECT(name)
|
#define PIOBJECT(name)
|
||||||
|
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name()
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\" and return type \"ret\", ret name()
|
||||||
#define EVENT_HANDLER0(ret, name) ret name()
|
#define EVENT_HANDLER0(ret, name) ret name()
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0)
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\" and return type \"ret\", ret name(type0 var0)
|
||||||
#define EVENT_HANDLER1(ret, name, type0, var0) ret name(type0 var0)
|
#define EVENT_HANDLER1(ret, name, type0, var0) ret name(type0 var0)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0, type1 var1)
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\" and return type \"ret\", ret name(type0 var0, type1 var1)
|
||||||
#define EVENT_HANDLER2(ret, name, type0, var0, type1, var1) ret name(type0 var0, type1 var1)
|
#define EVENT_HANDLER2(ret, name, type0, var0, type1, var1) ret name(type0 var0, type1 var1)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0, type1 var1, type2 var2)
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\" and return type \"ret\", ret name(type0 var0, type1 var1, type2 var2)
|
||||||
#define EVENT_HANDLER3(ret, name, type0, var0, type1, var1, type2, var2) ret name(type0 var0, type1 var1, type2 var2)
|
#define EVENT_HANDLER3(ret, name, type0, var0, type1, var1, type2, var2) ret name(type0 var0, type1 var1, type2 var2)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\", ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
/// \relatesalso PIObject \brief declare event handler \"event\" with name \"name\" and return type \"ret\", ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
#define EVENT_HANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
#define EVENT_HANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief EVENT_HANDLER is synonym of EVENT_HANDLER0
|
/// \relatesalso PIObject \brief EVENT_HANDLER is synonym of EVENT_HANDLER0
|
||||||
#define EVENT_HANDLER EVENT_HANDLER0
|
#define EVENT_HANDLER EVENT_HANDLER0
|
||||||
|
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name()
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\" and return type \"ret\", virtual ret name()
|
||||||
#define EVENT_VHANDLER0(ret, name) virtual ret name()
|
#define EVENT_VHANDLER0(ret, name) virtual ret name()
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0)
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\" and return type \"ret\", virtual ret name(type0 var0)
|
||||||
#define EVENT_VHANDLER1(ret, name, type0, var0) virtual ret name(type0 var0)
|
#define EVENT_VHANDLER1(ret, name, type0, var0) virtual ret name(type0 var0)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0, type1 var1)
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\" and return type \"ret\", virtual ret name(type0 var0, type1 var1)
|
||||||
#define EVENT_VHANDLER2(ret, name, type0, var0, type1, var1) virtual ret name(type0 var0, type1 var1)
|
#define EVENT_VHANDLER2(ret, name, type0, var0, type1, var1) virtual ret name(type0 var0, type1 var1)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0, type1 var1, type2 var2)
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\" and return type \"ret\", virtual ret name(type0 var0, type1 var1, type2 var2)
|
||||||
#define EVENT_VHANDLER3(ret, name, type0, var0, type1, var1, type2, var2) virtual ret name(type0 var0, type1 var1, type2 var2)
|
#define EVENT_VHANDLER3(ret, name, type0, var0, type1, var1, type2, var2) virtual ret name(type0 var0, type1 var1, type2 var2)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\", virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
/// \relatesalso PIObject \brief declare virtual event handler \"event\" with name \"name\" and return type \"ret\", virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
#define EVENT_VHANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
#define EVENT_VHANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief EVENT_VHANDLER is synonym of EVENT_VHANDLER0
|
/// \relatesalso PIObject \brief EVENT_VHANDLER is synonym of EVENT_VHANDLER0
|
||||||
@@ -100,57 +100,57 @@
|
|||||||
#define RAISE_EVENT RAISE_EVENT0
|
#define RAISE_EVENT RAISE_EVENT0
|
||||||
|
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
#define CONNECT0(ret, src, event, dest, handler)
|
#define CONNECT0(ret, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
#define CONNECT1(ret, type0, src, event, dest, handler)
|
#define CONNECT1(ret, type0, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
#define CONNECT2(ret, type0, type1, src, event, dest, handler)
|
#define CONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
#define CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
#define CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
#define CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
#define CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief CONNECT is synonym of CONNECT0
|
/// \relatesalso PIObject \brief CONNECT is synonym of CONNECT0
|
||||||
#define CONNECT CONNECT0
|
#define CONNECT CONNECT0
|
||||||
|
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||||
#define WEAK_CONNECT0(ret, src, event, dest, handler)
|
#define WEAK_CONNECT0(ret, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||||
#define WEAK_CONNECT1(ret, type0, src, event, dest, handler)
|
#define WEAK_CONNECT1(ret, type0, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||||
#define WEAK_CONNECT2(ret, type0, type1, src, event, dest, handler)
|
#define WEAK_CONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||||
#define WEAK_CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
#define WEAK_CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" from object \"dest\" without check of event exists
|
/// \relatesalso PIObject \brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" without check of event exists
|
||||||
#define WEAK_CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
#define WEAK_CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief WEAK_CONNECT is synonym of WEAK_CONNECT0
|
/// \relatesalso PIObject \brief WEAK_CONNECT is synonym of WEAK_CONNECT0
|
||||||
#define WEAK_CONNECT WEAK_CONNECT0
|
#define WEAK_CONNECT WEAK_CONNECT0
|
||||||
|
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||||
#define DISCONNECT0(ret, src, event, dest, handler)
|
#define DISCONNECT0(ret, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||||
#define DISCONNECT1(ret, type0, src, event, dest, handler)
|
#define DISCONNECT1(ret, type0, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||||
#define DISCONNECT2(ret, type0, type1, src, event, dest, handler)
|
#define DISCONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||||
#define DISCONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
#define DISCONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" from object \"dest\"
|
/// \relatesalso PIObject \brief piDisconnect event \"event\" from object \"src\" from event handler \"handler\" with return type \"ret\" from object \"dest\"
|
||||||
#define DISCONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
#define DISCONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject \brief DISCONNECT is synonym of DISCONNECT0
|
/// \relatesalso PIObject \brief DISCONNECT is synonym of DISCONNECT0
|
||||||
@@ -248,6 +248,20 @@ public:
|
|||||||
//! Set object debug active
|
//! Set object debug active
|
||||||
void setDebug(bool debug) {debug_ = debug;}
|
void setDebug(bool debug) {debug_ = debug;}
|
||||||
|
|
||||||
|
//! Returns properties of the object
|
||||||
|
const PIMap<PIString, PIVariant> & properties() const {return properties_;}
|
||||||
|
|
||||||
|
//! Returns properties count of the object
|
||||||
|
int propertiesCount() const {return properties_.size_s();}
|
||||||
|
|
||||||
|
//! Returns property with name "name"
|
||||||
|
PIVariant property(const PIString & name) {if (!properties_.contains(name)) return PIVariant(); return properties_.value(name);}
|
||||||
|
|
||||||
|
//! Set property with name "name" to "value". If there is no such property in object it will be added
|
||||||
|
void setProperty(const PIString & name, const PIVariant & value) {properties_[name] = value;}
|
||||||
|
|
||||||
|
//! Returns if property with name "name" exists
|
||||||
|
bool isPropertyExists(const PIString & name) {return properties_.contains(name);}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PIStringList events();
|
PIStringList events();
|
||||||
@@ -476,6 +490,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
PIVector<Connection> connections;
|
PIVector<Connection> connections;
|
||||||
|
PIMap<PIString, PIVariant> properties_;
|
||||||
|
|
||||||
static PIVector<PIObject * > objects;
|
static PIVector<PIObject * > objects;
|
||||||
static PIObject * findByName(const PIString & name) {
|
static PIObject * findByName(const PIString & name) {
|
||||||
|
|||||||
2
pip.h
2
pip.h
@@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
#include "pivariable.h"
|
#include "pivariant.h"
|
||||||
#include "piconsole.h"
|
#include "piconsole.h"
|
||||||
#include "picli.h"
|
#include "picli.h"
|
||||||
#include "pievaluator.h"
|
#include "pievaluator.h"
|
||||||
|
|||||||
2
pip.pro
2
pip.pro
@@ -9,7 +9,7 @@ INCLUDEPATH += .
|
|||||||
QT -= core gui
|
QT -= core gui
|
||||||
CONFIG -= qt
|
CONFIG -= qt
|
||||||
CONFIG += dll
|
CONFIG += dll
|
||||||
VERSION = 0.3.7
|
VERSION = 0.3.8
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,3,7,0
|
FILEVERSION 0,3,8,0
|
||||||
PRODUCTVERSION 0,3,7,0
|
PRODUCTVERSION 0,3,8,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS VS_FF_DEBUG
|
FILEFLAGS VS_FF_DEBUG
|
||||||
@@ -23,7 +23,7 @@ VS_VERSION_INFO VERSIONINFO
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "\0"
|
VALUE "CompanyName", "\0"
|
||||||
VALUE "FileDescription", "\0"
|
VALUE "FileDescription", "\0"
|
||||||
VALUE "FileVersion", "0.3.7.0\0"
|
VALUE "FileVersion", "0.3.8.0\0"
|
||||||
VALUE "LegalCopyright", "\0"
|
VALUE "LegalCopyright", "\0"
|
||||||
VALUE "OriginalFilename", "pip0.dll\0"
|
VALUE "OriginalFilename", "pip0.dll\0"
|
||||||
VALUE "ProductName", "pip\0"
|
VALUE "ProductName", "pip\0"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,3,7,0
|
FILEVERSION 0,3,8,0
|
||||||
PRODUCTVERSION 0,3,7,0
|
PRODUCTVERSION 0,3,8,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
FILEFLAGS 0x0L
|
FILEFLAGS 0x0L
|
||||||
FILEOS VOS__WINDOWS32
|
FILEOS VOS__WINDOWS32
|
||||||
@@ -19,7 +19,7 @@ VS_VERSION_INFO VERSIONINFO
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Peri4\0"
|
VALUE "CompanyName", "Peri4\0"
|
||||||
VALUE "FileDescription", "Platform-Independent Primitives\0"
|
VALUE "FileDescription", "Platform-Independent Primitives\0"
|
||||||
VALUE "FileVersion", "0.3.7.0\0"
|
VALUE "FileVersion", "0.3.8_alpha\0"
|
||||||
VALUE "LegalCopyright", "\0"
|
VALUE "LegalCopyright", "\0"
|
||||||
VALUE "OriginalFilename", "libpip.dll\0"
|
VALUE "OriginalFilename", "libpip.dll\0"
|
||||||
VALUE "ProductName", "PIP\0"
|
VALUE "ProductName", "PIP\0"
|
||||||
|
|||||||
57
piserial.cpp
57
piserial.cpp
@@ -42,6 +42,7 @@ PISerial::PISerial(): PIIODevice("", ReadWrite) {
|
|||||||
ispeed = ospeed = S115200;
|
ispeed = ospeed = S115200;
|
||||||
vtime = 1;
|
vtime = 1;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
block_write = true;
|
||||||
hCom = 0;
|
hCom = 0;
|
||||||
#endif
|
#endif
|
||||||
dbits = 8;
|
dbits = 8;
|
||||||
@@ -59,6 +60,7 @@ PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PIS
|
|||||||
ispeed = ospeed = speed_;
|
ispeed = ospeed = speed_;
|
||||||
vtime = 1;
|
vtime = 1;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
block_write = true;
|
||||||
hCom = 0;
|
hCom = 0;
|
||||||
#endif
|
#endif
|
||||||
dbits = 8;
|
dbits = 8;
|
||||||
@@ -208,10 +210,10 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
|
|||||||
int ret, all = 0;
|
int ret, all = 0;
|
||||||
if (timeout_ms > 0.) {
|
if (timeout_ms > 0.) {
|
||||||
setReadIsBlocking(false);
|
setReadIsBlocking(false);
|
||||||
all = ::read(fd, data, 1);
|
all = read(data, 1);
|
||||||
timer.reset();
|
timer.reset();
|
||||||
while (all < size && timer.elapsed_m() < timeout_ms) {
|
while (all < size && timer.elapsed_m() < timeout_ms) {
|
||||||
ret = ::read(fd, &((uchar * )data)[all], size - all);
|
ret = read(&((uchar * )data)[all], size - all);
|
||||||
if (ret > 0) all += ret;
|
if (ret > 0) all += ret;
|
||||||
else msleep(1);
|
else msleep(1);
|
||||||
}
|
}
|
||||||
@@ -219,9 +221,9 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
|
|||||||
return (all == size);
|
return (all == size);
|
||||||
} else {
|
} else {
|
||||||
setReadIsBlocking(true);
|
setReadIsBlocking(true);
|
||||||
all = ::read(fd, data, 1);
|
all = read(data, 1);
|
||||||
while (all < size) {
|
while (all < size) {
|
||||||
ret = ::read(fd, &((uchar * )data)[all], size - all);
|
ret = read(&((uchar * )data)[all], size - all);
|
||||||
if (ret > 0) all += ret;
|
if (ret > 0) all += ret;
|
||||||
}
|
}
|
||||||
received(data, all);
|
received(data, all);
|
||||||
@@ -249,13 +251,13 @@ PIString PISerial::read(int size, double timeout_ms) {
|
|||||||
timer.reset();
|
timer.reset();
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
while (timer.elapsed_m() < timeout_ms) {
|
while (timer.elapsed_m() < timeout_ms) {
|
||||||
ret = ::read(fd, td, 1024);
|
ret = read(td, 1024);
|
||||||
if (ret <= 0) msleep(1);
|
if (ret <= 0) msleep(1);
|
||||||
else str << PIString((char*)td, ret);
|
else str << PIString((char*)td, ret);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (all < size && timer.elapsed_m() < timeout_ms) {
|
while (all < size && timer.elapsed_m() < timeout_ms) {
|
||||||
ret = ::read(fd, td, size - all);
|
ret = read(td, size - all);
|
||||||
if (ret <= 0) msleep(1);
|
if (ret <= 0) msleep(1);
|
||||||
else {
|
else {
|
||||||
str << PIString((char*)td, ret);
|
str << PIString((char*)td, ret);
|
||||||
@@ -265,10 +267,10 @@ PIString PISerial::read(int size, double timeout_ms) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setReadIsBlocking(true);
|
setReadIsBlocking(true);
|
||||||
all = ::read(fd, td, 1);
|
all = read(td, 1);
|
||||||
str << PIString((char*)td, all);
|
str << PIString((char*)td, all);
|
||||||
while (all < size) {
|
while (all < size) {
|
||||||
ret = ::read(fd, td, size - all);
|
ret = read(td, size - all);
|
||||||
if (ret <= 0) msleep(1);
|
if (ret <= 0) msleep(1);
|
||||||
else {
|
else {
|
||||||
str << PIString((char*)td, ret);
|
str << PIString((char*)td, ret);
|
||||||
@@ -299,13 +301,13 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
|||||||
timer.reset();
|
timer.reset();
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
while (timer.elapsed_m() < timeout_ms) {
|
while (timer.elapsed_m() < timeout_ms) {
|
||||||
ret = ::read(fd, td, 1024);
|
ret = read(td, 1024);
|
||||||
if (ret <= 0) msleep(1);
|
if (ret <= 0) msleep(1);
|
||||||
else str.append(td, ret);
|
else str.append(td, ret);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (all < size && timer.elapsed_m() < timeout_ms) {
|
while (all < size && timer.elapsed_m() < timeout_ms) {
|
||||||
ret = ::read(fd, td, size - all);
|
ret = read(td, size - all);
|
||||||
if (ret <= 0) msleep(1);
|
if (ret <= 0) msleep(1);
|
||||||
else {
|
else {
|
||||||
str.append(td, ret);
|
str.append(td, ret);
|
||||||
@@ -315,10 +317,10 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setReadIsBlocking(true);
|
setReadIsBlocking(true);
|
||||||
all = ::read(fd, td, 1);
|
all = read(td, 1);
|
||||||
str.append(td, all);
|
str.append(td, all);
|
||||||
while (all < size) {
|
while (all < size) {
|
||||||
ret = ::read(fd, td, size - all);
|
ret = read(td, size - all);
|
||||||
if (ret <= 0) msleep(1);
|
if (ret <= 0) msleep(1);
|
||||||
else {
|
else {
|
||||||
str.append(td, ret);
|
str.append(td, ret);
|
||||||
@@ -336,7 +338,8 @@ bool PISerial::openDevice() {
|
|||||||
DWORD ds = 0, sm = 0;
|
DWORD ds = 0, sm = 0;
|
||||||
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
|
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
|
||||||
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
||||||
hCom = CreateFileA(path_.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
PIString wp = "//./" + path_;
|
||||||
|
hCom = CreateFileA(wp.data(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
|
||||||
if (hCom == INVALID_HANDLE_VALUE) {
|
if (hCom == INVALID_HANDLE_VALUE) {
|
||||||
piCoutObj << "Unable to open \"" << path_ << "\"";
|
piCoutObj << "Unable to open \"" << path_ << "\"";
|
||||||
fd = -1;
|
fd = -1;
|
||||||
@@ -370,10 +373,10 @@ void PISerial::applySettings() {
|
|||||||
if (fd == -1) return;
|
if (fd == -1) return;
|
||||||
COMMTIMEOUTS times;
|
COMMTIMEOUTS times;
|
||||||
times.ReadIntervalTimeout = block_read ? vtime : MAXDWORD;
|
times.ReadIntervalTimeout = block_read ? vtime : MAXDWORD;
|
||||||
times.ReadTotalTimeoutConstant = block_read ? 1 : 0;
|
times.ReadTotalTimeoutConstant = block_read ? 0 : 1;
|
||||||
times.ReadTotalTimeoutMultiplier = 0;
|
times.ReadTotalTimeoutMultiplier = block_read ? 0 : MAXDWORD;
|
||||||
times.WriteTotalTimeoutConstant = 1;
|
times.WriteTotalTimeoutConstant = 0;
|
||||||
times.WriteTotalTimeoutMultiplier = 0;
|
times.WriteTotalTimeoutMultiplier = block_write ? 0 : 1;
|
||||||
if (SetCommTimeouts(hCom, ×) == -1)
|
if (SetCommTimeouts(hCom, ×) == -1)
|
||||||
piCoutObj << "Unable to set timeouts for \"" << path_ << "\"";
|
piCoutObj << "Unable to set timeouts for \"" << path_ << "\"";
|
||||||
GetCommMask(hCom, &mask);
|
GetCommMask(hCom, &mask);
|
||||||
@@ -435,11 +438,11 @@ void PISerial::setReadIsBlocking(bool yes) {
|
|||||||
block_read = yes;
|
block_read = yes;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
COMMTIMEOUTS times;
|
COMMTIMEOUTS times;
|
||||||
times.ReadIntervalTimeout = yes ? vtime : MAXDWORD;
|
times.ReadIntervalTimeout = block_read ? vtime : MAXDWORD;
|
||||||
times.ReadTotalTimeoutConstant = yes ? 1 : 0;
|
times.ReadTotalTimeoutConstant = block_read ? 0 : 1;
|
||||||
times.ReadTotalTimeoutMultiplier = 0;
|
times.ReadTotalTimeoutMultiplier = block_read ? 0 : MAXDWORD;
|
||||||
times.WriteTotalTimeoutConstant = 1;
|
times.WriteTotalTimeoutConstant = 0;
|
||||||
times.WriteTotalTimeoutMultiplier = 0;
|
times.WriteTotalTimeoutMultiplier = block_write ? 0 : 1;
|
||||||
if (isOpened()) SetCommTimeouts(hCom, ×);
|
if (isOpened()) SetCommTimeouts(hCom, ×);
|
||||||
#else
|
#else
|
||||||
if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK);
|
if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK);
|
||||||
@@ -472,14 +475,12 @@ int PISerial::write(const void * data, int max_size, bool wait) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
if (block_write != wait) {
|
||||||
|
block_write = wait;
|
||||||
|
setReadIsBlocking(block_read);
|
||||||
|
}
|
||||||
DWORD wrote;
|
DWORD wrote;
|
||||||
WriteFile(hCom, data, max_size, &wrote, 0);
|
WriteFile(hCom, data, max_size, &wrote, 0);
|
||||||
if (wait) {
|
|
||||||
DWORD event;
|
|
||||||
SetCommMask(hCom, EV_TXEMPTY);
|
|
||||||
WaitCommEvent(hCom, &event, NULL);
|
|
||||||
SetCommMask(hCom, EV_RXCHAR);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
int wrote;
|
int wrote;
|
||||||
wrote = ::write(fd, data, max_size);
|
wrote = ::write(fd, data, max_size);
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool configureDevice(const void * e_main, const void * e_parent = 0);
|
bool configureDevice(const void * e_main, const void * e_parent = 0);
|
||||||
|
int write(const void * data, int max_size) {return write(data, max_size, true);}
|
||||||
|
|
||||||
//! Executes when any read function was successful. Default implementation does nothing
|
//! Executes when any read function was successful. Default implementation does nothing
|
||||||
virtual void received(const void * data, int size) {;}
|
virtual void received(const void * data, int size) {;}
|
||||||
@@ -289,6 +290,7 @@ protected:
|
|||||||
DCB desc, sdesc;
|
DCB desc, sdesc;
|
||||||
void * hCom;
|
void * hCom;
|
||||||
DWORD readed, mask;
|
DWORD readed, mask;
|
||||||
|
bool block_write;
|
||||||
#else
|
#else
|
||||||
termios desc, sdesc;
|
termios desc, sdesc;
|
||||||
uint readed;
|
uint readed;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class PIP_EXPORT PIStateMachine: public PIObject
|
|||||||
PIOBJECT(PIStateMachine)
|
PIOBJECT(PIStateMachine)
|
||||||
public:
|
public:
|
||||||
//! Constructs an empty state machine
|
//! Constructs an empty state machine
|
||||||
PIStateMachine() {resetConditions();}
|
PIStateMachine(void * _parent = 0) {if (_parent == 0) parent_ = this; else parent_ = _parent; resetConditions();}
|
||||||
~PIStateMachine() {;}
|
~PIStateMachine() {;}
|
||||||
|
|
||||||
//! %Condition is a pair (string, number)
|
//! %Condition is a pair (string, number)
|
||||||
@@ -87,13 +87,14 @@ public:
|
|||||||
//! %Rule of transition between states of machine
|
//! %Rule of transition between states of machine
|
||||||
struct Rule {
|
struct Rule {
|
||||||
//! Constuctor
|
//! Constuctor
|
||||||
Rule() {;}
|
Rule() {handler = 0;}
|
||||||
//! Constuctor
|
//! Constuctor
|
||||||
Rule(Type f, Type t, const PIStringList & c = PIStringList(), Handler h = 0, bool rac = false) {
|
Rule(Type f, Type t, const PIStringList & c = PIStringList(), Handler h = 0, bool at = false, bool rac = false) {
|
||||||
from = f;
|
from = f;
|
||||||
to = t;
|
to = t;
|
||||||
for (int i = 0; i < c.size_s(); ++i)
|
for (int i = 0; i < c.size_s(); ++i)
|
||||||
conditions << Condition(c[i], 1);
|
conditions << Condition(c[i], 1);
|
||||||
|
autoTransition = at;
|
||||||
resetAllConditions = rac;
|
resetAllConditions = rac;
|
||||||
handler = h;
|
handler = h;
|
||||||
}
|
}
|
||||||
@@ -103,6 +104,8 @@ public:
|
|||||||
Type to;
|
Type to;
|
||||||
//! %Conditions of transition
|
//! %Conditions of transition
|
||||||
PIVector<Condition> conditions;
|
PIVector<Condition> conditions;
|
||||||
|
//! Automatic transition
|
||||||
|
bool autoTransition;
|
||||||
//! Reset or not all performed conditions of machine on transition
|
//! Reset or not all performed conditions of machine on transition
|
||||||
bool resetAllConditions;
|
bool resetAllConditions;
|
||||||
//! Pointer to function executed on transition
|
//! Pointer to function executed on transition
|
||||||
@@ -116,7 +119,7 @@ public:
|
|||||||
//! %State of machine
|
//! %State of machine
|
||||||
struct State {
|
struct State {
|
||||||
//! Constuctor
|
//! Constuctor
|
||||||
State() {;}
|
State() {handler = 0;}
|
||||||
//! Constuctor
|
//! Constuctor
|
||||||
State(Type v, const PIString & n = "", Handler h = 0) {value = v; name = n; handler = h;}
|
State(Type v, const PIString & n = "", Handler h = 0) {value = v; name = n; handler = h;}
|
||||||
//! %State value
|
//! %State value
|
||||||
@@ -129,9 +132,11 @@ public:
|
|||||||
bool operator !=(const State & other) const {return value != other.value;}
|
bool operator !=(const State & other) const {return value != other.value;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void * parent() const {return parent_;}
|
||||||
|
void setParent(void * parent) {parent_ = parent;}
|
||||||
|
|
||||||
//! Add state of machine
|
//! Add state of machine
|
||||||
void addState(Type value, const PIString & name = "", Handler handler = 0) {if (states_.contain(State(value, name))) return; states_ << State(value, name, handler);}
|
void addState(Type value, const PIString & name = "", Handler handler = 0) {if (states_.contains(State(value, name))) return; states_ << State(value, name, handler);}
|
||||||
|
|
||||||
//! States count
|
//! States count
|
||||||
int statesCount() const {return states_.size_s();}
|
int statesCount() const {return states_.size_s();}
|
||||||
@@ -141,16 +146,16 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Add rule of transition
|
//! Add rule of transition
|
||||||
void addRule(Type from, Type to, const PIString & condition, Handler handler = 0, bool resetAllConditions = false) {if (rules_.contain(Rule(from, to))) return; rules_ << Rule(from, to, PIStringList(condition), handler, resetAllConditions);}
|
void addRule(Type from, Type to, const PIString & condition, Handler handler = 0, bool autoTransition = false, bool resetAllConditions = false) {if (rules_.contains(Rule(from, to))) return; rules_ << Rule(from, to, PIStringList(condition), handler, autoTransition, resetAllConditions);}
|
||||||
|
|
||||||
//! Add rule of transition
|
//! Add rule of transition
|
||||||
void addRule(Type from, Type to, Handler handler, bool resetAllConditions = false) {if (rules_.contain(Rule(from, to))) return; rules_ << Rule(from, to, PIStringList(), handler, resetAllConditions);}
|
void addRule(Type from, Type to, Handler handler, bool autoTransition = false, bool resetAllConditions = false) {if (rules_.contains(Rule(from, to))) return; rules_ << Rule(from, to, PIStringList(), handler, autoTransition, resetAllConditions);}
|
||||||
|
|
||||||
//! Add rule of transition
|
//! Add rule of transition
|
||||||
void addRule(Type from, Type to, const PIStringList & conditions = PIStringList(), Handler handler = 0, bool resetAllConditions = false) {if (rules_.contain(Rule(from, to))) return; rules_ << Rule(from, to, conditions, handler, resetAllConditions);}
|
void addRule(Type from, Type to, const PIStringList & conditions = PIStringList(), Handler handler = 0, bool autoTransition = false, bool resetAllConditions = false) {if (rules_.contains(Rule(from, to))) return; rules_ << Rule(from, to, conditions, handler, autoTransition, resetAllConditions);}
|
||||||
|
|
||||||
//! Add rule of transition
|
//! Add rule of transition
|
||||||
void addRule(const Rule & rule) {if (rules_.contain(rule)) return; rules_ << rule;}
|
void addRule(const Rule & rule) {if (rules_.contains(rule)) return; rules_ << rule;}
|
||||||
|
|
||||||
//! Rules count
|
//! Rules count
|
||||||
int rulesCount() const {return rules_.size_s();}
|
int rulesCount() const {return rules_.size_s();}
|
||||||
@@ -180,7 +185,7 @@ public:
|
|||||||
if ((r.from != state_.value) || (r.to != to)) continue;
|
if ((r.from != state_.value) || (r.to != to)) continue;
|
||||||
if (!checkConditions(r)) continue;
|
if (!checkConditions(r)) continue;
|
||||||
State ts = findState(to);
|
State ts = findState(to);
|
||||||
if (r.handler != 0) r.handler(this);
|
if (r.handler != 0 && parent_ != 0) r.handler(parent_);
|
||||||
transition(state_, ts);
|
transition(state_, ts);
|
||||||
state_ = ts;
|
state_ = ts;
|
||||||
resetConditions(r);
|
resetConditions(r);
|
||||||
@@ -255,9 +260,18 @@ public:
|
|||||||
|
|
||||||
EVENT_HANDLER(void, tick) {tick(0, 0);}
|
EVENT_HANDLER(void, tick) {tick(0, 0);}
|
||||||
EVENT_HANDLER2(void, tick, void * , data, int, delim) {
|
EVENT_HANDLER2(void, tick, void * , data, int, delim) {
|
||||||
if (switch_to != state_.value) switchToState(switch_to);
|
|
||||||
execution(state_);
|
execution(state_);
|
||||||
if (state_.handler != 0) state_.handler(this);
|
if (state_.handler != 0 && parent_ != 0) state_.handler(parent_);
|
||||||
|
if (switch_to != state_.value) switchToState(switch_to);
|
||||||
|
else {
|
||||||
|
piForeachC (Rule & r, rules_) {
|
||||||
|
if (!r.autoTransition || r.from != state_.value) continue;
|
||||||
|
if (checkConditions(r)) {
|
||||||
|
switchToState(r.to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -310,6 +324,7 @@ private:
|
|||||||
PIVector<Rule> rules_;
|
PIVector<Rule> rules_;
|
||||||
State init_, state_;
|
State init_, state_;
|
||||||
Type switch_to;
|
Type switch_to;
|
||||||
|
void * parent_;
|
||||||
PIVector<Condition> cond;
|
PIVector<Condition> cond;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
62
pistring.h
62
pistring.h
@@ -52,6 +52,7 @@ public:
|
|||||||
|
|
||||||
//! Contructs string with single symbol "c"
|
//! Contructs string with single symbol "c"
|
||||||
PIString(const PIChar & c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += c;}
|
PIString(const PIChar & c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += c;}
|
||||||
|
PIString(const char c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += PIChar(c);}
|
||||||
|
|
||||||
/*! \brief Contructs string from c-string "str"
|
/*! \brief Contructs string from c-string "str"
|
||||||
* \details "str" should be null-terminated\n
|
* \details "str" should be null-terminated\n
|
||||||
@@ -84,7 +85,21 @@ public:
|
|||||||
/*! \brief Contructs string as sequence of symbols "c" of buffer with length "len"
|
/*! \brief Contructs string as sequence of symbols "c" of buffer with length "len"
|
||||||
* \details Example: \snippet pistring.cpp PIString(int, PIChar) */
|
* \details Example: \snippet pistring.cpp PIString(int, PIChar) */
|
||||||
PIString(const int len, const PIChar & c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
PIString(const int len, const PIChar & c): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);}
|
||||||
/*
|
|
||||||
|
|
||||||
|
PIString(const short & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const ushort & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const int & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const uint & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const long & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const ulong & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const llong & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const ullong & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const float & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
PIString(const double & value): PIVector<PIChar>() {reserve(256); piMonitor.strings++; piMonitor.containers--; *this = fromNumber(value);}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
//! Contructs string from other string "str"
|
//! Contructs string from other string "str"
|
||||||
PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; uint len = str.size(); for (uint i = 0; i < len; ++i) push_back(str[i]);}
|
PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; uint len = str.size(); for (uint i = 0; i < len; ++i) push_back(str[i]);}
|
||||||
*/
|
*/
|
||||||
@@ -191,6 +206,18 @@ public:
|
|||||||
bool operator >=(const string & str) const {return *this >= PIString(str);}
|
bool operator >=(const string & str) const {return *this >= PIString(str);}
|
||||||
|
|
||||||
|
|
||||||
|
operator short() const {return toShort();}
|
||||||
|
operator ushort() const {return toUShort();}
|
||||||
|
operator int() const {return toInt();}
|
||||||
|
operator uint() const {return toUInt();}
|
||||||
|
operator long() const {return toLong();}
|
||||||
|
operator ulong() const {return toULong();}
|
||||||
|
operator llong() const {return toLLong();}
|
||||||
|
operator ullong() const {return toULLong();}
|
||||||
|
operator float() const {return toFloat();}
|
||||||
|
operator double() const {return toDouble();}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Append string "str" at the end of string
|
/*! \brief Append string "str" at the end of string
|
||||||
* \details Example: \snippet pistring.cpp PIString::<<(PIString) */
|
* \details Example: \snippet pistring.cpp PIString::<<(PIString) */
|
||||||
PIString & operator <<(const PIString & str) {*this += str; return *this;}
|
PIString & operator <<(const PIString & str) {*this += str; return *this;}
|
||||||
@@ -414,9 +441,9 @@ public:
|
|||||||
//! \brief Convert each symbol in copyed string to lower case and return it
|
//! \brief Convert each symbol in copyed string to lower case and return it
|
||||||
PIString toLowerCase() const;
|
PIString toLowerCase() const;
|
||||||
#ifdef HAS_LOCALE
|
#ifdef HAS_LOCALE
|
||||||
PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point);}
|
PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point).replaceAll(",", currentLocale->decimal_point);}
|
||||||
#else
|
#else
|
||||||
PIString toNativeDecimalPoints() const {PIString s(*this); return s;}
|
PIString toNativeDecimalPoints() const {return PIString(*this).replaceAll(",", ".");}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -660,18 +687,31 @@ private:
|
|||||||
else base = 10;
|
else base = 10;
|
||||||
} else
|
} else
|
||||||
if (base < 2 || base > 40) {if (ok != 0) *ok = false; return 0;}
|
if (base < 2 || base > 40) {if (ok != 0) *ok = false; return 0;}
|
||||||
v.reverse();
|
//v.reverse();
|
||||||
if (ok != 0) *ok = true;
|
if (ok != 0) *ok = true;
|
||||||
|
PIVector<int> digits;
|
||||||
llong ret = 0, m = 1;
|
llong ret = 0, m = 1;
|
||||||
|
bool neg = false;
|
||||||
int cs;
|
int cs;
|
||||||
piForeachC (PIChar & i, v) {
|
for (int i = 0; i < v.size_s(); ++i) {
|
||||||
if (i == PIChar('-')) {ret = -ret; continue;}
|
if (v[i] == PIChar('-')) {neg = !neg; continue;}
|
||||||
//cout << i << ", " << fromBaseN[int(i.toAscii())] << ", " << m << endl;
|
cs = fromBaseN[int(v[i].toAscii())];
|
||||||
cs = fromBaseN[int(i.toAscii())];
|
|
||||||
if (cs < 0 || cs >= base) break;
|
if (cs < 0 || cs >= base) break;
|
||||||
ret += cs * m;
|
digits << cs;
|
||||||
|
}
|
||||||
|
piForeachRC (int & i, digits) {
|
||||||
|
ret += i * m;
|
||||||
m *= base;
|
m *= base;
|
||||||
}
|
}
|
||||||
|
if (neg) ret = -ret;
|
||||||
|
/*piForeachC (PIChar & i, v) {
|
||||||
|
if (i == PIChar('-')) {ret = -ret; continue;}
|
||||||
|
cs = fromBaseN[int(i.toAscii())];
|
||||||
|
cout << i << " = " << cs << endl;
|
||||||
|
if (cs < 0 || cs >= base) return ret;
|
||||||
|
ret += cs * m;
|
||||||
|
m *= base;
|
||||||
|
}*/
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
void appendFromChars(const char * c, int s);
|
void appendFromChars(const char * c, int s);
|
||||||
@@ -765,6 +805,10 @@ public:
|
|||||||
//! \details Example: \snippet pistring.cpp PIStringList::removeDuplicates
|
//! \details Example: \snippet pistring.cpp PIStringList::removeDuplicates
|
||||||
PIStringList & removeDuplicates();
|
PIStringList & removeDuplicates();
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \details Example: \snippet pistring.cpp PIStringList::trim
|
||||||
|
PIStringList & trim() {for (uint i = 0; i < size(); ++i) at(i).trim(); return *this;}
|
||||||
|
|
||||||
//! Return sum of lengths of all strings
|
//! Return sum of lengths of all strings
|
||||||
uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}
|
uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;}
|
||||||
|
|
||||||
|
|||||||
24
pithread.h
24
pithread.h
@@ -29,32 +29,8 @@
|
|||||||
#include "pimutex.h"
|
#include "pimutex.h"
|
||||||
#include "piobject.h"
|
#include "piobject.h"
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
|
||||||
//! \brief Sleep for "msecs" milliseconds
|
|
||||||
void msleep(int msecs);
|
|
||||||
#else
|
|
||||||
# ifdef WINDOWS
|
|
||||||
inline void msleep(int msecs) {Sleep(msecs);}
|
|
||||||
# else
|
|
||||||
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \brief Precise sleep for "usecs" microseconds
|
|
||||||
* \details This function consider \c "usleep" offset
|
|
||||||
* on QNX/Linux/Mac, which is calculated with
|
|
||||||
* \a pip_sys_test program. If there is correct
|
|
||||||
* offset value in system config, this function
|
|
||||||
* wait \b exactly "usecs" microseconds. */
|
|
||||||
void piUSleep(int usecs); // on !Windows consider constant "usleep" offset
|
|
||||||
|
|
||||||
/*! \brief Precise sleep for "msecs" milliseconds
|
|
||||||
* \details This function exec \a piUSleep (msecs * 1000). */
|
|
||||||
inline void piMSleep(int msecs) {piUSleep(msecs * 1000);} // on !Windows consider constant "usleep" offset
|
|
||||||
|
|
||||||
typedef void (*ThreadFunc)(void * );
|
typedef void (*ThreadFunc)(void * );
|
||||||
|
|
||||||
|
|
||||||
class PIP_EXPORT PIThread: public PIObject
|
class PIP_EXPORT PIThread: public PIObject
|
||||||
{
|
{
|
||||||
PIOBJECT(PIThread)
|
PIOBJECT(PIThread)
|
||||||
|
|||||||
298
pitime.cpp
Normal file
298
pitime.cpp
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Timer
|
||||||
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pitime.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class PISystemTime
|
||||||
|
* \brief System time
|
||||||
|
*
|
||||||
|
* \section PISystemTime_sec0 Synopsis
|
||||||
|
* This class provide arithmetic functions for POSIX system time.
|
||||||
|
* This time represents as seconds and nanosecons in integer formats.
|
||||||
|
* You can take current system time with function \a currentSystemTime(),
|
||||||
|
* compare times, sum or subtract two times, convert time to/from
|
||||||
|
* seconds, milliseconds, microseconds or nanoseconds.
|
||||||
|
* \section PISystemTime_sec1 Example
|
||||||
|
* \snippet pitimer.cpp system_time
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
bool operator ==(const PITime & t0, const PITime & t1) {
|
||||||
|
return (t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator <(const PITime & t0, const PITime & t1) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds < t1.seconds;
|
||||||
|
} else return t0.minutes < t1.minutes;
|
||||||
|
} else return t0.hours < t1.hours;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator >(const PITime & t0, const PITime & t1) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds > t1.seconds;
|
||||||
|
} else return t0.minutes > t1.minutes;
|
||||||
|
} else return t0.hours > t1.hours;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const PIDate & t0, const PIDate & t1) {
|
||||||
|
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator <(const PIDate & t0, const PIDate & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
return t0.day < t1.day;
|
||||||
|
} else return t0.month < t1.month;
|
||||||
|
} else return t0.year < t1.year;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator >(const PIDate & t0, const PIDate & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
return t0.day > t1.day;
|
||||||
|
} else return t0.month > t1.month;
|
||||||
|
} else return t0.year > t1.year;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const PIDateTime & t0, const PIDateTime & t1) {
|
||||||
|
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day &&
|
||||||
|
t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator <(const PIDateTime & t0, const PIDateTime & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
if (t0.day == t1.day) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds < t1.seconds;
|
||||||
|
} else return t0.minutes < t1.minutes;
|
||||||
|
} else return t0.hours < t1.hours;
|
||||||
|
} else return t0.day < t1.day;
|
||||||
|
} else return t0.month < t1.month;
|
||||||
|
} else return t0.year < t1.year;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator >(const PIDateTime & t0, const PIDateTime & t1) {
|
||||||
|
if (t0.year == t1.year) {
|
||||||
|
if (t0.month == t1.month) {
|
||||||
|
if (t0.day == t1.day) {
|
||||||
|
if (t0.hours == t1.hours) {
|
||||||
|
if (t0.minutes == t1.minutes) {
|
||||||
|
return t0.seconds > t1.seconds;
|
||||||
|
} else return t0.minutes > t1.minutes;
|
||||||
|
} else return t0.hours > t1.hours;
|
||||||
|
} else return t0.day > t1.day;
|
||||||
|
} else return t0.month > t1.month;
|
||||||
|
} else return t0.year > t1.year;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PITime currentTime() {
|
||||||
|
time_t rt = time(0);
|
||||||
|
tm * pt = localtime(&rt);
|
||||||
|
PITime t;
|
||||||
|
t.seconds = pt->tm_sec;
|
||||||
|
t.minutes = pt->tm_min;
|
||||||
|
t.hours = pt->tm_hour;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIDate currentDate() {
|
||||||
|
time_t rt = time(0);
|
||||||
|
tm * pt = localtime(&rt);
|
||||||
|
PIDate d;
|
||||||
|
d.day = pt->tm_mday;
|
||||||
|
d.month = pt->tm_mon + 1;
|
||||||
|
d.year = pt->tm_year + 1900;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIDateTime currentDateTime() {
|
||||||
|
time_t rt = time(0);
|
||||||
|
tm * pt = localtime(&rt);
|
||||||
|
PIDateTime dt;
|
||||||
|
dt.milliseconds = 0;
|
||||||
|
dt.seconds = pt->tm_sec;
|
||||||
|
dt.minutes = pt->tm_min;
|
||||||
|
dt.hours = pt->tm_hour;
|
||||||
|
dt.day = pt->tm_mday;
|
||||||
|
dt.month = pt->tm_mon + 1;
|
||||||
|
dt.year = pt->tm_year + 1900;
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PISystemTime currentSystemTime() {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
FILETIME ft, sft;
|
||||||
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
sft.dwHighDateTime = ft.dwHighDateTime - __pi_ftjan1970.dwHighDateTime;
|
||||||
|
if (ft.dwLowDateTime < __pi_ftjan1970.dwLowDateTime) {
|
||||||
|
sft.dwLowDateTime = ft.dwLowDateTime + (0xFFFFFFFF - __pi_ftjan1970.dwLowDateTime);
|
||||||
|
sft.dwHighDateTime++;
|
||||||
|
} else
|
||||||
|
sft.dwLowDateTime = ft.dwLowDateTime - __pi_ftjan1970.dwLowDateTime;
|
||||||
|
ullong lt = ullong(sft.dwHighDateTime) * 0x100000000U + ullong(sft.dwLowDateTime);
|
||||||
|
return PISystemTime(lt / 10000000U, (lt % 10000000U) * 100U);
|
||||||
|
//long t_cur = GetCurrentTime();
|
||||||
|
//return PISystemTime(t_cur / 1000, (t_cur % 1000) * 1000000);
|
||||||
|
#else
|
||||||
|
# ifdef MAC_OS
|
||||||
|
mach_timespec_t t_cur;
|
||||||
|
clock_get_time(__pi_mac_clock, &t_cur);
|
||||||
|
# else
|
||||||
|
timespec t_cur;
|
||||||
|
clock_gettime(0, &t_cur);
|
||||||
|
# endif
|
||||||
|
return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PITime::toString(const PIString & format) const {
|
||||||
|
PIString ts = format;
|
||||||
|
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("h", PIString::fromNumber(hours));
|
||||||
|
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("m", PIString::fromNumber(minutes));
|
||||||
|
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("s", PIString::fromNumber(seconds));
|
||||||
|
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
||||||
|
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("z", PIString::fromNumber(milliseconds));
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIDate::toString(const PIString & format) const {
|
||||||
|
PIString ts = format;
|
||||||
|
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||||
|
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||||
|
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||||
|
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("M", PIString::fromNumber(month));
|
||||||
|
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("d", PIString::fromNumber(day));
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIDateTime::toString(const PIString & format) const {
|
||||||
|
PIString ts = format;
|
||||||
|
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||||
|
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||||
|
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||||
|
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("M", PIString::fromNumber(month));
|
||||||
|
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("d", PIString::fromNumber(day));
|
||||||
|
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("h", PIString::fromNumber(hours));
|
||||||
|
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("m", PIString::fromNumber(minutes));
|
||||||
|
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("s", PIString::fromNumber(seconds));
|
||||||
|
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
||||||
|
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("z", PIString::fromNumber(milliseconds));
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
time_t PIDateTime::toSecondSinceEpoch() const {
|
||||||
|
tm pt;
|
||||||
|
pt.tm_sec = seconds;
|
||||||
|
pt.tm_min = minutes;
|
||||||
|
pt.tm_hour = hours;
|
||||||
|
pt.tm_mday = day;
|
||||||
|
pt.tm_mon = month - 1;
|
||||||
|
pt.tm_year = year - 1900;
|
||||||
|
return mktime(&pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIDateTime PIDateTime::fromSecondSinceEpoch(const time_t sec) {
|
||||||
|
tm * pt = localtime(&sec);
|
||||||
|
PIDateTime dt;
|
||||||
|
dt.seconds = pt->tm_sec;
|
||||||
|
dt.minutes = pt->tm_min;
|
||||||
|
dt.hours = pt->tm_hour;
|
||||||
|
dt.day = pt->tm_mday;
|
||||||
|
dt.month = pt->tm_mon + 1;
|
||||||
|
dt.year = pt->tm_year + 1900;
|
||||||
|
return dt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString time2string(const PITime & time, const PIString & format) {
|
||||||
|
PIString ts = format;
|
||||||
|
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("h", PIString::fromNumber(time.hours));
|
||||||
|
ts.replace("mm", PIString::fromNumber(time.minutes).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("m", PIString::fromNumber(time.minutes));
|
||||||
|
ts.replace("ss", PIString::fromNumber(time.seconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("s", PIString::fromNumber(time.seconds));
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString date2string(const PIDate & date, const PIString & format) {
|
||||||
|
PIString ts = format;
|
||||||
|
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||||
|
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||||
|
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||||
|
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("M", PIString::fromNumber(date.month));
|
||||||
|
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("d", PIString::fromNumber(date.day));
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString datetime2string(const PIDateTime & date, const PIString & format) {
|
||||||
|
PIString ts = format;
|
||||||
|
ts.replace("hh", PIString::fromNumber(date.hours).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("h", PIString::fromNumber(date.hours));
|
||||||
|
ts.replace("mm", PIString::fromNumber(date.minutes).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("m", PIString::fromNumber(date.minutes));
|
||||||
|
ts.replace("ss", PIString::fromNumber(date.seconds).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("s", PIString::fromNumber(date.seconds));
|
||||||
|
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||||
|
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||||
|
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||||
|
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("M", PIString::fromNumber(date.month));
|
||||||
|
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||||
|
ts.replace("d", PIString::fromNumber(date.day));
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
235
pitime.h
Normal file
235
pitime.h
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
/*! \file pitime.h
|
||||||
|
* \brief Time structs
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Time structs
|
||||||
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PITIME_H
|
||||||
|
#define PITIME_H
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <csignal>
|
||||||
|
#include "pistring.h"
|
||||||
|
|
||||||
|
#ifdef DOXYGEN
|
||||||
|
//! \brief Sleep for "msecs" milliseconds
|
||||||
|
void msleep(int msecs);
|
||||||
|
#else
|
||||||
|
# ifdef WINDOWS
|
||||||
|
inline void msleep(int msecs) {Sleep(msecs);}
|
||||||
|
# else
|
||||||
|
inline void msleep(int msecs) {usleep(msecs * 1000);}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \brief Precise sleep for "usecs" microseconds
|
||||||
|
* \details This function consider \c "usleep" offset
|
||||||
|
* on QNX/Linux/Mac, which is calculated with
|
||||||
|
* \a pip_sys_test program. If there is correct
|
||||||
|
* offset value in system config, this function
|
||||||
|
* wait \b exactly "usecs" microseconds. */
|
||||||
|
void piUSleep(int usecs); // on !Windows consider constant "usleep" offset
|
||||||
|
|
||||||
|
/*! \brief Precise sleep for "msecs" milliseconds
|
||||||
|
* \details This function exec \a piUSleep (msecs * 1000). */
|
||||||
|
inline void piMSleep(int msecs) {piUSleep(msecs * 1000);} // on !Windows consider constant "usleep" offset
|
||||||
|
|
||||||
|
class PIP_EXPORT PISystemTime {
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Contructs system time with s = ns = 0
|
||||||
|
PISystemTime() {seconds = nanoseconds = 0;}
|
||||||
|
|
||||||
|
//! Contructs system time with s = "s" and ns = "ns"
|
||||||
|
PISystemTime(long s, long ns) {seconds = s; nanoseconds = ns; checkOverflows();}
|
||||||
|
|
||||||
|
//! Contructs system time from another
|
||||||
|
PISystemTime(const PISystemTime & t) {seconds = t.seconds; nanoseconds = t.nanoseconds;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns stored system time value in seconds
|
||||||
|
double toSeconds() const {return double(seconds) + nanoseconds / 1.e+9;}
|
||||||
|
|
||||||
|
//! Returns stored system time value in milliseconds
|
||||||
|
double toMilliseconds() const {return seconds * 1.e+3 + nanoseconds / 1.e+6;}
|
||||||
|
|
||||||
|
//! Returns stored system time value in microseconds
|
||||||
|
double toMicroseconds() const {return seconds * 1.e+6 + nanoseconds / 1.e+3;}
|
||||||
|
|
||||||
|
//! Returns stored system time value in nanoseconds
|
||||||
|
double toNanoseconds() const {return seconds * 1.e+9 + double(nanoseconds);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Add to stored system time "v" seconds
|
||||||
|
PISystemTime & addSeconds(double v) {*this += fromSeconds(v); return *this;}
|
||||||
|
|
||||||
|
//! Add to stored system time "v" milliseconds
|
||||||
|
PISystemTime & addMilliseconds(double v) {*this += fromMilliseconds(v); return *this;}
|
||||||
|
|
||||||
|
//! Add to stored system time "v" microseconds
|
||||||
|
PISystemTime & addMicroseconds(double v) {*this += fromMicroseconds(v); return *this;}
|
||||||
|
|
||||||
|
//! Add to stored system time "v" nanoseconds
|
||||||
|
PISystemTime & addNanoseconds(double v) {*this += fromNanoseconds(v); return *this;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Sleep for stored value. \warning Use this function to sleep for difference of system times or constructs system time.
|
||||||
|
//! If you call this function on system time returned from \a currentSystemTime() thread will be sleep almost forever.
|
||||||
|
void sleep() {piUSleep(piFloord(toMicroseconds()));} // wait self value, useful to wait some dT = (t1 - t0)
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns copy of this system time with absolutely values of s and ns
|
||||||
|
PISystemTime abs() const {return PISystemTime(piAbsl(seconds), piAbsl(nanoseconds));}
|
||||||
|
|
||||||
|
//! Returns sum of this system time with "t"
|
||||||
|
PISystemTime operator +(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds += t.seconds; tt.nanoseconds += t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||||
|
|
||||||
|
//! Returns difference between this system time and "t"
|
||||||
|
PISystemTime operator -(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds -= t.seconds; tt.nanoseconds -= t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||||
|
|
||||||
|
//! Add to stored value system time "t"
|
||||||
|
PISystemTime & operator +=(const PISystemTime & t) {seconds += t.seconds; nanoseconds += t.nanoseconds; checkOverflows(); return *this;}
|
||||||
|
|
||||||
|
//! Subtract from stored value system time "t"
|
||||||
|
PISystemTime & operator -=(const PISystemTime & t) {seconds -= t.seconds; nanoseconds -= t.nanoseconds; checkOverflows(); return *this;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Compare system times
|
||||||
|
bool operator ==(const PISystemTime & t) {return ((seconds == t.seconds) && (nanoseconds == t.nanoseconds));}
|
||||||
|
|
||||||
|
//! Compare system times
|
||||||
|
bool operator !=(const PISystemTime & t) {return ((seconds != t.seconds) || (nanoseconds != t.nanoseconds));}
|
||||||
|
|
||||||
|
//! Compare system times
|
||||||
|
bool operator >(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds > t.nanoseconds; return seconds > t.seconds;}
|
||||||
|
|
||||||
|
//! Compare system times
|
||||||
|
bool operator <(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds < t.nanoseconds; return seconds < t.seconds;}
|
||||||
|
|
||||||
|
//! Compare system times
|
||||||
|
bool operator >=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds >= t.nanoseconds; return seconds >= t.seconds;}
|
||||||
|
|
||||||
|
//! Compare system times
|
||||||
|
bool operator <=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds <= t.nanoseconds; return seconds <= t.seconds;}
|
||||||
|
|
||||||
|
|
||||||
|
//! Contructs system time from seconds "v"
|
||||||
|
static PISystemTime fromSeconds(double v) {long s = piFloord(v); return PISystemTime(s, (v - s) * 1000000000);}
|
||||||
|
|
||||||
|
//! Contructs system time from milliseconds "v"
|
||||||
|
static PISystemTime fromMilliseconds(double v) {long s = piFloord(v / 1000.); return PISystemTime(s, (v / 1000. - s) * 1000000000);}
|
||||||
|
|
||||||
|
//! Contructs system time from microseconds "v"
|
||||||
|
static PISystemTime fromMicroseconds(double v) {long s = piFloord(v / 1000000.); return PISystemTime(s, (v / 1000000. - s) * 1000000000);}
|
||||||
|
|
||||||
|
//! Contructs system time from nanoseconds "v"
|
||||||
|
static PISystemTime fromNanoseconds(double v) {long s = piFloord(v / 1000000000.); return PISystemTime(s, (v / 1000000000. - s) * 1000000000);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Seconds of stored system time
|
||||||
|
long seconds;
|
||||||
|
|
||||||
|
//! Nanoseconds of stored system time
|
||||||
|
long nanoseconds;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkOverflows() {while (nanoseconds >= 1000000000) {nanoseconds -= 1000000000; seconds++;} while (nanoseconds < 0) {nanoseconds += 1000000000; seconds--;}}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \relatesalso PICout \relatesalso PIByteArray \brief Output operator to PICout
|
||||||
|
inline PICout operator <<(PICout s, const PISystemTime & v) {s.setControl(0, true); s.space(); s << "(" << v.seconds << " s, " << v.nanoseconds << " ns)"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PISystemTime \relatesalso PIByteArray \brief Output operator to PIByteArray
|
||||||
|
inline PIByteArray & operator <<(PIByteArray & s, const PISystemTime & v) {s << v.seconds << v.nanoseconds; return s;}
|
||||||
|
|
||||||
|
//! \relatesalso PISystemTime \relatesalso PIByteArray \brief Input operator from PIByteArray
|
||||||
|
inline PIByteArray & operator >>(PIByteArray & s, PISystemTime & v) {s >> v.seconds >> v.nanoseconds; return s;}
|
||||||
|
|
||||||
|
struct PIP_EXPORT PITime {
|
||||||
|
PITime() {hours = minutes = seconds = milliseconds = 0;}
|
||||||
|
int milliseconds;
|
||||||
|
int seconds;
|
||||||
|
int minutes;
|
||||||
|
int hours;
|
||||||
|
PIString toString(const PIString & format = "h:mm:ss") const;
|
||||||
|
};
|
||||||
|
PIP_EXPORT bool operator ==(const PITime & t0, const PITime & t1);
|
||||||
|
PIP_EXPORT bool operator <(const PITime & t0, const PITime & t1);
|
||||||
|
PIP_EXPORT bool operator >(const PITime & t0, const PITime & t1);
|
||||||
|
inline bool operator !=(const PITime & t0, const PITime & t1) {return !(t0 == t1);}
|
||||||
|
inline bool operator <=(const PITime & t0, const PITime & t1) {return !(t0 > t1);}
|
||||||
|
inline bool operator >=(const PITime & t0, const PITime & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
|
struct PIP_EXPORT PIDate {
|
||||||
|
PIDate() {year = month = day = 0;}
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
PIString toString(const PIString & format = "d.MM.yyyy") const;
|
||||||
|
};
|
||||||
|
PIP_EXPORT bool operator ==(const PIDate & t0, const PIDate & t1);
|
||||||
|
PIP_EXPORT bool operator <(const PIDate & t0, const PIDate & t1);
|
||||||
|
PIP_EXPORT bool operator >(const PIDate & t0, const PIDate & t1);
|
||||||
|
inline bool operator !=(const PIDate & t0, const PIDate & t1) {return !(t0 == t1);}
|
||||||
|
inline bool operator <=(const PIDate & t0, const PIDate & t1) {return !(t0 > t1);}
|
||||||
|
inline bool operator >=(const PIDate & t0, const PIDate & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
|
struct PIP_EXPORT PIDateTime {
|
||||||
|
PIDateTime() {year = month = day = hours = minutes = seconds = 0;}
|
||||||
|
PIDateTime(const PITime & time) {year = month = day = 0; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
||||||
|
PIDateTime(const PIDate & date) {year = date.year; month = date.month; day = date.day; hours = minutes = seconds = milliseconds = 0;}
|
||||||
|
PIDateTime(const PIDate & date, const PITime & time) {year = date.year; month = date.month; day = date.day; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
||||||
|
int milliseconds;
|
||||||
|
int seconds;
|
||||||
|
int minutes;
|
||||||
|
int hours;
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
PIDateTime normalized() const {return PIDateTime::fromSecondSinceEpoch(toSecondSinceEpoch());}
|
||||||
|
void normalize() {*this = normalized();}
|
||||||
|
PIString toString(const PIString & format = "h:mm:ss d.MM.yyyy") const;
|
||||||
|
time_t toSecondSinceEpoch() const;
|
||||||
|
PISystemTime toSystemTime() const {return PISystemTime(int(toSecondSinceEpoch()), milliseconds * 1000000);}
|
||||||
|
void operator +=(const PIDateTime & d1) {year += d1.year; month += d1.month; day += d1.day; hours += d1.hours; minutes += d1.minutes; seconds += d1.seconds; normalize();}
|
||||||
|
void operator -=(const PIDateTime & d1) {year -= d1.year; month -= d1.month; day -= d1.day; hours -= d1.hours; minutes -= d1.minutes; seconds -= d1.seconds; normalize();}
|
||||||
|
static PIDateTime fromSecondSinceEpoch(const time_t sec);
|
||||||
|
static PIDateTime fromSystemTime(const PISystemTime & st) {PIDateTime dt = fromSecondSinceEpoch(st.seconds); dt.milliseconds = piClampi(st.nanoseconds / 1000000, 0, 999); return dt;}
|
||||||
|
};
|
||||||
|
inline PIDateTime operator +(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td += d1; return td.normalized();}
|
||||||
|
inline PIDateTime operator -(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td -= d1; return td.normalized();}
|
||||||
|
PIP_EXPORT bool operator ==(const PIDateTime & t0, const PIDateTime & t1);
|
||||||
|
PIP_EXPORT bool operator <(const PIDateTime & t0, const PIDateTime & t1);
|
||||||
|
PIP_EXPORT bool operator >(const PIDateTime & t0, const PIDateTime & t1);
|
||||||
|
inline bool operator !=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 == t1);}
|
||||||
|
inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 > t1);}
|
||||||
|
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
||||||
|
|
||||||
|
PIP_EXPORT PITime currentTime();
|
||||||
|
PIP_EXPORT PIDate currentDate();
|
||||||
|
PIP_EXPORT PIDateTime currentDateTime();
|
||||||
|
|
||||||
|
//! \relatesalso PISystemTime \brief Returns current system time
|
||||||
|
PIP_EXPORT PISystemTime currentSystemTime();
|
||||||
|
PIP_EXPORT PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
||||||
|
PIP_EXPORT PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.toString() instead
|
||||||
|
PIP_EXPORT PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
||||||
|
|
||||||
|
#endif // PITIME_H
|
||||||
268
pitimer.cpp
268
pitimer.cpp
@@ -1,4 +1,4 @@
|
|||||||
/*ccc
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Timer
|
Timer
|
||||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
@@ -47,88 +47,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*! \class PISystemTime
|
|
||||||
* \brief System time
|
|
||||||
*
|
|
||||||
* \section PISystemTime_sec0 Synopsis
|
|
||||||
* This class provide arithmetic functions for POSIX system time.
|
|
||||||
* This time represents as seconds and nanosecons in integer formats.
|
|
||||||
* You can take current system time with function \a currentSystemTime(),
|
|
||||||
* compare times, sum or subtract two times, convert time to/from
|
|
||||||
* seconds, milliseconds, microseconds or nanoseconds.
|
|
||||||
* \section PISystemTime_sec1 Example
|
|
||||||
* \snippet pitimer.cpp system_time
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
bool operator ==(const PITime & t0, const PITime & t1) {
|
|
||||||
return (t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
|
||||||
}
|
|
||||||
bool operator <(const PITime & t0, const PITime & t1) {
|
|
||||||
if (t0.hours == t1.hours) {
|
|
||||||
if (t0.minutes == t1.minutes) {
|
|
||||||
return t0.seconds < t1.seconds;
|
|
||||||
} else return t0.minutes < t1.minutes;
|
|
||||||
} else return t0.hours < t1.hours;
|
|
||||||
}
|
|
||||||
bool operator >(const PITime & t0, const PITime & t1) {
|
|
||||||
if (t0.hours == t1.hours) {
|
|
||||||
if (t0.minutes == t1.minutes) {
|
|
||||||
return t0.seconds > t1.seconds;
|
|
||||||
} else return t0.minutes > t1.minutes;
|
|
||||||
} else return t0.hours > t1.hours;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator ==(const PIDate & t0, const PIDate & t1) {
|
|
||||||
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day);
|
|
||||||
}
|
|
||||||
bool operator <(const PIDate & t0, const PIDate & t1) {
|
|
||||||
if (t0.year == t1.year) {
|
|
||||||
if (t0.month == t1.month) {
|
|
||||||
return t0.day < t1.day;
|
|
||||||
} else return t0.month < t1.month;
|
|
||||||
} else return t0.year < t1.year;
|
|
||||||
}
|
|
||||||
bool operator >(const PIDate & t0, const PIDate & t1) {
|
|
||||||
if (t0.year == t1.year) {
|
|
||||||
if (t0.month == t1.month) {
|
|
||||||
return t0.day > t1.day;
|
|
||||||
} else return t0.month > t1.month;
|
|
||||||
} else return t0.year > t1.year;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator ==(const PIDateTime & t0, const PIDateTime & t1) {
|
|
||||||
return (t0.year == t1.year && t0.month == t1.month && t0.day == t1.day &&
|
|
||||||
t0.hours == t1.hours && t0.minutes == t1.minutes && t0.seconds == t1.seconds);
|
|
||||||
}
|
|
||||||
bool operator <(const PIDateTime & t0, const PIDateTime & t1) {
|
|
||||||
if (t0.year == t1.year) {
|
|
||||||
if (t0.month == t1.month) {
|
|
||||||
if (t0.day == t1.day) {
|
|
||||||
if (t0.hours == t1.hours) {
|
|
||||||
if (t0.minutes == t1.minutes) {
|
|
||||||
return t0.seconds < t1.seconds;
|
|
||||||
} else return t0.minutes < t1.minutes;
|
|
||||||
} else return t0.hours < t1.hours;
|
|
||||||
} else return t0.day < t1.day;
|
|
||||||
} else return t0.month < t1.month;
|
|
||||||
} else return t0.year < t1.year;
|
|
||||||
}
|
|
||||||
bool operator >(const PIDateTime & t0, const PIDateTime & t1) {
|
|
||||||
if (t0.year == t1.year) {
|
|
||||||
if (t0.month == t1.month) {
|
|
||||||
if (t0.day == t1.day) {
|
|
||||||
if (t0.hours == t1.hours) {
|
|
||||||
if (t0.minutes == t1.minutes) {
|
|
||||||
return t0.seconds > t1.seconds;
|
|
||||||
} else return t0.minutes > t1.minutes;
|
|
||||||
} else return t0.hours > t1.hours;
|
|
||||||
} else return t0.day > t1.day;
|
|
||||||
} else return t0.month > t1.month;
|
|
||||||
} else return t0.year > t1.year;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PIP_TIMER_RT
|
#ifdef PIP_TIMER_RT
|
||||||
PITimer::TimerPool * pool = 0;
|
PITimer::TimerPool * pool = 0;
|
||||||
#endif
|
#endif
|
||||||
@@ -659,187 +577,3 @@ double PITimer::elapsed_system_s() {
|
|||||||
return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9));
|
return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PITime currentTime() {
|
|
||||||
time_t rt = time(0);
|
|
||||||
tm * pt = localtime(&rt);
|
|
||||||
PITime t;
|
|
||||||
t.seconds = pt->tm_sec;
|
|
||||||
t.minutes = pt->tm_min;
|
|
||||||
t.hours = pt->tm_hour;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIDate currentDate() {
|
|
||||||
time_t rt = time(0);
|
|
||||||
tm * pt = localtime(&rt);
|
|
||||||
PIDate d;
|
|
||||||
d.day = pt->tm_mday;
|
|
||||||
d.month = pt->tm_mon + 1;
|
|
||||||
d.year = pt->tm_year + 1900;
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIDateTime currentDateTime() {
|
|
||||||
time_t rt = time(0);
|
|
||||||
tm * pt = localtime(&rt);
|
|
||||||
PIDateTime dt;
|
|
||||||
dt.milliseconds = 0;
|
|
||||||
dt.seconds = pt->tm_sec;
|
|
||||||
dt.minutes = pt->tm_min;
|
|
||||||
dt.hours = pt->tm_hour;
|
|
||||||
dt.day = pt->tm_mday;
|
|
||||||
dt.month = pt->tm_mon + 1;
|
|
||||||
dt.year = pt->tm_year + 1900;
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PISystemTime currentSystemTime() {
|
|
||||||
#ifdef WINDOWS
|
|
||||||
FILETIME ft, sft;
|
|
||||||
GetSystemTimeAsFileTime(&ft);
|
|
||||||
sft.dwHighDateTime = ft.dwHighDateTime - __pi_ftjan1970.dwHighDateTime;
|
|
||||||
if (ft.dwLowDateTime < __pi_ftjan1970.dwLowDateTime) {
|
|
||||||
sft.dwLowDateTime = ft.dwLowDateTime + (0xFFFFFFFF - __pi_ftjan1970.dwLowDateTime);
|
|
||||||
sft.dwHighDateTime++;
|
|
||||||
} else
|
|
||||||
sft.dwLowDateTime = ft.dwLowDateTime - __pi_ftjan1970.dwLowDateTime;
|
|
||||||
ullong lt = ullong(sft.dwHighDateTime) * 0x100000000U + ullong(sft.dwLowDateTime);
|
|
||||||
return PISystemTime(lt / 10000000U, (lt % 10000000U) * 100U);
|
|
||||||
//long t_cur = GetCurrentTime();
|
|
||||||
//return PISystemTime(t_cur / 1000, (t_cur % 1000) * 1000000);
|
|
||||||
#else
|
|
||||||
# ifdef MAC_OS
|
|
||||||
mach_timespec_t t_cur;
|
|
||||||
clock_get_time(__pi_mac_clock, &t_cur);
|
|
||||||
# else
|
|
||||||
timespec t_cur;
|
|
||||||
clock_gettime(0, &t_cur);
|
|
||||||
# endif
|
|
||||||
return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PITime::toString(const PIString & format) const {
|
|
||||||
PIString ts = format;
|
|
||||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("h", PIString::fromNumber(hours));
|
|
||||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("m", PIString::fromNumber(minutes));
|
|
||||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("s", PIString::fromNumber(seconds));
|
|
||||||
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
|
||||||
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("z", PIString::fromNumber(milliseconds));
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PIDate::toString(const PIString & format) const {
|
|
||||||
PIString ts = format;
|
|
||||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
|
||||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
|
||||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
|
||||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("M", PIString::fromNumber(month));
|
|
||||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("d", PIString::fromNumber(day));
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PIDateTime::toString(const PIString & format) const {
|
|
||||||
PIString ts = format;
|
|
||||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
|
||||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
|
||||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
|
||||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("M", PIString::fromNumber(month));
|
|
||||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("d", PIString::fromNumber(day));
|
|
||||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("h", PIString::fromNumber(hours));
|
|
||||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("m", PIString::fromNumber(minutes));
|
|
||||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("s", PIString::fromNumber(seconds));
|
|
||||||
ts.replace("zzz", PIString::fromNumber(milliseconds).expandLeftTo(3, '0'));
|
|
||||||
ts.replace("zz", PIString::fromNumber(milliseconds).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("z", PIString::fromNumber(milliseconds));
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
time_t PIDateTime::toSecondSinceEpoch() const {
|
|
||||||
tm pt;
|
|
||||||
pt.tm_sec = seconds;
|
|
||||||
pt.tm_min = minutes;
|
|
||||||
pt.tm_hour = hours;
|
|
||||||
pt.tm_mday = day;
|
|
||||||
pt.tm_mon = month - 1;
|
|
||||||
pt.tm_year = year - 1900;
|
|
||||||
return mktime(&pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIDateTime PIDateTime::fromSecondSinceEpoch(const time_t sec) {
|
|
||||||
tm * pt = localtime(&sec);
|
|
||||||
PIDateTime dt;
|
|
||||||
dt.seconds = pt->tm_sec;
|
|
||||||
dt.minutes = pt->tm_min;
|
|
||||||
dt.hours = pt->tm_hour;
|
|
||||||
dt.day = pt->tm_mday;
|
|
||||||
dt.month = pt->tm_mon + 1;
|
|
||||||
dt.year = pt->tm_year + 1900;
|
|
||||||
return dt;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString time2string(const PITime & time, const PIString & format) {
|
|
||||||
PIString ts = format;
|
|
||||||
ts.replace("hh", PIString::fromNumber(time.hours).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("h", PIString::fromNumber(time.hours));
|
|
||||||
ts.replace("mm", PIString::fromNumber(time.minutes).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("m", PIString::fromNumber(time.minutes));
|
|
||||||
ts.replace("ss", PIString::fromNumber(time.seconds).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("s", PIString::fromNumber(time.seconds));
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString date2string(const PIDate & date, const PIString & format) {
|
|
||||||
PIString ts = format;
|
|
||||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
|
||||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
|
||||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
|
||||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("M", PIString::fromNumber(date.month));
|
|
||||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("d", PIString::fromNumber(date.day));
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString datetime2string(const PIDateTime & date, const PIString & format) {
|
|
||||||
PIString ts = format;
|
|
||||||
ts.replace("hh", PIString::fromNumber(date.hours).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("h", PIString::fromNumber(date.hours));
|
|
||||||
ts.replace("mm", PIString::fromNumber(date.minutes).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("m", PIString::fromNumber(date.minutes));
|
|
||||||
ts.replace("ss", PIString::fromNumber(date.seconds).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("s", PIString::fromNumber(date.seconds));
|
|
||||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
|
||||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
|
||||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
|
||||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("M", PIString::fromNumber(date.month));
|
|
||||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
|
||||||
ts.replace("d", PIString::fromNumber(date.day));
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|||||||
188
pitimer.h
188
pitimer.h
@@ -23,187 +23,11 @@
|
|||||||
#ifndef PITIMER_H
|
#ifndef PITIMER_H
|
||||||
#define PITIMER_H
|
#define PITIMER_H
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
#include <csignal>
|
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "pistring.h"
|
#include "pitime.h"
|
||||||
#include "piobject.h"
|
|
||||||
|
|
||||||
typedef void (*TimerEvent)(void * , int );
|
typedef void (*TimerEvent)(void * , int );
|
||||||
|
|
||||||
class PIP_EXPORT PISystemTime {
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Contructs system time with s = ns = 0
|
|
||||||
PISystemTime() {seconds = nanoseconds = 0;}
|
|
||||||
|
|
||||||
//! Contructs system time with s = "s" and ns = "ns"
|
|
||||||
PISystemTime(long s, long ns) {seconds = s; nanoseconds = ns; checkOverflows();}
|
|
||||||
|
|
||||||
//! Contructs system time from another
|
|
||||||
PISystemTime(const PISystemTime & t) {seconds = t.seconds; nanoseconds = t.nanoseconds;}
|
|
||||||
|
|
||||||
|
|
||||||
//! Returns stored system time value in seconds
|
|
||||||
double toSeconds() const {return double(seconds) + nanoseconds / 1.e+9;}
|
|
||||||
|
|
||||||
//! Returns stored system time value in milliseconds
|
|
||||||
double toMilliseconds() const {return seconds * 1.e+3 + nanoseconds / 1.e+6;}
|
|
||||||
|
|
||||||
//! Returns stored system time value in microseconds
|
|
||||||
double toMicroseconds() const {return seconds * 1.e+6 + nanoseconds / 1.e+3;}
|
|
||||||
|
|
||||||
//! Returns stored system time value in nanoseconds
|
|
||||||
double toNanoseconds() const {return seconds * 1.e+9 + double(nanoseconds);}
|
|
||||||
|
|
||||||
|
|
||||||
//! Add to stored system time "v" seconds
|
|
||||||
PISystemTime & addSeconds(double v) {*this += fromSeconds(v); return *this;}
|
|
||||||
|
|
||||||
//! Add to stored system time "v" milliseconds
|
|
||||||
PISystemTime & addMilliseconds(double v) {*this += fromMilliseconds(v); return *this;}
|
|
||||||
|
|
||||||
//! Add to stored system time "v" microseconds
|
|
||||||
PISystemTime & addMicroseconds(double v) {*this += fromMicroseconds(v); return *this;}
|
|
||||||
|
|
||||||
//! Add to stored system time "v" nanoseconds
|
|
||||||
PISystemTime & addNanoseconds(double v) {*this += fromNanoseconds(v); return *this;}
|
|
||||||
|
|
||||||
|
|
||||||
//! Sleep for stored value. \warning Use this function to sleep for difference of system times or constructs system time.
|
|
||||||
//! If you call this function on system time returned from \a currentSystemTime() thread will be sleep almost forever.
|
|
||||||
void sleep() {piUSleep(piFloord(toMicroseconds()));} // wait self value, useful to wait some dT = (t1 - t0)
|
|
||||||
|
|
||||||
|
|
||||||
//! Returns copy of this system time with absolutely values of s and ns
|
|
||||||
PISystemTime abs() const {return PISystemTime(piAbsl(seconds), piAbsl(nanoseconds));}
|
|
||||||
|
|
||||||
//! Returns sum of this system time with "t"
|
|
||||||
PISystemTime operator +(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds += t.seconds; tt.nanoseconds += t.nanoseconds; tt.checkOverflows(); return tt;}
|
|
||||||
|
|
||||||
//! Returns difference between this system time and "t"
|
|
||||||
PISystemTime operator -(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds -= t.seconds; tt.nanoseconds -= t.nanoseconds; tt.checkOverflows(); return tt;}
|
|
||||||
|
|
||||||
//! Add to stored value system time "t"
|
|
||||||
PISystemTime & operator +=(const PISystemTime & t) {seconds += t.seconds; nanoseconds += t.nanoseconds; checkOverflows(); return *this;}
|
|
||||||
|
|
||||||
//! Subtract from stored value system time "t"
|
|
||||||
PISystemTime & operator -=(const PISystemTime & t) {seconds -= t.seconds; nanoseconds -= t.nanoseconds; checkOverflows(); return *this;}
|
|
||||||
|
|
||||||
|
|
||||||
//! Compare system times
|
|
||||||
bool operator ==(const PISystemTime & t) {return ((seconds == t.seconds) && (nanoseconds == t.nanoseconds));}
|
|
||||||
|
|
||||||
//! Compare system times
|
|
||||||
bool operator !=(const PISystemTime & t) {return ((seconds != t.seconds) || (nanoseconds != t.nanoseconds));}
|
|
||||||
|
|
||||||
//! Compare system times
|
|
||||||
bool operator >(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds > t.nanoseconds; return seconds > t.seconds;}
|
|
||||||
|
|
||||||
//! Compare system times
|
|
||||||
bool operator <(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds < t.nanoseconds; return seconds < t.seconds;}
|
|
||||||
|
|
||||||
//! Compare system times
|
|
||||||
bool operator >=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds >= t.nanoseconds; return seconds >= t.seconds;}
|
|
||||||
|
|
||||||
//! Compare system times
|
|
||||||
bool operator <=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds <= t.nanoseconds; return seconds <= t.seconds;}
|
|
||||||
|
|
||||||
|
|
||||||
//! Contructs system time from seconds "v"
|
|
||||||
static PISystemTime fromSeconds(double v) {long s = piFloord(v); return PISystemTime(s, (v - s) * 1000000000);}
|
|
||||||
|
|
||||||
//! Contructs system time from milliseconds "v"
|
|
||||||
static PISystemTime fromMilliseconds(double v) {long s = piFloord(v / 1000.); return PISystemTime(s, (v / 1000. - s) * 1000000000);}
|
|
||||||
|
|
||||||
//! Contructs system time from microseconds "v"
|
|
||||||
static PISystemTime fromMicroseconds(double v) {long s = piFloord(v / 1000000.); return PISystemTime(s, (v / 1000000. - s) * 1000000000);}
|
|
||||||
|
|
||||||
//! Contructs system time from nanoseconds "v"
|
|
||||||
static PISystemTime fromNanoseconds(double v) {long s = piFloord(v / 1000000000.); return PISystemTime(s, (v / 1000000000. - s) * 1000000000);}
|
|
||||||
|
|
||||||
|
|
||||||
//! Seconds of stored system time
|
|
||||||
long seconds;
|
|
||||||
|
|
||||||
//! Nanoseconds of stored system time
|
|
||||||
long nanoseconds;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void checkOverflows() {while (nanoseconds >= 1000000000) {nanoseconds -= 1000000000; seconds++;} while (nanoseconds < 0) {nanoseconds += 1000000000; seconds--;}}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//! \relatesalso PICout \relatesalso PIByteArray \brief Output operator to PICout
|
|
||||||
inline PICout operator <<(PICout s, const PISystemTime & v) {s.setControl(0, true); s.space(); s << "(" << v.seconds << " s, " << v.nanoseconds << " ns)"; s.restoreControl(); return s;}
|
|
||||||
|
|
||||||
//! \relatesalso PISystemTime \relatesalso PIByteArray \brief Output operator to PIByteArray
|
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PISystemTime & v) {s << v.seconds << v.nanoseconds; return s;}
|
|
||||||
|
|
||||||
//! \relatesalso PISystemTime \relatesalso PIByteArray \brief Input operator from PIByteArray
|
|
||||||
inline PIByteArray & operator >>(PIByteArray & s, PISystemTime & v) {s >> v.seconds >> v.nanoseconds; return s;}
|
|
||||||
|
|
||||||
struct PIP_EXPORT PITime {
|
|
||||||
PITime() {hours = minutes = seconds = milliseconds = 0;}
|
|
||||||
int milliseconds;
|
|
||||||
int seconds;
|
|
||||||
int minutes;
|
|
||||||
int hours;
|
|
||||||
PIString toString(const PIString & format = "h:mm:ss") const;
|
|
||||||
};
|
|
||||||
PIP_EXPORT bool operator ==(const PITime & t0, const PITime & t1);
|
|
||||||
PIP_EXPORT bool operator <(const PITime & t0, const PITime & t1);
|
|
||||||
PIP_EXPORT bool operator >(const PITime & t0, const PITime & t1);
|
|
||||||
inline bool operator !=(const PITime & t0, const PITime & t1) {return !(t0 == t1);}
|
|
||||||
inline bool operator <=(const PITime & t0, const PITime & t1) {return !(t0 > t1);}
|
|
||||||
inline bool operator >=(const PITime & t0, const PITime & t1) {return !(t0 < t1);}
|
|
||||||
|
|
||||||
struct PIP_EXPORT PIDate {
|
|
||||||
PIDate() {year = month = day = 0;}
|
|
||||||
int day;
|
|
||||||
int month;
|
|
||||||
int year;
|
|
||||||
PIString toString(const PIString & format = "d.MM.yyyy") const;
|
|
||||||
};
|
|
||||||
PIP_EXPORT bool operator ==(const PIDate & t0, const PIDate & t1);
|
|
||||||
PIP_EXPORT bool operator <(const PIDate & t0, const PIDate & t1);
|
|
||||||
PIP_EXPORT bool operator >(const PIDate & t0, const PIDate & t1);
|
|
||||||
inline bool operator !=(const PIDate & t0, const PIDate & t1) {return !(t0 == t1);}
|
|
||||||
inline bool operator <=(const PIDate & t0, const PIDate & t1) {return !(t0 > t1);}
|
|
||||||
inline bool operator >=(const PIDate & t0, const PIDate & t1) {return !(t0 < t1);}
|
|
||||||
|
|
||||||
struct PIP_EXPORT PIDateTime {
|
|
||||||
PIDateTime() {year = month = day = hours = minutes = seconds = 0;}
|
|
||||||
PIDateTime(const PITime & time) {year = month = day = 0; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
|
||||||
PIDateTime(const PIDate & date) {year = date.year; month = date.month; day = date.day; hours = minutes = seconds = milliseconds = 0;}
|
|
||||||
PIDateTime(const PIDate & date, const PITime & time) {year = date.year; month = date.month; day = date.day; hours = time.hours; minutes = time.minutes; seconds = time.seconds; milliseconds = time.milliseconds;}
|
|
||||||
int milliseconds;
|
|
||||||
int seconds;
|
|
||||||
int minutes;
|
|
||||||
int hours;
|
|
||||||
int day;
|
|
||||||
int month;
|
|
||||||
int year;
|
|
||||||
PIDateTime normalized() const {return PIDateTime::fromSecondSinceEpoch(toSecondSinceEpoch());}
|
|
||||||
void normalize() {*this = normalized();}
|
|
||||||
PIString toString(const PIString & format = "h:mm:ss d.MM.yyyy") const;
|
|
||||||
time_t toSecondSinceEpoch() const;
|
|
||||||
PISystemTime toSystemTime() const {return PISystemTime(int(toSecondSinceEpoch()), milliseconds * 1000000);}
|
|
||||||
void operator +=(const PIDateTime & d1) {year += d1.year; month += d1.month; day += d1.day; hours += d1.hours; minutes += d1.minutes; seconds += d1.seconds; normalize();}
|
|
||||||
void operator -=(const PIDateTime & d1) {year -= d1.year; month -= d1.month; day -= d1.day; hours -= d1.hours; minutes -= d1.minutes; seconds -= d1.seconds; normalize();}
|
|
||||||
static PIDateTime fromSecondSinceEpoch(const time_t sec);
|
|
||||||
static PIDateTime fromSystemTime(const PISystemTime & st) {PIDateTime dt = fromSecondSinceEpoch(st.seconds); dt.milliseconds = piClampi(st.nanoseconds / 1000000, 0, 999); return dt;}
|
|
||||||
};
|
|
||||||
inline PIDateTime operator +(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td += d1; return td.normalized();}
|
|
||||||
inline PIDateTime operator -(const PIDateTime & d0, const PIDateTime & d1) {PIDateTime td = d0; td -= d1; return td.normalized();}
|
|
||||||
PIP_EXPORT bool operator ==(const PIDateTime & t0, const PIDateTime & t1);
|
|
||||||
PIP_EXPORT bool operator <(const PIDateTime & t0, const PIDateTime & t1);
|
|
||||||
PIP_EXPORT bool operator >(const PIDateTime & t0, const PIDateTime & t1);
|
|
||||||
inline bool operator !=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 == t1);}
|
|
||||||
inline bool operator <=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 > t1);}
|
|
||||||
inline bool operator >=(const PIDateTime & t0, const PIDateTime & t1) {return !(t0 < t1);}
|
|
||||||
|
|
||||||
|
|
||||||
class PIP_EXPORT PITimer
|
class PIP_EXPORT PITimer
|
||||||
#ifndef PIP_TIMER_RT
|
#ifndef PIP_TIMER_RT
|
||||||
: public PIThread
|
: public PIThread
|
||||||
@@ -442,14 +266,4 @@ private:
|
|||||||
extern PITimer::TimerPool * pool;
|
extern PITimer::TimerPool * pool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PIP_EXPORT PITime currentTime();
|
|
||||||
PIP_EXPORT PIDate currentDate();
|
|
||||||
PIP_EXPORT PIDateTime currentDateTime();
|
|
||||||
|
|
||||||
//! \relatesalso PISystemTime \brief Returns current system time
|
|
||||||
PIP_EXPORT PISystemTime currentSystemTime();
|
|
||||||
PIP_EXPORT PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
|
||||||
PIP_EXPORT PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.toString() instead
|
|
||||||
PIP_EXPORT PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
|
||||||
|
|
||||||
#endif // PITIMER_H
|
#endif // PITIMER_H
|
||||||
|
|||||||
418
pivariant.cpp
Normal file
418
pivariant.cpp
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Variant type
|
||||||
|
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pivariant.h"
|
||||||
|
|
||||||
|
|
||||||
|
PIVariant::PIVariant() {
|
||||||
|
type_ = PIVariant::Invalid;
|
||||||
|
memset(_vraw, 0, __PIVARIANT_UNION_SIZE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIVariant::operator =(const PIVariant & v) {
|
||||||
|
type_ = v.type_;
|
||||||
|
memcpy(_vraw, v._vraw, __PIVARIANT_UNION_SIZE__);
|
||||||
|
_vbytearray = v._vbytearray;
|
||||||
|
_vbitarray = v._vbitarray;
|
||||||
|
_vstring = v._vstring;
|
||||||
|
_vstringlist = v._vstringlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool PIVariant::operator ==(const PIVariant & v) const {
|
||||||
|
if (type_ != v.type_) return false;
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint == v._vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong == v._vllong;
|
||||||
|
case PIVariant::Float: return _vfloat == v._vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble == v._vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble == v._vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd == _vvcomplexd(v);
|
||||||
|
case PIVariant::Complexld: return _vcomplexld == _vvcomplexld(v);
|
||||||
|
case PIVariant::BitArray: return _vbitarray == v._vbitarray;
|
||||||
|
case PIVariant::ByteArray: return _vbytearray == v._vbytearray;
|
||||||
|
case PIVariant::String: return _vstring == v._vstring;
|
||||||
|
case PIVariant::StringList: return _vstringlist == v._vstringlist;
|
||||||
|
case PIVariant::Time: return _vtime == _vvtime(v);
|
||||||
|
case PIVariant::Date: return _vdate == _vvdate(v);
|
||||||
|
case PIVariant::DateTime: return _vdatetime == _vvdatetime(v);
|
||||||
|
case PIVariant::SystemTime: return _vsystime == _vvsystime(v);
|
||||||
|
default: break;
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
|
||||||
|
PIString s = tname.trimmed().toLowerCase().replaceAll(" ", "");
|
||||||
|
if (s == "bool" || s == "boolean") return PIVariant::Bool;
|
||||||
|
if (s == "char" || s == "sbyte") return PIVariant::Char;
|
||||||
|
if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword") return PIVariant::Short;
|
||||||
|
if (s == "int" || s == "signed" || s == "signedint") return PIVariant::Int;
|
||||||
|
if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::Long;
|
||||||
|
if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword") return PIVariant::LLong;
|
||||||
|
if (s == "uchar" || s == "byte") return PIVariant::UChar;
|
||||||
|
if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word") return PIVariant::UShort;
|
||||||
|
if (s == "uint" || s == "unsigned" || s == "unsignedint") return PIVariant::UInt;
|
||||||
|
if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::ULong;
|
||||||
|
if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword") return PIVariant::ULLong;
|
||||||
|
if (s == "float") return PIVariant::Float;
|
||||||
|
if (s == "double" || s == "real") return PIVariant::Double;
|
||||||
|
if (s == "ldouble" || s == "longdouble") return PIVariant::LDouble;
|
||||||
|
if (s == "complexd" || s == "complex<double>") return PIVariant::Complexd;
|
||||||
|
if (s == "complexld" || s == "complex<ldouble>" || s == "complex<longdouble>") return PIVariant::Complexld;
|
||||||
|
if (s == "pibitarray" || s == "bitarray") return PIVariant::BitArray;
|
||||||
|
if (s == "pibytearray" || s == "bytearray" || s == "vector<uchar>" || s == "pivector<uchar>" || s == "vector<unsignedchar>" || s == "pivector<unsignedchar>" ||
|
||||||
|
s == "vector<char>" || s == "pivector<char>") return PIVariant::ByteArray;
|
||||||
|
if (s == "pistring" || s == "string") return PIVariant::String;
|
||||||
|
if (s == "pistringlist" || s == "vector<string>" || s == "vector<pistring>" || s == "pivector<string>" || s == "pivector<pistring>") return PIVariant::StringList;
|
||||||
|
if (s == "pitime" || s == "time") return PIVariant::Time;
|
||||||
|
if (s == "pidate" || s == "date") return PIVariant::Date;
|
||||||
|
if (s == "pidatetime" || s == "datetime") return PIVariant::DateTime;
|
||||||
|
if (s == "pisystemtime" || s == "systemtime") return PIVariant::SystemTime;
|
||||||
|
return PIVariant::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIVariant::typeName(PIVariant::Type type) {
|
||||||
|
switch (type) {
|
||||||
|
case PIVariant::Bool: return "Bool";
|
||||||
|
case PIVariant::Char: return "Char";
|
||||||
|
case PIVariant::UChar: return "UChar";
|
||||||
|
case PIVariant::Short: return "Short";
|
||||||
|
case PIVariant::UShort: return "UShort";
|
||||||
|
case PIVariant::Int: return "Int";
|
||||||
|
case PIVariant::UInt: return "UInt";
|
||||||
|
case PIVariant::Long: return "Long";
|
||||||
|
case PIVariant::ULong: return "ULong";
|
||||||
|
case PIVariant::LLong: return "LLong";
|
||||||
|
case PIVariant::ULLong: return "ULLong";
|
||||||
|
case PIVariant::Float: return "Float";
|
||||||
|
case PIVariant::Double: return "Double";
|
||||||
|
case PIVariant::LDouble: return "LDouble";
|
||||||
|
case PIVariant::Complexd: return "Complexd";
|
||||||
|
case PIVariant::Complexld: return "Complexld";
|
||||||
|
case PIVariant::BitArray: return "BitArray";
|
||||||
|
case PIVariant::ByteArray: return "ByteArray";
|
||||||
|
case PIVariant::String: return "String";
|
||||||
|
case PIVariant::StringList: return "StringList";
|
||||||
|
case PIVariant::Time: return "Time";
|
||||||
|
case PIVariant::Date: return "Date";
|
||||||
|
case PIVariant::DateTime: return "DateTime";
|
||||||
|
case PIVariant::SystemTime: return "SystemTime";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return "Invalid";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIVariant::toBool() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint != 0;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong != 0;
|
||||||
|
case PIVariant::Float: return _vfloat != 0;
|
||||||
|
case PIVariant::Double: return _vdouble != 0;
|
||||||
|
case PIVariant::LDouble: return _vldouble != 0;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real() != 0;
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real() != 0;
|
||||||
|
case PIVariant::String: return _vstring.toBool();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toBool();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIVariant::toInt() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong;
|
||||||
|
case PIVariant::Float: return _vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
|
case PIVariant::String: return _vstring.toInt();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toInt();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
llong PIVariant::toLLong() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong;
|
||||||
|
case PIVariant::Float: return _vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
|
case PIVariant::String: return _vstring.toLLong();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toLLong();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float PIVariant::toFloat() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong;
|
||||||
|
case PIVariant::Float: return _vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
|
case PIVariant::String: return _vstring.toFloat();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toFloat();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double PIVariant::toDouble() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong;
|
||||||
|
case PIVariant::Float: return _vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
|
case PIVariant::String: return _vstring.toDouble();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toDouble();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ldouble PIVariant::toLDouble() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong;
|
||||||
|
case PIVariant::Float: return _vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
|
case PIVariant::String: return _vstring.toLDouble();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toLDouble();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
complexd PIVariant::toComplexd() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong;
|
||||||
|
case PIVariant::Float: return _vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
|
case PIVariant::String: return _vstring.toDouble();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toDouble();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return complexd_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
complexld PIVariant::toComplexld() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool:
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return _vint;
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return _vllong;
|
||||||
|
case PIVariant::Float: return _vfloat;
|
||||||
|
case PIVariant::Double: return _vdouble;
|
||||||
|
case PIVariant::LDouble: return _vldouble;
|
||||||
|
case PIVariant::Complexd: return _vcomplexd.real();
|
||||||
|
case PIVariant::Complexld: return _vcomplexld.real();
|
||||||
|
case PIVariant::String: return _vstring.toLDouble();
|
||||||
|
case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toLDouble();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return complexld_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PITime PIVariant::toTime() const {
|
||||||
|
if (type_ == PIVariant::Time) return _vtime;
|
||||||
|
if (type_ == PIVariant::DateTime) return _vtime;
|
||||||
|
return PITime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIDate PIVariant::toDate() const {
|
||||||
|
if (type_ == PIVariant::Date) return _vdate;
|
||||||
|
if (type_ == PIVariant::DateTime) return *((PIDate*)(&(_vdatetime.day)));
|
||||||
|
return PIDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIDateTime PIVariant::toDateTime() const {
|
||||||
|
if (type_ == PIVariant::DateTime) return _vdatetime;
|
||||||
|
if (type_ == PIVariant::Time) return PIDateTime(_vtime);
|
||||||
|
if (type_ == PIVariant::Date) return PIDateTime(_vdate);
|
||||||
|
return PIDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PISystemTime PIVariant::toSystemTime() const {
|
||||||
|
if (type_ == PIVariant::SystemTime) return _vsystime;
|
||||||
|
return PISystemTime::fromSeconds(toDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PIVariant::toString() const {
|
||||||
|
switch (type_) {
|
||||||
|
case PIVariant::Bool: return _vint == 0 ? "false" : "true";
|
||||||
|
case PIVariant::Char:
|
||||||
|
case PIVariant::UChar:
|
||||||
|
case PIVariant::Short:
|
||||||
|
case PIVariant::UShort:
|
||||||
|
case PIVariant::Int:
|
||||||
|
case PIVariant::UInt:
|
||||||
|
case PIVariant::Long:
|
||||||
|
case PIVariant::ULong: return PIString::fromNumber(_vint);
|
||||||
|
case PIVariant::LLong:
|
||||||
|
case PIVariant::ULLong: return PIString::fromNumber(_vllong);
|
||||||
|
case PIVariant::Float: return PIString::fromNumber(_vfloat);
|
||||||
|
case PIVariant::Double: return PIString::fromNumber(_vdouble);
|
||||||
|
case PIVariant::LDouble: return PIString::fromNumber(_vldouble);
|
||||||
|
case PIVariant::Complexd: return "(" + PIString::fromNumber(_vcomplexd.real()) + "; " + PIString::fromNumber(_vcomplexd.imag()) + ")";
|
||||||
|
case PIVariant::Complexld: return "(" + PIString::fromNumber(_vcomplexld.real()) + "; " + PIString::fromNumber(_vcomplexld.imag()) + ")";
|
||||||
|
case PIVariant::BitArray: return PIString::fromNumber(_vbitarray.bitSize()) + " bits";
|
||||||
|
case PIVariant::ByteArray: return PIString::fromNumber(_vbytearray.size()) + " bytes";
|
||||||
|
case PIVariant::String: return _vstring;
|
||||||
|
case PIVariant::StringList: return "(" + _vstringlist.join("; ") + ")";
|
||||||
|
case PIVariant::Time: return _vtime.toString();
|
||||||
|
case PIVariant::Date: return _vdate.toString();
|
||||||
|
case PIVariant::DateTime: return _vdatetime.toString();
|
||||||
|
case PIVariant::SystemTime: return "(" + PIString::fromNumber(_vsystime.seconds) + " s, " + PIString::fromNumber(_vsystime.nanoseconds) + " ns)";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIStringList PIVariant::toStringList() const {
|
||||||
|
if (type_ == PIVariant::StringList) return _vstringlist;
|
||||||
|
return PIStringList(toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIBitArray PIVariant::toBitArray() const {
|
||||||
|
if (type_ == PIVariant::BitArray) return _vbitarray;
|
||||||
|
return PIBitArray(ullong(toLLong()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray PIVariant::toByteArray() const {
|
||||||
|
if (type_ == PIVariant::ByteArray) return _vbytearray;
|
||||||
|
return PIByteArray();
|
||||||
|
}
|
||||||
215
pivariant.h
Normal file
215
pivariant.h
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/*! \file pivariant.h
|
||||||
|
* \brief Variant type
|
||||||
|
*
|
||||||
|
* This file declares PIVariant
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Variant type
|
||||||
|
Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIVARIANT_H
|
||||||
|
#define PIVARIANT_H
|
||||||
|
|
||||||
|
#include "pistring.h"
|
||||||
|
#include "pibitarray.h"
|
||||||
|
#include "pitime.h"
|
||||||
|
#include "pimath.h"
|
||||||
|
|
||||||
|
#define __PIVARIANT_UNION_SIZE__ 32
|
||||||
|
|
||||||
|
#define _vcomplexd (*((complexd*)_vraw))
|
||||||
|
#define _vcomplexld (*((complexld*)_vraw))
|
||||||
|
#define _vtime (*((PITime*)_vraw))
|
||||||
|
#define _vdate (*((PIDate*)_vraw))
|
||||||
|
#define _vdatetime (*((PIDateTime*)_vraw))
|
||||||
|
#define _vsystime (*((PISystemTime*)_vraw))
|
||||||
|
|
||||||
|
#define _vvcomplexd(v) (*((complexd*)v._vraw))
|
||||||
|
#define _vvcomplexld(v) (*((complexld*)v._vraw))
|
||||||
|
#define _vvtime(v) (*((PITime*)v._vraw))
|
||||||
|
#define _vvdate(v) (*((PIDate*)v._vraw))
|
||||||
|
#define _vvdatetime(v) (*((PIDateTime*)v._vraw))
|
||||||
|
#define _vvsystime(v) (*((PISystemTime*)v._vraw))
|
||||||
|
|
||||||
|
class PIP_EXPORT PIVariant {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Invalid = 0,
|
||||||
|
Bool,
|
||||||
|
Char,
|
||||||
|
UChar,
|
||||||
|
Short,
|
||||||
|
UShort,
|
||||||
|
Int,
|
||||||
|
UInt,
|
||||||
|
Long,
|
||||||
|
ULong,
|
||||||
|
LLong,
|
||||||
|
ULLong,
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
LDouble,
|
||||||
|
Complexd,
|
||||||
|
Complexld,
|
||||||
|
BitArray,
|
||||||
|
ByteArray,
|
||||||
|
String,
|
||||||
|
StringList,
|
||||||
|
Time,
|
||||||
|
Date,
|
||||||
|
DateTime,
|
||||||
|
SystemTime/*,
|
||||||
|
Custom = 0xFF*/
|
||||||
|
};
|
||||||
|
|
||||||
|
PIVariant();
|
||||||
|
PIVariant(const char * v) {setValue(PIString(v));}
|
||||||
|
PIVariant(const bool v) {setValue(v);}
|
||||||
|
PIVariant(const char v) {setValue(v);}
|
||||||
|
PIVariant(const uchar v) {setValue(v);}
|
||||||
|
PIVariant(const short v) {setValue(v);}
|
||||||
|
PIVariant(const ushort v) {setValue(v);}
|
||||||
|
PIVariant(const int & v) {setValue(v);}
|
||||||
|
PIVariant(const uint & v) {setValue(v);}
|
||||||
|
PIVariant(const long & v) {setValue(v);}
|
||||||
|
PIVariant(const ulong & v) {setValue(v);}
|
||||||
|
PIVariant(const llong & v) {setValue(v);}
|
||||||
|
PIVariant(const ullong & v) {setValue(v);}
|
||||||
|
PIVariant(const float & v) {setValue(v);}
|
||||||
|
PIVariant(const double & v) {setValue(v);}
|
||||||
|
PIVariant(const ldouble & v) {setValue(v);}
|
||||||
|
PIVariant(const complexd & v) {setValue(v);}
|
||||||
|
PIVariant(const complexld & v) {setValue(v);}
|
||||||
|
PIVariant(const PIBitArray & v) {setValue(v);}
|
||||||
|
PIVariant(const PIByteArray & v) {setValue(v);}
|
||||||
|
PIVariant(const PIString & v) {setValue(v);}
|
||||||
|
PIVariant(const PIStringList & v) {setValue(v);}
|
||||||
|
PIVariant(const PITime & v) {setValue(v);}
|
||||||
|
PIVariant(const PIDate & v) {setValue(v);}
|
||||||
|
PIVariant(const PIDateTime & v) {setValue(v);}
|
||||||
|
PIVariant(const PISystemTime & v) {setValue(v);}
|
||||||
|
|
||||||
|
void setValue(const char * v) {setValue(PIString(v));}
|
||||||
|
void setValue(const bool v) {type_ = PIVariant::Bool; _vint = (v ? 1 : 0);}
|
||||||
|
void setValue(const char v) {type_ = PIVariant::Char; _vint = v;}
|
||||||
|
void setValue(const uchar v) {type_ = PIVariant::UChar; _vint = v;}
|
||||||
|
void setValue(const short v) {type_ = PIVariant::Short; _vint = v;}
|
||||||
|
void setValue(const ushort v) {type_ = PIVariant::UShort; _vint = v;}
|
||||||
|
void setValue(const int & v) {type_ = PIVariant::Int; _vint = v;}
|
||||||
|
void setValue(const uint & v) {type_ = PIVariant::UInt; _vint = v;}
|
||||||
|
void setValue(const long & v) {type_ = PIVariant::Long; _vint = v;}
|
||||||
|
void setValue(const ulong & v) {type_ = PIVariant::ULong; _vint = v;}
|
||||||
|
void setValue(const llong & v) {type_ = PIVariant::LLong; _vllong = v;}
|
||||||
|
void setValue(const ullong & v) {type_ = PIVariant::ULLong; _vllong = v;}
|
||||||
|
void setValue(const float & v) {type_ = PIVariant::Float; _vfloat = v;}
|
||||||
|
void setValue(const double & v) {type_ = PIVariant::Double; _vdouble = v;}
|
||||||
|
void setValue(const ldouble & v) {type_ = PIVariant::LDouble; _vldouble = v;}
|
||||||
|
void setValue(const complexd & v) {type_ = PIVariant::Complexd; _vcomplexd = v;}
|
||||||
|
void setValue(const complexld & v) {type_ = PIVariant::Complexld; _vcomplexld = v;}
|
||||||
|
void setValue(const PIBitArray & v) {type_ = PIVariant::BitArray; _vbitarray = v;}
|
||||||
|
void setValue(const PIByteArray & v) {type_ = PIVariant::ByteArray; _vbytearray = v;}
|
||||||
|
void setValue(const PIString & v) {type_ = PIVariant::String; _vstring = v;}
|
||||||
|
void setValue(const PIStringList & v) {type_ = PIVariant::StringList; _vstringlist = v;}
|
||||||
|
void setValue(const PITime & v) {type_ = PIVariant::Time; _vtime = v;}
|
||||||
|
void setValue(const PIDate & v) {type_ = PIVariant::Date; _vdate = v;}
|
||||||
|
void setValue(const PIDateTime & v) {type_ = PIVariant::DateTime; _vdatetime = v;}
|
||||||
|
void setValue(const PISystemTime & v) {type_ = PIVariant::SystemTime; _vsystime = v;}
|
||||||
|
|
||||||
|
bool toBool() const;
|
||||||
|
int toInt() const;
|
||||||
|
llong toLLong() const;
|
||||||
|
float toFloat() const;
|
||||||
|
double toDouble() const;
|
||||||
|
ldouble toLDouble() const;
|
||||||
|
complexd toComplexd() const;
|
||||||
|
complexld toComplexld() const;
|
||||||
|
PITime toTime() const;
|
||||||
|
PIDate toDate() const;
|
||||||
|
PIDateTime toDateTime() const;
|
||||||
|
PISystemTime toSystemTime() const;
|
||||||
|
PIString toString() const;
|
||||||
|
PIStringList toStringList() const;
|
||||||
|
PIBitArray toBitArray() const;
|
||||||
|
PIByteArray toByteArray() const;
|
||||||
|
|
||||||
|
void operator =(const PIVariant & v);
|
||||||
|
void operator =(const char * v) {setValue(PIString(v));}
|
||||||
|
void operator =(const bool v) {setValue(v);}
|
||||||
|
void operator =(const char v) {setValue(v);}
|
||||||
|
void operator =(const uchar v) {setValue(v);}
|
||||||
|
void operator =(const short v) {setValue(v);}
|
||||||
|
void operator =(const ushort v) {setValue(v);}
|
||||||
|
void operator =(const int & v) {setValue(v);}
|
||||||
|
void operator =(const uint & v) {setValue(v);}
|
||||||
|
void operator =(const long & v) {setValue(v);}
|
||||||
|
void operator =(const ulong & v) {setValue(v);}
|
||||||
|
void operator =(const llong & v) {setValue(v);}
|
||||||
|
void operator =(const ullong & v) {setValue(v);}
|
||||||
|
void operator =(const float & v) {setValue(v);}
|
||||||
|
void operator =(const double & v) {setValue(v);}
|
||||||
|
void operator =(const ldouble & v) {setValue(v);}
|
||||||
|
void operator =(const complexd & v) {setValue(v);}
|
||||||
|
void operator =(const complexld & v) {setValue(v);}
|
||||||
|
void operator =(const PIBitArray & v) {setValue(v);}
|
||||||
|
void operator =(const PIByteArray & v) {setValue(v);}
|
||||||
|
void operator =(const PIString & v) {setValue(v);}
|
||||||
|
void operator =(const PIStringList & v) {setValue(v);}
|
||||||
|
void operator =(const PITime & v) {setValue(v);}
|
||||||
|
void operator =(const PIDate & v) {setValue(v);}
|
||||||
|
void operator =(const PIDateTime & v) {setValue(v);}
|
||||||
|
void operator =(const PISystemTime & v) {setValue(v);}
|
||||||
|
|
||||||
|
bool operator ==(const PIVariant & v) const;
|
||||||
|
bool operator !=(const PIVariant & v) const {return !(*this == v);}
|
||||||
|
|
||||||
|
PIVariant::Type type() const {return type_;}
|
||||||
|
PIString typeName() const {return typeName(type_);}
|
||||||
|
|
||||||
|
bool isValid() const {return type_ != PIVariant::Invalid;}
|
||||||
|
|
||||||
|
static PIVariant::Type typeFromName(const PIString & tname);
|
||||||
|
static PIString typeName(PIVariant::Type type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
union {
|
||||||
|
int _vint;
|
||||||
|
llong _vllong;
|
||||||
|
float _vfloat;
|
||||||
|
double _vdouble;
|
||||||
|
ldouble _vldouble;
|
||||||
|
uchar _vraw[__PIVARIANT_UNION_SIZE__];
|
||||||
|
/*complexd _vcomplexd;
|
||||||
|
complexld _vcomplexld;
|
||||||
|
PITime _vtime;
|
||||||
|
PIDate _vdate;
|
||||||
|
PIDateTime _vdatetime;
|
||||||
|
PISystemTime _vsystime;*/
|
||||||
|
};
|
||||||
|
PIBitArray _vbitarray;
|
||||||
|
PIByteArray _vbytearray;
|
||||||
|
PIString _vstring;
|
||||||
|
PIStringList _vstringlist;
|
||||||
|
PIVariant::Type type_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline PICout operator <<(PICout s, const PIVariant & v) {s.space(); s.setControl(0, true); s << "PIVariant(" << PIVariant::typeName(v.type()) << ", " << v.toString() << ")"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PIVARIANT_H
|
||||||
318
pivector.h
318
pivector.h
@@ -1,7 +1,7 @@
|
|||||||
/*! \file picontainers.h
|
/*! \file pivector.h
|
||||||
* \brief Dynamic array of any type
|
* \brief Dynamic array of any type
|
||||||
*
|
*
|
||||||
* This file declare PIVector
|
* This file declares PIVector
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
@@ -34,26 +34,27 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class PIVector {
|
class PIVector {
|
||||||
public:
|
public:
|
||||||
PIVector(): __piv_data__(0), __piv_size__(0), __piv_rsize__(0) {
|
PIVector(): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
//printf("new vector 1 %p (%s) ... !{\n", this, typeid(T).name());
|
//printf("new vector 1 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
//printf("(s=%d, d=%p) }!\n", int(__piv_size__), __piv_data__);
|
//printf("(s=%d, d=%p) }!\n", int(piv_size), piv_data);
|
||||||
}
|
}
|
||||||
PIVector(const PIVector<T> & other): __piv_data__(0), __piv_size__(0), __piv_rsize__(0) {
|
PIVector(const PIVector<T> & other): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
//printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
|
//printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
alloc(other.__piv_size__);
|
alloc(other.piv_size);
|
||||||
for (ullong i = 0; i < __piv_size__; ++i)
|
for (size_t i = 0; i < piv_size; ++i)
|
||||||
new(__piv_data__ + i)T(other.__piv_data__[i]);
|
new(piv_data + i)T(other.piv_data[i]);
|
||||||
//printf("(s=%d, d=%p) }!\n", int(__piv_size__), __piv_data__);
|
//printf("(s=%d, d=%p) }!\n", int(piv_size), piv_data);
|
||||||
}
|
}
|
||||||
PIVector(ullong __piv_size__, const T & f = T()): __piv_data__(0), __piv_size__(0), __piv_rsize__(0) {
|
PIVector(size_t piv_size, const T & f = T()): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
//printf("new vector 3 %p (%s) ... !{\n", this, typeid(T).name());
|
//printf("new vector 3 %p (%s) ... !{\n", this, typeid(T).name());
|
||||||
resize(__piv_size__, f);
|
resize(piv_size, f);
|
||||||
//printf("(s=%d, d=%p) }!\n", int(__piv_size__), __piv_data__);
|
//printf("(s=%d, d=%p) }!\n", int(piv_size), piv_data);
|
||||||
}
|
}
|
||||||
~PIVector() {
|
~PIVector() {
|
||||||
//printf("delete vector %p (%s) (s=%d, d=%p) ... ~{\n", this, typeid(T).name(), int(__piv_size__), __piv_data__);
|
//printf("delete vector %p (%s) (s=%d, d=%p) ... ~{\n", this, typeid(T).name(), int(piv_size), piv_data);
|
||||||
deleteT(__piv_data__, __piv_size__);
|
deleteT(piv_data, piv_size);
|
||||||
dealloc();
|
dealloc();
|
||||||
|
//deleteRaw(piv_tdata);
|
||||||
_reset();
|
_reset();
|
||||||
//printf("}~\n");
|
//printf("}~\n");
|
||||||
}
|
}
|
||||||
@@ -61,25 +62,25 @@ public:
|
|||||||
PIVector<T> & operator =(const PIVector<T> & other) {
|
PIVector<T> & operator =(const PIVector<T> & other) {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
bool tj, oj;
|
bool tj, oj;
|
||||||
tj = (__piv_size__ != 0 && __piv_data__ == 0);// || (__piv_size__ == 0 && __piv_data__ != 0);
|
tj = (piv_size != 0 && piv_data == 0);// || (piv_size == 0 && piv_data != 0);
|
||||||
oj = (other.__piv_size__ != 0 && other.__piv_data__ == 0);// || (other.__piv_size__ == 0 && other.__piv_data__ != 0);
|
oj = (other.piv_size != 0 && other.piv_data == 0);// || (other.piv_size == 0 && other.piv_data != 0);
|
||||||
//printf("operator= (%p = %p) (s=%d, d=%p, o.s=%d, o.d=%p) (%d, %d) ... o[\n", this, &other, int(__piv_size__), __piv_data__, int(other.__piv_size__), other.__piv_data__, int(tj), int(oj));
|
//printf("operator= (%p = %p) (s=%d, d=%p, o.s=%d, o.d=%p) (%d, %d) ... o[\n", this, &other, int(piv_size), piv_data, int(other.piv_size), other.piv_data, int(tj), int(oj));
|
||||||
if (tj) {
|
if (tj) {
|
||||||
printf("JUNK this\n");
|
printf("JUNK this\n");
|
||||||
_reset();
|
_reset();
|
||||||
} else {
|
} else {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
/*if (__piv_size__ == other.__piv_size__) {
|
/*if (piv_size == other.piv_size) {
|
||||||
for (ullong i = 0; i < __piv_size__; ++i)
|
for (size_t i = 0; i < piv_size; ++i)
|
||||||
__piv_data__[i] = other.__piv_data__[i];
|
piv_data[i] = other.piv_data[i];
|
||||||
return *this;
|
return *this;
|
||||||
}*/
|
}*/
|
||||||
if (!oj) {
|
if (!oj) {
|
||||||
alloc(other.__piv_size__);
|
alloc(other.piv_size);
|
||||||
//zeroRaw(__piv_data__, __piv_size__);
|
//zeroRaw(piv_data, piv_size);
|
||||||
for (ullong i = 0; i < __piv_size__; ++i)
|
for (size_t i = 0; i < piv_size; ++i)
|
||||||
new(__piv_data__ + i)T(other.__piv_data__[i]); //__piv_data__[i] = other.__piv_data__[i];
|
new(piv_data + i)T(other.piv_data[i]); //piv_data[i] = other.piv_data[i];
|
||||||
} else {
|
} else {
|
||||||
printf("JUNK other\n");
|
printf("JUNK other\n");
|
||||||
}
|
}
|
||||||
@@ -92,9 +93,9 @@ public:
|
|||||||
class iterator {
|
class iterator {
|
||||||
friend class PIVector<T>;
|
friend class PIVector<T>;
|
||||||
private:
|
private:
|
||||||
iterator(PIVector<T> * v, ullong p): parent(v), pos(p) {}
|
iterator(PIVector<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
PIVector<T> * parent;
|
PIVector<T> * parent;
|
||||||
ullong pos;
|
size_t pos;
|
||||||
public:
|
public:
|
||||||
iterator(): parent(0) {}
|
iterator(): parent(0) {}
|
||||||
T & operator *() {return (*parent)[pos];}
|
T & operator *() {return (*parent)[pos];}
|
||||||
@@ -110,9 +111,9 @@ public:
|
|||||||
class const_iterator {
|
class const_iterator {
|
||||||
friend class PIVector<T>;
|
friend class PIVector<T>;
|
||||||
private:
|
private:
|
||||||
const_iterator(const PIVector<T> * v, ullong p): parent(v), pos(p) {}
|
const_iterator(const PIVector<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
const PIVector<T> * parent;
|
const PIVector<T> * parent;
|
||||||
ullong pos;
|
size_t pos;
|
||||||
public:
|
public:
|
||||||
const_iterator(): parent(0) {}
|
const_iterator(): parent(0) {}
|
||||||
//T & operator *() {return (*parent)[pos];}
|
//T & operator *() {return (*parent)[pos];}
|
||||||
@@ -128,9 +129,9 @@ public:
|
|||||||
class reverse_iterator {
|
class reverse_iterator {
|
||||||
friend class PIVector<T>;
|
friend class PIVector<T>;
|
||||||
private:
|
private:
|
||||||
reverse_iterator(PIVector<T> * v, ullong p): parent(v), pos(p) {}
|
reverse_iterator(PIVector<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
PIVector<T> * parent;
|
PIVector<T> * parent;
|
||||||
ullong pos;
|
size_t pos;
|
||||||
public:
|
public:
|
||||||
reverse_iterator(): parent(0) {}
|
reverse_iterator(): parent(0) {}
|
||||||
T & operator *() {return (*parent)[pos];}
|
T & operator *() {return (*parent)[pos];}
|
||||||
@@ -146,9 +147,9 @@ public:
|
|||||||
class const_reverse_iterator {
|
class const_reverse_iterator {
|
||||||
friend class PIVector<T>;
|
friend class PIVector<T>;
|
||||||
private:
|
private:
|
||||||
const_reverse_iterator(const PIVector<T> * v, ullong p): parent(v), pos(p) {}
|
const_reverse_iterator(const PIVector<T> * v, size_t p): parent(v), pos(p) {}
|
||||||
const PIVector<T> * parent;
|
const PIVector<T> * parent;
|
||||||
ullong pos;
|
size_t pos;
|
||||||
public:
|
public:
|
||||||
const_reverse_iterator(): parent(0) {}
|
const_reverse_iterator(): parent(0) {}
|
||||||
//T & operator *() {return (*parent)[pos];}
|
//T & operator *() {return (*parent)[pos];}
|
||||||
@@ -162,129 +163,125 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
iterator begin() {return iterator(this, 0);}
|
iterator begin() {return iterator(this, 0);}
|
||||||
iterator end() {return iterator(this, __piv_size__);}
|
iterator end() {return iterator(this, piv_size);}
|
||||||
const_iterator begin() const {return const_iterator(this, 0);}
|
const_iterator begin() const {return const_iterator(this, 0);}
|
||||||
const_iterator end() const {return const_iterator(this, __piv_size__);}
|
const_iterator end() const {return const_iterator(this, piv_size);}
|
||||||
reverse_iterator rbegin() {return reverse_iterator(this, __piv_size__ - 1);}
|
reverse_iterator rbegin() {return reverse_iterator(this, piv_size - 1);}
|
||||||
reverse_iterator rend() {return reverse_iterator(this, -1);}
|
reverse_iterator rend() {return reverse_iterator(this, -1);}
|
||||||
const_reverse_iterator rbegin() const {return const_reverse_iterator(this, __piv_size__ - 1);}
|
const_reverse_iterator rbegin() const {return const_reverse_iterator(this, piv_size - 1);}
|
||||||
const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
||||||
|
|
||||||
ullong size() const {return __piv_size__;}
|
size_t size() const {return piv_size;}
|
||||||
int size_s() const {return __piv_size__;}
|
ssize_t size_s() const {return piv_size;}
|
||||||
ullong length() const {return __piv_size__;}
|
size_t length() const {return piv_size;}
|
||||||
bool isEmpty() const {return (__piv_size__ == 0);}
|
bool isEmpty() const {return (piv_size == 0);}
|
||||||
|
|
||||||
T & operator [](ullong index) {return __piv_data__[index];}
|
T & operator [](size_t index) {return piv_data[index];}
|
||||||
T & at(ullong index) {return __piv_data__[index];}
|
T & at(size_t index) {return piv_data[index];}
|
||||||
const T & operator [](ullong index) const {return __piv_data__[index];}
|
const T & operator [](size_t index) const {return piv_data[index];}
|
||||||
const T & at(ullong index) const {return __piv_data__[index];}
|
const T & at(size_t index) const {return piv_data[index];}
|
||||||
T & back() {return __piv_data__[__piv_size__ - 1];}
|
T & back() {return piv_data[piv_size - 1];}
|
||||||
const T & back() const {return __piv_data__[__piv_size__ - 1];}
|
const T & back() const {return piv_data[piv_size - 1];}
|
||||||
T & front() {return __piv_data__[0];}
|
T & front() {return piv_data[0];}
|
||||||
const T & front() const {return __piv_data__[0];}
|
const T & front() const {return piv_data[0];}
|
||||||
bool operator ==(const PIVector<T> & t) const {if (__piv_size__ != t.__piv_size__) return false; for (ullong i = 0; i < __piv_size__; ++i) if (t[i] != __piv_data__[i]) return false; return true;}
|
bool operator ==(const PIVector<T> & t) const {if (piv_size != t.piv_size) return false; for (size_t i = 0; i < piv_size; ++i) if (t[i] != piv_data[i]) return false; return true;}
|
||||||
bool operator !=(const PIVector<T> & t) const {if (__piv_size__ != t.__piv_size__) return true; for (ullong i = 0; i < __piv_size__; ++i) if (t[i] != __piv_data__[i]) return true; return false;}
|
bool operator !=(const PIVector<T> & t) const {if (piv_size != t.piv_size) return true; for (size_t i = 0; i < piv_size; ++i) if (t[i] != piv_data[i]) return true; return false;}
|
||||||
bool contains(const T & v) const {for (ullong i = 0; i < __piv_size__; ++i) if (v == __piv_data__[i]) return true; return false;}
|
bool contains(const T & v) const {for (size_t i = 0; i < piv_size; ++i) if (v == piv_data[i]) return true; return false;}
|
||||||
int etries(const T & v) const {int ec = 0; for (ullong i = 0; i < __piv_size__; ++i) if (v == __piv_data__[i]) ++ec; return ec;}
|
int etries(const T & v) const {int ec = 0; for (size_t i = 0; i < piv_size; ++i) if (v == piv_data[i]) ++ec; return ec;}
|
||||||
|
|
||||||
T * data(ullong index = 0) {return &(__piv_data__[index]);}
|
T * data(size_t index = 0) {return &(piv_data[index]);}
|
||||||
const T * data(ullong index = 0) const {return &(__piv_data__[index]);}
|
const T * data(size_t index = 0) const {return &(piv_data[index]);}
|
||||||
PIVector<T> & clear() {resize(0); return *this;}
|
PIVector<T> & clear() {resize(0); return *this;}
|
||||||
PIVector<T> & fill(const T & f = T()) {
|
PIVector<T> & fill(const T & f = T()) {
|
||||||
//if (sizeof(T) == 1) memset(__piv_data__, f, __piv_size__);
|
//if (sizeof(T) == 1) memset(piv_data, f, piv_size);
|
||||||
deleteT(__piv_data__, __piv_size__);
|
deleteT(piv_data, piv_size);
|
||||||
//zeroRaw(__piv_data__, __piv_size__);
|
//zeroRaw(piv_data, piv_size);
|
||||||
for (ullong i = 0; i < __piv_size__; ++i)
|
for (size_t i = 0; i < piv_size; ++i)
|
||||||
new(__piv_data__ + i)T(f);
|
new(piv_data + i)T(f);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
||||||
PIVector<T> & resize(ullong new_size, const T & f = T()) {
|
PIVector<T> & assign(size_t new_size, const T & f) {resize(new_size); fill(f);}
|
||||||
if (new_size < __piv_size__) {
|
PIVector<T> & resize(size_t new_size, const T & f = T()) {
|
||||||
T * de = &(__piv_data__[new_size]);
|
if (new_size < piv_size) {
|
||||||
deleteT(de, __piv_size__ - new_size);
|
T * de = &(piv_data[new_size]);
|
||||||
__piv_size__ = new_size;
|
deleteT(de, piv_size - new_size);
|
||||||
|
piv_size = new_size;
|
||||||
}
|
}
|
||||||
if (new_size > __piv_size__) {
|
if (new_size > piv_size) {
|
||||||
ullong os = __piv_size__;
|
size_t os = piv_size;
|
||||||
alloc(new_size);
|
alloc(new_size);
|
||||||
//if (sizeof(T) == 1) memset(&(__piv_data__[os]), f, ds);
|
//if (sizeof(T) == 1) memset(&(piv_data[os]), f, ds);
|
||||||
//zeroRaw(&(__piv_data__[os]), new_size - os);
|
//zeroRaw(&(piv_data[os]), new_size - os);
|
||||||
for (ullong i = os; i < new_size; ++i) new(__piv_data__ + i)T(f);
|
for (size_t i = os; i < new_size; ++i) new(piv_data + i)T(f);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
PIVector<T> & reserve(ullong new_size) {if (new_size <= __piv_rsize__) return *this; ullong os = __piv_size__; alloc(new_size); __piv_size__ = os; return *this;}
|
PIVector<T> & reserve(size_t new_size) {if (new_size <= piv_rsize) return *this; size_t os = piv_size; alloc(new_size); piv_size = os; return *this;}
|
||||||
|
|
||||||
PIVector<T> & insert(ullong index, const T & v = T()) {
|
PIVector<T> & insert(size_t index, const T & v = T()) {
|
||||||
alloc(__piv_size__ + 1);
|
alloc(piv_size + 1);
|
||||||
if (index < __piv_size__ - 1) {
|
if (index < piv_size - 1) {
|
||||||
ullong os = __piv_size__ - index - 1;
|
size_t os = piv_size - index - 1;
|
||||||
T * pd = newRaw(os);
|
memmove(&(piv_data[index + 1]), &(piv_data[index]), os * sizeof(T));
|
||||||
memcpy(pd, &(__piv_data__[index]), os * sizeof(T));
|
|
||||||
memcpy(&(__piv_data__[index + 1]), pd, os * sizeof(T));
|
|
||||||
deleteRaw(pd);
|
|
||||||
}
|
}
|
||||||
//zeroRaw(&(__piv_data__[index]), 1);
|
//zeroRaw(&(piv_data[index]), 1);
|
||||||
new(__piv_data__ + index)T(v);
|
new(piv_data + index)T(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIVector<T> & remove(ullong index, ullong count = 1) {
|
PIVector<T> & remove(size_t index, size_t count = 1) {
|
||||||
if (index + count >= __piv_size__) {
|
if (index + count >= piv_size) {
|
||||||
resize(index);
|
resize(index);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ullong os = __piv_size__ - index - count;
|
size_t os = piv_size - index - count;
|
||||||
T * pd = newRaw(os), * de = &(__piv_data__[index]);
|
T * de = &(piv_data[index]);
|
||||||
deleteT(de, count);
|
deleteT(de, count);
|
||||||
memcpy(pd, &(__piv_data__[index + count]), os * sizeof(T));
|
memmove(&(piv_data[index]), &(piv_data[index + count]), os * sizeof(T));
|
||||||
memcpy(&(__piv_data__[index]), pd, os * sizeof(T));
|
piv_size -= count;
|
||||||
deleteRaw(pd);
|
|
||||||
__piv_size__ -= count;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(PIVector<T> & other) {
|
void swap(PIVector<T> & other) {
|
||||||
piSwap<T*>(__piv_data__, other.__piv_data__);
|
piSwap<T*>(piv_data, other.piv_data);
|
||||||
piSwap<ullong>(__piv_size__, other.__piv_size__);
|
piSwap<size_t>(piv_size, other.piv_size);
|
||||||
piSwap<ullong>(__piv_rsize__, other.__piv_rsize__);
|
piSwap<size_t>(piv_rsize, other.piv_rsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*CompareFunc)(const T * , const T * );
|
typedef int (*CompareFunc)(const T * , const T * );
|
||||||
static int compare_func(const T * t0, const T * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);}
|
static int compare_func(const T * t0, const T * t1) {return (*t0) < (*t1) ? -1 : ((*t0) == (*t1) ? 0 : 1);}
|
||||||
PIVector<T> & sort(CompareFunc compare = compare_func) {qsort(__piv_data__, __piv_size__, sizeof(T), (int(*)(const void * , const void * ))compare); return *this;}
|
PIVector<T> & sort(CompareFunc compare = compare_func) {qsort(piv_data, piv_size, sizeof(T), (int(*)(const void * , const void * ))compare); return *this;}
|
||||||
|
|
||||||
PIVector<T> & enlarge(llong __piv_size__) {llong ns = size_s() + __piv_size__; if (ns <= 0) clear(); else resize(ullong(ns)); return *this;}
|
PIVector<T> & enlarge(llong piv_size) {llong ns = size_s() + piv_size; if (ns <= 0) clear(); else resize(size_t(ns)); return *this;}
|
||||||
|
|
||||||
PIVector<T> & removeOne(const T & v) {for (ullong i = 0; i < __piv_size__; ++i) if (__piv_data__[i] == v) {remove(i); return *this;} return *this;}
|
PIVector<T> & removeOne(const T & v) {for (size_t i = 0; i < piv_size; ++i) if (piv_data[i] == v) {remove(i); return *this;} return *this;}
|
||||||
PIVector<T> & removeAll(const T & v) {for (ullong i = 0; i < __piv_size__; ++i) if (__piv_data__[i] == v) {remove(i); --i;} return *this;}
|
PIVector<T> & removeAll(const T & v) {for (llong i = 0; i < piv_size; ++i) if (piv_data[i] == v) {remove(i); --i;} return *this;}
|
||||||
|
|
||||||
PIVector<T> & push_back(const T & v) {alloc(__piv_size__ + 1); new(__piv_data__ + __piv_size__ - 1)T(v); return *this;}
|
PIVector<T> & push_back(const T & v) {alloc(piv_size + 1); new(piv_data + piv_size - 1)T(v); return *this;}
|
||||||
PIVector<T> & append(const T & v) {return push_back(v);}
|
PIVector<T> & append(const T & v) {return push_back(v);}
|
||||||
PIVector<T> & operator <<(const T & v) {return push_back(v);}
|
PIVector<T> & operator <<(const T & v) {return push_back(v);}
|
||||||
|
|
||||||
PIVector<T> & push_front(const T & v) {insert(0, v); return *this;}
|
PIVector<T> & push_front(const T & v) {insert(0, v); return *this;}
|
||||||
PIVector<T> & prepend(const T & v) {return push_front(v);}
|
PIVector<T> & prepend(const T & v) {return push_front(v);}
|
||||||
|
|
||||||
PIVector<T> & pop_back() {if (__piv_size__ == 0) return *this; resize(__piv_size__ - 1); return *this;}
|
PIVector<T> & pop_back() {if (piv_size == 0) return *this; resize(piv_size - 1); return *this;}
|
||||||
PIVector<T> & pop_front() {if (__piv_size__ == 0) return *this; remove(0); return *this;}
|
PIVector<T> & pop_front() {if (piv_size == 0) return *this; remove(0); return *this;}
|
||||||
|
|
||||||
T take_back() {T t(back()); pop_back(); return t;}
|
T take_back() {T t(back()); pop_back(); return t;}
|
||||||
T take_front() {T t(front()); pop_front(); return t;}
|
T take_front() {T t(front()); pop_front(); return t;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _reset() {__piv_size__ = __piv_rsize__ = 0; __piv_data__ = 0;}
|
void _reset() {piv_size = piv_rsize = 0; piv_data = 0;}
|
||||||
ullong asize(ullong s) {
|
size_t asize(size_t s) {
|
||||||
if (s == 0) return 0;
|
if (s == 0) return 0;
|
||||||
if (__piv_rsize__ + __piv_rsize__ >= s && __piv_rsize__ < s)
|
if (piv_rsize + piv_rsize >= s && piv_rsize < s)
|
||||||
return __piv_rsize__ + __piv_rsize__;
|
return piv_rsize + piv_rsize;
|
||||||
ullong t = 0, s_ = s - 1;
|
size_t t = 0, s_ = s - 1;
|
||||||
while (s_ >> t) ++t;
|
while (s_ >> t) ++t;
|
||||||
return (1 << t);
|
return (1 << t);
|
||||||
}
|
}
|
||||||
T * newRaw(ullong s) {
|
T * newRaw(size_t s) {
|
||||||
//cout << std::dec << " ![("<<this<<")newRaw " << s << " elements ... <\n" << endl;
|
//cout << std::dec << " ![("<<this<<")newRaw " << s << " elements ... <\n" << endl;
|
||||||
//uchar * ret = new uchar[s * sizeof(T)];
|
//uchar * ret = new uchar[s * sizeof(T)];
|
||||||
uchar * ret = (uchar*)(malloc(s * sizeof(T)));//new uchar[];
|
uchar * ret = (uchar*)(malloc(s * sizeof(T)));//new uchar[];
|
||||||
@@ -292,55 +289,110 @@ private:
|
|||||||
//cout << std::hex << " > (new 0x" << (llong)ret << ") ok]!" << endl;
|
//cout << std::hex << " > (new 0x" << (llong)ret << ") ok]!" << endl;
|
||||||
return (T*)ret;
|
return (T*)ret;
|
||||||
}
|
}
|
||||||
void deleteT(T * d, ullong sz) {
|
/*void reallocRawTemp(size_t s) {
|
||||||
|
if (piv_tdata == 0) piv_tdata = (T*)(malloc(s * sizeof(T)));
|
||||||
|
else piv_tdata = (T*)(realloc(piv_tdata, s * sizeof(T)));
|
||||||
|
}*/
|
||||||
|
void deleteT(T * d, size_t sz) {
|
||||||
//cout << " ~[("<<this<<")deleteT " << std::dec << sz << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
//cout << " ~[("<<this<<")deleteT " << std::dec << sz << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
||||||
if ((uchar*)d != 0) {
|
if ((uchar*)d != 0) {
|
||||||
for (ullong i = 0; i < sz; ++i)
|
for (size_t i = 0; i < sz; ++i)
|
||||||
d[i].~T();
|
d[i].~T();
|
||||||
//zeroRaw(d, sz);
|
//zeroRaw(d, sz);
|
||||||
}
|
}
|
||||||
//cout << " > ok]~" << endl;
|
//cout << " > ok]~" << endl;
|
||||||
}
|
}
|
||||||
void deleteRaw(T *& d) {
|
void deleteRaw(T *& d) {
|
||||||
//cout << " ~[("<<this<<")deleteRaw " << std::dec << __piv_rsize__ << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
//cout << " ~[("<<this<<")deleteRaw " << std::dec << piv_rsize << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
||||||
if ((uchar*)d != 0) free((uchar*)d);
|
if ((uchar*)d != 0) free((uchar*)d);
|
||||||
d = 0;
|
d = 0;
|
||||||
//cout << " > ok]~" << endl;
|
//cout << " > ok]~" << endl;
|
||||||
}
|
}
|
||||||
void zeroRaw(T * d, ullong s) {
|
void zeroRaw(T * d, size_t s) {
|
||||||
//cout << " ~[("<<this<<")zeroRaw " << std::dec << s << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
//cout << " ~[("<<this<<")zeroRaw " << std::dec << s << " elements " << std::hex << "0x" << (llong)d << " ... <\n" << endl;
|
||||||
if ((uchar*)d != 0) memset(d, 0, s*sizeof(T));
|
if ((uchar*)d != 0) memset(d, 0, s*sizeof(T));
|
||||||
//cout << " > ok]~" << endl;
|
//cout << " > ok]~" << endl;
|
||||||
}
|
}
|
||||||
void dealloc() {deleteRaw(__piv_data__);}
|
void dealloc() {deleteRaw(piv_data);}
|
||||||
void alloc(ullong new_size) {
|
inline void alloc(size_t new_size) {
|
||||||
if (new_size <= __piv_rsize__) {
|
if (new_size <= piv_rsize) {
|
||||||
__piv_size__ = new_size;
|
piv_size = new_size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//int os = __piv_size__;
|
//int os = piv_size;
|
||||||
__piv_size__ = new_size;
|
piv_size = new_size;
|
||||||
ullong as = asize(new_size);
|
size_t as = asize(new_size);
|
||||||
if (as == __piv_rsize__) return;
|
if (as == piv_rsize) return;
|
||||||
|
|
||||||
//cout << std::hex << " ![("<<this<<")realloc " << __piv_data__ << " data ... <\n" << endl;
|
//cout << std::hex << " ![("<<this<<")realloc " << piv_data << " data ... <\n" << endl;
|
||||||
__piv_data__ = (T*)(realloc(__piv_data__, as*sizeof(T)));
|
piv_data = (T*)(realloc(piv_data, as*sizeof(T)));
|
||||||
//zeroRaw(&(__piv_data__[os]), as - os);
|
//zeroRaw(&(piv_data[os]), as - os);
|
||||||
__piv_rsize__ = as;
|
piv_rsize = as;
|
||||||
//cout << std::hex << " > (new 0x" << (llong)__piv_data__ << ") ok]!" << endl;
|
//cout << std::hex << " > (new 0x" << (llong)piv_data << ") ok]!" << endl;
|
||||||
/*__piv_rsize__ = as;
|
/*piv_rsize = as;
|
||||||
T * pd = newRaw(__piv_rsize__);
|
T * pd = newRaw(piv_rsize);
|
||||||
if (os > 0 && __piv_data__ != 0) {
|
if (os > 0 && piv_data != 0) {
|
||||||
memcpy(pd, __piv_data__, os * sizeof(T));
|
memcpy(pd, piv_data, os * sizeof(T));
|
||||||
deleteRaw(__piv_data__);
|
deleteRaw(piv_data);
|
||||||
}
|
}
|
||||||
__piv_data__ = pd;*/
|
piv_data = pd;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
T * __piv_data__;
|
T * piv_data;
|
||||||
ullong __piv_size__, __piv_rsize__;
|
size_t piv_size, piv_rsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define __PIVECTOR_SIMPLE_FUNCTIONS__(T) \
|
||||||
|
template<> inline PIVector<T>::~PIVector() {dealloc(); _reset();} \
|
||||||
|
template<> inline PIVector<T> & PIVector<T>::push_back(const T & v) {alloc(piv_size + 1); piv_data[piv_size - 1] = v; return *this;} \
|
||||||
|
template<> inline PIVector<T> & PIVector<T>::fill(const T & f) { \
|
||||||
|
for (size_t i = 0; i < piv_size; ++i) \
|
||||||
|
piv_data[i] = f; \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
template<> inline PIVector<T> & PIVector<T>::resize(size_t new_size, const T & f) { \
|
||||||
|
if (new_size < piv_size) \
|
||||||
|
piv_size = new_size; \
|
||||||
|
if (new_size > piv_size) { \
|
||||||
|
size_t os = piv_size; \
|
||||||
|
alloc(new_size); \
|
||||||
|
for (size_t i = os; i < new_size; ++i) piv_data[i] = f; \
|
||||||
|
} \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
template<> inline PIVector<T> & PIVector<T>::insert(size_t index, const T & v) { \
|
||||||
|
alloc(piv_size + 1); \
|
||||||
|
if (index < piv_size - 1) { \
|
||||||
|
size_t os = piv_size - index - 1; \
|
||||||
|
memmove(&(piv_data[index + 1]), &(piv_data[index]), os * sizeof(T)); \
|
||||||
|
} \
|
||||||
|
piv_data[index] = v; \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
template<> inline PIVector<T> & PIVector<T>::remove(size_t index, size_t count) { \
|
||||||
|
if (index + count >= piv_size) { \
|
||||||
|
resize(index); \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
size_t os = piv_size - index - count; \
|
||||||
|
memmove(&(piv_data[index]), &(piv_data[index + count]), os * sizeof(T)); \
|
||||||
|
piv_size -= count; \
|
||||||
|
return *this; \
|
||||||
|
}
|
||||||
|
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(char)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(uchar)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(short)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(ushort)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(int)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(uint)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(long)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(ulong)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(llong)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(ullong)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(float)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(double)
|
||||||
|
__PIVECTOR_SIMPLE_FUNCTIONS__(ldouble)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -425,15 +477,17 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define __PIVECTOR_SIMPLE_FUNCTIONS__(T)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIVector<T> & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIVector<T> & v) {s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline PICout operator <<(PICout s, const PIVector<T> & v) {s.space(); s.setControl(0, true); s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
|
inline PICout operator <<(PICout s, const PIVector<T> & v) {s.space(); s.setControl(0, true); s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; s.restoreControl(); return s;}
|
||||||
|
|
||||||
|
|
||||||
#endif // PIVECTOR_H
|
#endif // PIVECTOR_H
|
||||||
|
|||||||
Reference in New Issue
Block a user