initial
This commit is contained in:
parent
7fc39d6d31
commit
8fd444092b
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"git.ignoreLimitWarning": true
|
||||||
|
}
|
||||||
1563
CMakeLists.txt
Normal file
1563
CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load Diff
1
CODE_OF_CONDUCT.md
Normal file
1
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Our code of conduct is published at https://zeek.org/community-code-of-conduct/
|
||||||
3
CONTRIBUTING.md
Normal file
3
CONTRIBUTING.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Our contribution guide is available at https://github.com/zeek/zeek/wiki/Contribution-Guide.
|
||||||
|
|
||||||
|
More information about contributing is also available at https://docs.zeek.org/en/master/devel/contributors.html.
|
||||||
34
COPYING
Normal file
34
COPYING
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
Copyright (c) 1995-now, The Regents of the University of California
|
||||||
|
through the Lawrence Berkeley National Laboratory and the
|
||||||
|
International Computer Science Institute. 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.
|
||||||
|
|
||||||
|
(2) 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.
|
||||||
|
|
||||||
|
(3) Neither the name of the University of California, Lawrence Berkeley
|
||||||
|
National Laboratory, U.S. Dept. of Energy, International Computer
|
||||||
|
Science Institute, nor the names of contributors may be used to endorse
|
||||||
|
or promote products derived from this software without specific prior
|
||||||
|
written permission.
|
||||||
|
|
||||||
|
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 OWNER 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.
|
||||||
|
|
||||||
|
Note that some files in the distribution may carry their own copyright
|
||||||
|
notices.
|
||||||
1214
COPYING-3rdparty
Normal file
1214
COPYING-3rdparty
Normal file
File diff suppressed because it is too large
Load Diff
72
Makefile
Normal file
72
Makefile
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#
|
||||||
|
# A simple static wrapper for a number of standard Makefile targets,
|
||||||
|
# mostly just forwarding to build/Makefile. This is provided only for
|
||||||
|
# convenience and supports only a subset of what CMake's Makefile
|
||||||
|
# offers. For more, execute that one directly.
|
||||||
|
#
|
||||||
|
|
||||||
|
BUILD=build
|
||||||
|
REPO=$$(cd $(CURDIR) && basename $$(git config --get remote.origin.url | sed 's/^[^:]*://g'))
|
||||||
|
VERSION_FULL=$(REPO)-$$(cd $(CURDIR) && cat VERSION)
|
||||||
|
GITDIR=$$(test -f .git && echo $$(cut -d" " -f2 .git) || echo .git)
|
||||||
|
REALPATH=$$($$(realpath --relative-to=$(shell pwd) . >/dev/null 2>&1) && echo 'realpath' || echo 'grealpath')
|
||||||
|
|
||||||
|
all: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
install: configured all
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
install-aux: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
clean: configured docclean
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
doc:
|
||||||
|
$(MAKE) -C doc $@
|
||||||
|
|
||||||
|
docclean:
|
||||||
|
(cd doc && make clean)
|
||||||
|
|
||||||
|
livehtml:
|
||||||
|
$(MAKE) -C doc $@
|
||||||
|
|
||||||
|
# The COPYFILE_DISABLE flag used in the tar commands below is an undocumented feature
|
||||||
|
# of the tar binary on macOS. It causes tar to avoid including any of the special files
|
||||||
|
# that macOS litters around the repository directory, such as ._ resource files, none
|
||||||
|
# of which should be included in the distribution packages.
|
||||||
|
dist:
|
||||||
|
@test -e ../$(VERSION_FULL) && rm -ri ../$(VERSION_FULL) || true
|
||||||
|
@cp -R . ../$(VERSION_FULL)
|
||||||
|
@for i in . $$(git submodule foreach -q --recursive $(REALPATH) --relative-to=$$(pwd) .); do ((cd ../$(VERSION_FULL)/$$i && test -f .git && cp -R $(GITDIR) .gitnew && rm -f .git && mv .gitnew .git && sed -i.bak -e 's#[[:space:]]*worktree[[:space:]]*=[[:space:]]*.*##g' .git/config) || true); done
|
||||||
|
@for i in . $$(git submodule foreach -q --recursive $(REALPATH) --relative-to=$$(pwd) .); do (cd ../$(VERSION_FULL)/$$i && git reset -q --hard && git clean -ffdxq); done
|
||||||
|
@(cd ../$(VERSION_FULL) && find . -name \.git\* | xargs rm -rf)
|
||||||
|
@(cd ../$(VERSION_FULL) && find . -name \.idea -type d | xargs rm -rf)
|
||||||
|
@(cd ../$(VERSION_FULL) && find . -maxdepth 1 -name build\* | xargs rm -rf)
|
||||||
|
@python3 ./ci/collect-repo-info.py --only-git > ../$(VERSION_FULL)/repo-info.json
|
||||||
|
@mv ../$(VERSION_FULL) .
|
||||||
|
@COPYFILE_DISABLE=true tar -czf $(VERSION_FULL).tar.gz $(VERSION_FULL)
|
||||||
|
@echo Package: $(VERSION_FULL).tar.gz
|
||||||
|
@rm -rf $(VERSION_FULL)
|
||||||
|
|
||||||
|
distclean:
|
||||||
|
rm -rf $(BUILD)
|
||||||
|
$(MAKE) -C testing $@
|
||||||
|
|
||||||
|
test:
|
||||||
|
-@( cd testing && make )
|
||||||
|
|
||||||
|
test-aux:
|
||||||
|
-test -d auxil/zeekctl && ( cd auxil/zeekctl && make test-all )
|
||||||
|
-test -d auxil/btest && ( cd auxil/btest && make test )
|
||||||
|
-test -d auxil/zeek-aux && ( cd auxil/zeek-aux && make test )
|
||||||
|
-test -d auxil/plugins && ( cd auxil/plugins && make test-all )
|
||||||
|
|
||||||
|
test-all: test test-aux
|
||||||
|
|
||||||
|
configured:
|
||||||
|
@test -d $(BUILD) || ( echo "Error: No build/ directory found. Did you run configure?" && exit 1 )
|
||||||
|
@test -e $(BUILD)/Makefile || ( echo "Error: No build/Makefile found. Did you run configure?" && exit 1 )
|
||||||
|
|
||||||
|
.PHONY : all install clean doc docclean dist distclean configured livehtml
|
||||||
104
README
Normal file
104
README
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
=================================
|
||||||
|
The Zeek Network Security Monitor
|
||||||
|
=================================
|
||||||
|
|
||||||
|
Zeek is a powerful framework for network traffic analysis and security
|
||||||
|
monitoring. Follow us on Twitter at @zeekurity.
|
||||||
|
|
||||||
|
Key Features
|
||||||
|
============
|
||||||
|
|
||||||
|
* **In-depth Analysis**
|
||||||
|
Zeek ships with analyzers for many protocols, enabling
|
||||||
|
high-level semantic analysis at the application layer.
|
||||||
|
|
||||||
|
* **Adaptable & Flexible**
|
||||||
|
Zeek's domain specific scripting language enables site-specific
|
||||||
|
monitoring policies and means that it is not restricted to any
|
||||||
|
particular detection approach.
|
||||||
|
|
||||||
|
* **Efficient**
|
||||||
|
Zeek targets high-performance networks and is used operationally
|
||||||
|
at a variety of large sites.
|
||||||
|
|
||||||
|
* **Highly Stateful**
|
||||||
|
Zeek keeps extensive application-layer state about the network
|
||||||
|
it monitors and provides a high-level archive of a network's
|
||||||
|
activity.
|
||||||
|
|
||||||
|
Getting Started
|
||||||
|
===============
|
||||||
|
|
||||||
|
The best place to find information about getting started with Zeek is
|
||||||
|
our web site https://www.zeek.org, specifically the documentation
|
||||||
|
section there [1]. One the web site you can also get downloads for
|
||||||
|
stable releases, tutorials on getting Zeek set up, and many other
|
||||||
|
useful resources.
|
||||||
|
|
||||||
|
You can find release notes in NEWS, and a complete record of all
|
||||||
|
changes in CHANGES.
|
||||||
|
|
||||||
|
To work with the most recent code from the development branch of Zeek,
|
||||||
|
clone the master git repository:
|
||||||
|
|
||||||
|
> git clone --recursive https://github.com/zeek/zeek
|
||||||
|
|
||||||
|
With all dependencies [2] in place, build and install:
|
||||||
|
|
||||||
|
> ./configure && make && sudo make install
|
||||||
|
|
||||||
|
Write your first Zeek script:
|
||||||
|
|
||||||
|
# File "hello.zeek"
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
print "Hello, World!";
|
||||||
|
}
|
||||||
|
|
||||||
|
And run it:
|
||||||
|
|
||||||
|
> zeek hello.zeek
|
||||||
|
|
||||||
|
For learning more about the Zeek scripting language,
|
||||||
|
https://try.zeek.org is a great resource.
|
||||||
|
|
||||||
|
Development
|
||||||
|
===========
|
||||||
|
|
||||||
|
Zeek is developed on GitHub by its community. We welcome
|
||||||
|
contributions. Working on an open source project like Zeek can be an
|
||||||
|
incredibly rewarding experience and, packet by packet, makes the
|
||||||
|
Internet a little safer. Today, as a result of countless
|
||||||
|
contributions, Zeek is used operationally around the world by major
|
||||||
|
companies and educational and scientific institutions alike for
|
||||||
|
securing their cyber infrastructure.
|
||||||
|
|
||||||
|
If you're interested in getting involved, we collect feature requests
|
||||||
|
and issues on GitHub. More information on Zeek's development can be
|
||||||
|
found here [2], and information about its community and mailing lists
|
||||||
|
(which are fairly active) can be found here [3].
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
Zeek comes with a BSD license, allowing for free use with virtually no
|
||||||
|
restrictions. You can find it in COPYING.
|
||||||
|
|
||||||
|
Tooling
|
||||||
|
-------
|
||||||
|
|
||||||
|
We use the following tooling to help discover issues to fix, amongst a number of
|
||||||
|
others.
|
||||||
|
|
||||||
|
- Clang-Tidy [5]
|
||||||
|
- Coverity [6]
|
||||||
|
- PVS-Studio - static analyzer for C, C++, C#, and Java code [7]
|
||||||
|
|
||||||
|
[1] https://www.zeek.org/documentation/index.html
|
||||||
|
[2] https://docs.zeek.org/en/stable/install/install.html
|
||||||
|
[3] https://www.zeek.org/development/index.html
|
||||||
|
[4] https://www.zeek.org/community/index.html
|
||||||
|
[5] https://clang.llvm.org/extra/clang-tidy/
|
||||||
|
[6] https://scan.coverity.com/projects/bro
|
||||||
|
[7] https://pvs-studio.com/en/pvs-studio/?utm_source=github&utm_medium=organic&utm_campaign=open_source
|
||||||
126
README.md
126
README.md
@ -0,0 +1,126 @@
|
|||||||
|
<h1 align="center">
|
||||||
|
|
||||||
|
[](https://www.zeek.org)
|
||||||
|
|
||||||
|
The Zeek Network Security Monitor
|
||||||
|
|
||||||
|
</h1><h4 align="center">
|
||||||
|
|
||||||
|
A [powerful](https://old.zeek.org/why_choose_zeek.pdf) framework for network
|
||||||
|
traffic analysis and security monitoring.
|
||||||
|
|
||||||
|
[_Key Features_](#key-features) —
|
||||||
|
[_Documentation_](https://docs.zeek.org/en/stable/index.html) —
|
||||||
|
[_Getting Started_](#getting-started) —
|
||||||
|
[_Development_](#development) —
|
||||||
|
[_License_](#license)
|
||||||
|
|
||||||
|
Follow us on Twitter at [@zeekurity](https://twitter.com/zeekurity).
|
||||||
|
|
||||||
|
[](https://coveralls.io/github/zeek/zeek?branch=master)
|
||||||
|
[](https://cirrus-ci.com/github/zeek/zeek)
|
||||||
|
|
||||||
|
[](https://zeek.org/slack)
|
||||||
|
[](https://community.zeek.org)
|
||||||
|
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
|
||||||
|
Key Features
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* __In-depth Analysis__
|
||||||
|
Zeek ships with analyzers for many protocols, enabling high-level semantic
|
||||||
|
analysis at the application layer.
|
||||||
|
|
||||||
|
* __Adaptable and Flexible__
|
||||||
|
Zeek's domain-specific scripting language enables site-specific monitoring
|
||||||
|
policies and means that it is not restricted to any particular detection
|
||||||
|
approach.
|
||||||
|
|
||||||
|
* __Efficient__
|
||||||
|
Zeek targets high-performance networks and is used operationally at a variety
|
||||||
|
of large sites.
|
||||||
|
|
||||||
|
* __Highly Stateful__
|
||||||
|
Zeek keeps extensive application-layer state about the network it monitors
|
||||||
|
and provides a high-level archive of a network's activity.
|
||||||
|
|
||||||
|
Getting Started
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The best place to find information about getting started with Zeek is
|
||||||
|
our web site [www.zeek.org](https://www.zeek.org), specifically the
|
||||||
|
[documentation](https://docs.zeek.org/en/stable/index.html) section
|
||||||
|
there. On the web site you can also find downloads for stable
|
||||||
|
releases, tutorials on getting Zeek set up, and many other useful
|
||||||
|
resources.
|
||||||
|
|
||||||
|
You can find release notes in [NEWS](https://github.com/zeek/zeek/blob/master/NEWS),
|
||||||
|
and a complete record of all changes in [CHANGES](https://github.com/zeek/zeek/blob/master/CHANGES).
|
||||||
|
|
||||||
|
To work with the most recent code from the development branch of Zeek,
|
||||||
|
clone the master git repository:
|
||||||
|
|
||||||
|
`git clone --recursive https://github.com/zeek/zeek`
|
||||||
|
|
||||||
|
With all [dependencies](https://docs.zeek.org/en/stable/install/install.html#prerequisites)
|
||||||
|
in place, build and install:
|
||||||
|
|
||||||
|
`./configure && make && sudo make install`
|
||||||
|
|
||||||
|
Write your first Zeek script:
|
||||||
|
|
||||||
|
```zeek
|
||||||
|
# File "hello.zeek"
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
print "Hello World!";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And run it:
|
||||||
|
|
||||||
|
`zeek hello.zeek`
|
||||||
|
|
||||||
|
For learning more about the Zeek scripting
|
||||||
|
language, [try.zeek.org](http://try.zeek.org) is a great resource.
|
||||||
|
|
||||||
|
Development
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Zeek is developed on GitHub by its community. We welcome
|
||||||
|
contributions. Working on an open source project like Zeek can be an
|
||||||
|
incredibly rewarding experience and, packet by packet, makes the
|
||||||
|
Internet a little safer. Today, as a result of countless
|
||||||
|
contributions, Zeek is used operationally around the world by major
|
||||||
|
companies and educational and scientific institutions alike for
|
||||||
|
securing their cyber infrastructure.
|
||||||
|
|
||||||
|
If you're interested in getting involved, we collect feature requests
|
||||||
|
and issues on GitHub [here](https://github.com/zeek/zeek/issues) and
|
||||||
|
you might find
|
||||||
|
[these](https://github.com/zeek/zeek/labels/good%20first%20issue)
|
||||||
|
to be a good place to get started. More information on Zeek's
|
||||||
|
development can be found
|
||||||
|
[here](https://docs.zeek.org/en/current/devel/index.html), and information
|
||||||
|
about its community and mailing lists (which are fairly active) can be
|
||||||
|
found [here](https://www.zeek.org/community/).
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
Zeek comes with a BSD license, allowing for free use with virtually no
|
||||||
|
restrictions. You can find it [here](https://github.com/zeek/zeek/blob/master/COPYING).
|
||||||
|
|
||||||
|
|
||||||
|
Tooling
|
||||||
|
-------
|
||||||
|
|
||||||
|
We use the following tooling to help discover issues to fix, amongst a number of
|
||||||
|
others.
|
||||||
|
|
||||||
|
- [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/)
|
||||||
|
- [Coverity](https://scan.coverity.com/projects/bro)
|
||||||
|
- [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=github&utm_medium=organic&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code.
|
||||||
5
SECURITY.md
Normal file
5
SECURITY.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
Zeek's Security Policy is defined on our website at https://zeek.org/security-reporting/
|
||||||
|
|
||||||
|
Our Security Release Process is further clarified at https://github.com/zeek/zeek/wiki/Security-Release-Process
|
||||||
BIN
auxil/.DS_Store
vendored
Normal file
BIN
auxil/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
auxil/bifcl/.DS_Store
vendored
Normal file
BIN
auxil/bifcl/.DS_Store
vendored
Normal file
Binary file not shown.
146
auxil/bifcl/.clang-format
Normal file
146
auxil/bifcl/.clang-format
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# Copyright (c) 2020-2023 by the Zeek Project. See LICENSE for details.
|
||||||
|
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: true
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: false
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 120
|
||||||
|
CommentPragmas: 'NOLINT'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
|
||||||
|
# Include categories go like this:
|
||||||
|
# 0: reserved, since this automatically is the primary header for any .cc file
|
||||||
|
# 1: zeek-config.h
|
||||||
|
# 2: any c-style header
|
||||||
|
# 3: any c++-style header
|
||||||
|
# 4: any header that starts with "zeek/"
|
||||||
|
# 5: everything else, which should catch any of the auto-generated code from the
|
||||||
|
# build directory as well
|
||||||
|
#
|
||||||
|
# Sections 0-1 and 2-3 get grouped together in their respective blocks
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"zeek-config\.h"'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 1
|
||||||
|
- Regex: '^"zeek/zeek-config\.h"'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 2
|
||||||
|
- Regex: '^<[[:print:]]+\.(h|hh)>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 2
|
||||||
|
- Regex: '^<[[:print:]]+>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 3
|
||||||
|
- Regex: '^"zeek/'
|
||||||
|
Priority: 4
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 5
|
||||||
|
|
||||||
|
IncludeIsMainRegex: '$'
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: '^BEGIN_'
|
||||||
|
MacroBlockEnd: '^END_'
|
||||||
|
MaxEmptyLinesToKeep: 2
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 500
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||||
|
PointerAlignment: Left
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceAfterLogicalNot: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpacesInConditionalStatement: true
|
||||||
|
Standard: Cpp11
|
||||||
|
StatementMacros:
|
||||||
|
- STANDARD_OPERATOR_1
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
---
|
||||||
|
Language: Json
|
||||||
|
...
|
||||||
101
auxil/bifcl/.cmake-format.json
Normal file
101
auxil/bifcl/.cmake-format.json
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
"parse": {
|
||||||
|
"additional_commands": {
|
||||||
|
"CheckIPProto": {
|
||||||
|
"kwargs": {
|
||||||
|
"_proto": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"CheckType": {
|
||||||
|
"kwargs": {
|
||||||
|
"_type": "*",
|
||||||
|
"_alt_type": "*",
|
||||||
|
"_var": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SetPackageVersion": {
|
||||||
|
"kwargs": {
|
||||||
|
"_version": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SetPackageFileName": {
|
||||||
|
"kwargs": {
|
||||||
|
"_version": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SetPackageInstallScripts": {
|
||||||
|
"kwargs": {
|
||||||
|
"VERSION": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConfigurePackaging": {
|
||||||
|
"kwargs": {
|
||||||
|
"_version": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SetPackageGenerators": {},
|
||||||
|
"SetPackageMetadata": {},
|
||||||
|
"FindRequiredPackage": {
|
||||||
|
"kwargs": {
|
||||||
|
"packageName": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"InstallClobberImmune": {
|
||||||
|
"kwargs": {
|
||||||
|
"_srcfile": "*",
|
||||||
|
"_dstfile": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"InstallPackageConfigFile": {
|
||||||
|
"kwargs": {
|
||||||
|
"_srcfile": "*",
|
||||||
|
"_dstdir": "*",
|
||||||
|
"_dstfilename": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"InstallShellScript": {
|
||||||
|
"kwargs": {
|
||||||
|
"_srcfile": "*",
|
||||||
|
"_dstfile": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"InstallSymLink": {
|
||||||
|
"kwargs": {
|
||||||
|
"_filepath": "*",
|
||||||
|
"_sympath": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"spicy_add_analyzer": {
|
||||||
|
"kwargs": {
|
||||||
|
"NAME": "*",
|
||||||
|
"PACKAGE_NAME": "*",
|
||||||
|
"SOURCES": "*",
|
||||||
|
"MODULES": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zeek_add_plugin": {
|
||||||
|
"kwargs": {
|
||||||
|
"INCLUDE_DIRS": "*",
|
||||||
|
"DEPENDENCIES": "*",
|
||||||
|
"SOURCES": "*",
|
||||||
|
"BIFS": "*",
|
||||||
|
"PAC": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"always_wrap": [
|
||||||
|
"spicy_add_analyzer",
|
||||||
|
"zeek_add_plugin"
|
||||||
|
],
|
||||||
|
"line_width": 100,
|
||||||
|
"tab_size": 4,
|
||||||
|
"separate_ctrl_name_with_space": true,
|
||||||
|
"max_subgroups_hwrap": 3,
|
||||||
|
"line_ending": "unix"
|
||||||
|
},
|
||||||
|
"markup": {
|
||||||
|
"enable_markup": false
|
||||||
|
}
|
||||||
|
}
|
||||||
2
auxil/bifcl/.git-blame-ignore-revs
Normal file
2
auxil/bifcl/.git-blame-ignore-revs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# clang-format: Reformat Bifcl in Spicy style
|
||||||
|
1c92e23be51ffb2d66e3a1a37d2930c3fb17844f
|
||||||
22
auxil/bifcl/.github/codeql/codeql-config.yml
vendored
Normal file
22
auxil/bifcl/.github/codeql/codeql-config.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
name: "bifcl CodeQL config"
|
||||||
|
|
||||||
|
# CodeQL is bizarre -- "paths-ignore" only works for select languages, not
|
||||||
|
# including C/C++. Removing the build tree after the build doesn't work either
|
||||||
|
# because the build process itself contributes CodeQL data. You also cannot
|
||||||
|
# express alert management in-code. So ... all that's left is crude filter
|
||||||
|
# management below and battling the UI.
|
||||||
|
|
||||||
|
queries:
|
||||||
|
- uses: security-and-quality
|
||||||
|
|
||||||
|
query-filters:
|
||||||
|
- exclude:
|
||||||
|
id: cpp/non-constant-format
|
||||||
|
- exclude:
|
||||||
|
id: cpp/include-non-header
|
||||||
|
- exclude:
|
||||||
|
id: cpp/long-switch
|
||||||
|
- exclude:
|
||||||
|
id: cpp/commented-out-code
|
||||||
|
- exclude:
|
||||||
|
id: cpp/use-of-goto
|
||||||
40
auxil/bifcl/.github/workflows/codeql.yml
vendored
Normal file
40
auxil/bifcl/.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [master]
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
schedule:
|
||||||
|
- cron: '47 21 * * 5'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-python@v4
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: cpp
|
||||||
|
config-file: ./.github/codeql/codeql-config.yml
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
./configure
|
||||||
|
make -j $(nproc)
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: "/language:cpp"
|
||||||
14
auxil/bifcl/.github/workflows/pre-commit.yml
vendored
Normal file
14
auxil/bifcl/.github/workflows/pre-commit.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
name: pre-commit
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pre-commit:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3.1.0
|
||||||
|
- uses: actions/setup-python@v4
|
||||||
|
- uses: pre-commit/action@v3.0.0
|
||||||
2
auxil/bifcl/.gitignore
vendored
Normal file
2
auxil/bifcl/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
build
|
||||||
|
tmp
|
||||||
9
auxil/bifcl/.gitmodules
vendored
Normal file
9
auxil/bifcl/.gitmodules
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[submodule "cmake"]
|
||||||
|
path = cmake
|
||||||
|
url = https://github.com/zeek/cmake
|
||||||
|
[submodule "auxil/libstd"]
|
||||||
|
path = auxil/libstd
|
||||||
|
url = https://github.com/zeek/libunistd
|
||||||
|
[submodule "auxil/libunistd"]
|
||||||
|
path = auxil/libunistd
|
||||||
|
url = https://github.com/zeek/libunistd
|
||||||
30
auxil/bifcl/.pre-commit-config.yaml
Normal file
30
auxil/bifcl/.pre-commit-config.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# See https://pre-commit.com for more information
|
||||||
|
# See https://pre-commit.com/hooks.html for more hooks
|
||||||
|
#
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: v19.1.7
|
||||||
|
hooks:
|
||||||
|
- id: clang-format
|
||||||
|
types_or:
|
||||||
|
- "c"
|
||||||
|
- "c++"
|
||||||
|
- "json"
|
||||||
|
|
||||||
|
- repo: https://github.com/maxwinterstein/shfmt-py
|
||||||
|
rev: v3.7.0.1
|
||||||
|
hooks:
|
||||||
|
- id: shfmt
|
||||||
|
args: ["-w", "-i", "4", "-ci"]
|
||||||
|
|
||||||
|
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
||||||
|
rev: v0.6.13
|
||||||
|
hooks:
|
||||||
|
- id: cmake-format
|
||||||
|
exclude: '^auxil/.*$'
|
||||||
|
|
||||||
|
- repo: https://github.com/crate-ci/typos
|
||||||
|
rev: v1.30.1
|
||||||
|
hooks:
|
||||||
|
- id: typos
|
||||||
|
exclude: '^(.typos.toml|auxil/.*|CHANGES)$'
|
||||||
400
auxil/bifcl/CHANGES
Normal file
400
auxil/bifcl/CHANGES
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
1.8.0-27 | 2025-04-14 07:41:41 -0700
|
||||||
|
|
||||||
|
* Update pre-commit versions, remove yapf from pre-commit (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Reformat CMakeLists via pre-commit (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Switch namespacing in generated code to C++-17-style nested namespaces (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0-23 | 2025-03-07 10:44:39 -0700
|
||||||
|
|
||||||
|
* Add #pragma once to generated headers (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0-16 | 2024-01-22 10:05:00 -0700
|
||||||
|
|
||||||
|
* Make BIFs just return ValPtr directly instead of BifReturnVal (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0-14 | 2023-11-06 13:32:55 -0700
|
||||||
|
|
||||||
|
* Update .git-blame-ignore-revs (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Reformat Bifcl in Spicy style (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0-11 | 2023-08-03 09:36:59 -0700
|
||||||
|
|
||||||
|
* Remove usage of FindRequiredPackage (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0-9 | 2023-07-02 14:51:55 -0700
|
||||||
|
|
||||||
|
* Add /J flag on Windows to force unsigned char (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Pass -funsigned-char flag during compilation (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0-6 | 2023-06-22 11:02:37 -0700
|
||||||
|
|
||||||
|
* Force -std=c++17 mode for cmake targets, remove use of RequireCXX17.cmake (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Require CMake 3.15.0 to build, similar to the recent changes to zeek and broker (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0-2 | 2023-05-31 14:24:15 +0200
|
||||||
|
|
||||||
|
* Remove vendored CMake files from repo (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.8.0 | 2023-05-23 10:52:35 -0700
|
||||||
|
|
||||||
|
* Update submodule(s) [nomail] [skip ci] (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.7.0-11 | 2023-04-19 19:28:13 +0200
|
||||||
|
|
||||||
|
* Render runtime type checks for var_args bifs (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
Currently, Zeek disables any static type checking for var_arg bifs.
|
||||||
|
However, the generated preamble for var_args bifs assume that
|
||||||
|
typed positional arguments are correctly typed and blindly calls
|
||||||
|
the type converters on them. This easily triggers abort()s at runtime
|
||||||
|
currently when a script mistakenly uses the wrong types for var_arg
|
||||||
|
bifs. For example, calling publish_rr() with a port instead of a string
|
||||||
|
causes a hard-abort with Zeek 5.0.8.
|
||||||
|
|
||||||
|
$ zeek -e 'Cluster::publish_rr(Cluster::Pool(), 80/tcp)'
|
||||||
|
fatal error in <no location>: Val::CONVERTER (port/string) (80/tcp)
|
||||||
|
Aborted (core dumped)
|
||||||
|
|
||||||
|
Extend bifcl so that for var_arg functions and the types that bifcl understands,
|
||||||
|
we render a runtime type check and explicit early return to avoid the abort().
|
||||||
|
For any/other types, the implementer of the bif continuous to be responsible
|
||||||
|
for type checking.
|
||||||
|
|
||||||
|
This isn't solving the var_args situation generally, but avoids some
|
||||||
|
ad-hoc fixes trickling in current bif implementations.
|
||||||
|
|
||||||
|
Some references:
|
||||||
|
|
||||||
|
https://github.com/zeek/zeek/issues/1523
|
||||||
|
https://github.com/zeek/zeek/issues/2425
|
||||||
|
https://github.com/zeek/zeek/issues/2935
|
||||||
|
https://github.com/zeek/zeek/pull/2950
|
||||||
|
|
||||||
|
* GH-25: builtin-func.l: Allow more than just one additional component (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
I'm not sure why this was restricted to only two components,
|
||||||
|
the following appears functional in Zeek scripts.
|
||||||
|
|
||||||
|
module A::B::C;
|
||||||
|
|
||||||
|
export {
|
||||||
|
type MyRecord: record {
|
||||||
|
a: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Closes #25.
|
||||||
|
|
||||||
|
1.7.0-7 | 2023-02-27 09:33:13 -0700
|
||||||
|
|
||||||
|
* Other minor cleanups (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Use bools for boolean comparisons (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Use nullptrs for pointer initializations (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.7.0-3 | 2023-02-22 07:33:15 -0700
|
||||||
|
|
||||||
|
* Include stdint.h early to prevent redefinition of int type macros (Tim Wojtulewicz)
|
||||||
|
|
||||||
|
* Remove argument from BIFCL_LSAN_DISABLE macro to fix warning on Windows (Tim Wojtulewicz)
|
||||||
|
|
||||||
|
1.7.0 | 2023-02-01 15:42:00 -0700
|
||||||
|
|
||||||
|
* Tag version 1.7.0 (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.6.2-28 | 2022-12-14 14:54:23 -0700
|
||||||
|
|
||||||
|
* Adjust CodeQL setup to bifcl (Christian Kreibich, Corelight)
|
||||||
|
|
||||||
|
First real foray into CodeQL and I'm pretty underwhelmed. The warnings are
|
||||||
|
either noise or in bison-generated code, which would be nice to whitelist,
|
||||||
|
except CodeQL gives no way to exclude files for compiled code, and you cannot
|
||||||
|
control alerts in-code. So the only mechanisms remaining are crude wholesale
|
||||||
|
suppression via the config file, and dismissal in the UI, for which there are
|
||||||
|
insufficient options (I went for "won't fix" for these).
|
||||||
|
|
||||||
|
1.6.2-21 | 2022-10-26 08:47:22 -0700
|
||||||
|
|
||||||
|
* Only adding subdir if running standalone (Tomer Lev)
|
||||||
|
|
||||||
|
* Adding support for libunistd. Also adding pragma guard for the right arch (Tomer Lev)
|
||||||
|
|
||||||
|
* Add libunistd submodule [nomail] [skip ci] (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.6.2-17 | 2022-10-24 08:08:44 -0700
|
||||||
|
|
||||||
|
* Add pre-commit github workflow (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Add pre-commit configuration and run it on everything (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Add clang-format and run it on everything (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.6.2-12 | 2022-10-18 14:27:38 -0700
|
||||||
|
|
||||||
|
* Bumped cmake submodule commit (Tomer Lev)
|
||||||
|
|
||||||
|
* Adapted bifcl to compile with MSVC for Windows environment. (Elad Solomon)
|
||||||
|
|
||||||
|
1.6.2-9 | 2022-10-13 13:58:34 -0500
|
||||||
|
|
||||||
|
* Use full path to filename in #line directives in generated code (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
This fixes the DWARF information gets output by the compiler, and allows debuggers
|
||||||
|
to use the full path name to display contextual information when a session stops
|
||||||
|
inside of BIF code.
|
||||||
|
|
||||||
|
1.6.2-7 | 2022-09-28 10:08:51 +0200
|
||||||
|
|
||||||
|
* GH-15: Keep zeekygen comments close to their definitions (Benjamin
|
||||||
|
Bannier, Corelight)
|
||||||
|
|
||||||
|
1.6.2-4 | 2022-07-12 13:55:23 -0700
|
||||||
|
|
||||||
|
* Remove remaining uses of Bro naming (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Deprecate bro_int_t and bro_uint_t (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Keep make dist from deleting all paths containing 'build' [skip ci] (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.6.2 | 2022-06-01 09:29:50 -0700
|
||||||
|
|
||||||
|
* Release 1.6.2
|
||||||
|
|
||||||
|
1.6.1-3 | 2022-02-07 10:04:10 -0700
|
||||||
|
|
||||||
|
* trimmed & regularized some minor variable naming (Vern Paxson, Corelight)
|
||||||
|
|
||||||
|
1.6.1 | 2021-12-10 09:38:56 -0700
|
||||||
|
|
||||||
|
* Update cmake submodule to latest master (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.6.0-2 | 2021-11-23 13:50:42 -0700
|
||||||
|
|
||||||
|
* Allow analyzer to be passed as nullptr for enqueue methods (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
This allows the methods to be used in contexts where the analyzer ID
|
||||||
|
is not available or when the ID doesn't matter, such as in packet
|
||||||
|
analyzers.
|
||||||
|
|
||||||
|
1.6.0 | 2021-07-06 08:55:36 -0700
|
||||||
|
|
||||||
|
* Update cmake submodule pointer (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.5.0-14 | 2021-07-06 08:52:10 -0700
|
||||||
|
|
||||||
|
* Updates for building Zeek as a subproject (Seth Hall, Corelight)
|
||||||
|
|
||||||
|
1.5.0-12 | 2021-04-29 10:44:10 -0700
|
||||||
|
|
||||||
|
* Rename Session::ConnVal() to Session::GetVal() (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.5.0-10 | 2021-03-17 13:44:12 -0700
|
||||||
|
|
||||||
|
* Prevent use of LeakSanitizer on FreeBSD (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.5.0-8 | 2021-01-29 21:05:13 -0800
|
||||||
|
|
||||||
|
* GH-1377: Add missing zeek/ to generated header includes (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.5.0-6 | 2021-01-29 16:37:13 -0800
|
||||||
|
|
||||||
|
* Remove v4.1 deprecation warnings (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.5.0-4 | 2021-01-21 10:03:42 -0700
|
||||||
|
|
||||||
|
* support for new FileVal class (Vern Paxson, Corelight)
|
||||||
|
|
||||||
|
1.5.0 | 2020-12-04 11:14:48 -0800
|
||||||
|
|
||||||
|
* Release 1.5.0.
|
||||||
|
|
||||||
|
1.4.0-19 | 2020-12-02 11:04:01 -0800
|
||||||
|
|
||||||
|
* Update minimum required CMake to 3.5 (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Postpone initialization of constants for subdir BIFs (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.4.0-11 | 2020-08-26 11:20:13 -0700
|
||||||
|
|
||||||
|
* Rename bro-bif.h to zeek-bif.h (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.4.0-9 | 2020-08-21 08:30:47 -0700
|
||||||
|
|
||||||
|
* Move __RegisterBif from zeek::detail::plugin to zeek::plugin::detail (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* SOURCE_LOCAL is part of the zeek::util::detail namespace now (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.4.0-6 | 2020-08-01 09:14:45 -0700
|
||||||
|
|
||||||
|
* Move Connection to zeek namespace (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move BifReturnVal to zeek::detail namespace (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move event code to zeek namespace, rename mgr to event_mgr (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move BroFile to zeek namespace, rename to File (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move base analyzer classes to zeek namespace (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.4.0 | 2020-07-23 10:10:53 -0700
|
||||||
|
|
||||||
|
* Release 1.4.0
|
||||||
|
|
||||||
|
1.3.0-54 | 2020-07-03 23:55:07 -0700
|
||||||
|
|
||||||
|
* Ensure strncpy null-termination (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Fix stringop-truncation compiler warning (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0-52 | 2020-07-02 19:22:22 -0700
|
||||||
|
|
||||||
|
* Add zeek:: namespace to val_mgr usage (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move BuiltinFunc to zeek namespace (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move Frame to the zeek::detail namespace (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move all Val classes to the zeek namespaces (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Move IntrusivePtr to the zeek namespace (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.3.0-44 | 2020-06-11 23:11:52 -0700
|
||||||
|
|
||||||
|
* Update namespace for *Type classes (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Update namespace for plugin::Plugin and plugin::BifItem classes (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Update namespace for __RegisterBif function (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.3.0-39 | 2020-06-03 13:18:47 -0700
|
||||||
|
|
||||||
|
* Use new TimeVal/DoubleVal subclass ctors (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0-37 | 2020-06-01 19:24:32 -0700
|
||||||
|
|
||||||
|
* Include Func.h in files during build (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
1.3.0-35 | 2020-06-01 10:58:45 -0700
|
||||||
|
|
||||||
|
* Change constructor for BroFile args (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Switch zeek::id::lookup to zeek::id::find (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Use zeek::BifEvent:: for enqueue_ functions instead of BifEvent::
|
||||||
|
|
||||||
|
The old BifEvent::generate_ functions were already deprecated (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Deprecate BifFunc:: declarations, replace with zeek::BifFunc::
|
||||||
|
|
||||||
|
Also changes name of function slightly, example: bro_fmt -> fmt_bif. (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Deprecate names in BifConst, replace with zeek::BifConst
|
||||||
|
|
||||||
|
Some Val* types are also replaced with IntrusivePtr (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Deprecate all BroType* in BifType:: namespace
|
||||||
|
|
||||||
|
Replaced with equivalently named IntrusivePtr in zeek::BifType:: (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Change internal_handler() usage (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Renaming/scoping of lookup functions (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Replace deprecated use of internal_const_val() (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Update deprecated use of internal_type() (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0-20 | 2020-04-24 16:17:33 -0700
|
||||||
|
|
||||||
|
* Deprecate BifEvent::generate_*, add BifEvent::enqueue_* (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Update deprecated Connection::BuildConnVal usage (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Return nullptr instead of 0 in BIF error conditions (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Update deprecated ValManager::Get usages (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Change BIFs to return a wrapper object
|
||||||
|
|
||||||
|
That allows implicit conversion from either Val* or IntrusivePtr<T> (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0-13 | 2020-04-16 13:50:22 -0700
|
||||||
|
|
||||||
|
* Remove use of Variable-Length-Arrays (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0-11 | 2020-04-13 14:53:11 -0700
|
||||||
|
|
||||||
|
* Support multiple/alternate event prototype definitions (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0-9 | 2020-04-01 13:13:23 -0700
|
||||||
|
|
||||||
|
* Don't pass a TimerMgr to EventMgr::Enqueue() (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Use EventMgr::Enqueue() instead of QueueEventFast() (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Move BIF function arguments from val_list to vector of IntrusivePtr (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0-1 | 2020-02-10 12:00:31 -0800
|
||||||
|
|
||||||
|
* Fix header include guards (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.3.0 | 2020-02-05 21:28:12 -0800
|
||||||
|
|
||||||
|
* Release 1.3.0
|
||||||
|
|
||||||
|
1.2-14 | 2020-01-03 09:53:56 -0700
|
||||||
|
|
||||||
|
* Disable LeakSanitizer
|
||||||
|
|
||||||
|
Related to https://github.com/zeek/zeek/issues/699 (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.2-9 | 2019-10-28 17:58:16 -0700
|
||||||
|
|
||||||
|
* Move CMake project() after cmake_minimum_required() (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Move headers into include/ subdir (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
This avoids potential problems with libc++ 8+ on case-insensitive file
|
||||||
|
systems due to inclusion of a new header called <version> which will end
|
||||||
|
up conflicting with the VERSION file if the search path includes the
|
||||||
|
project root.
|
||||||
|
|
||||||
|
1.2 | 2019-06-12 15:01:17 -0700
|
||||||
|
|
||||||
|
* Release 1.2.
|
||||||
|
|
||||||
|
1.1-19 | 2019-06-12 15:01:04 -0700
|
||||||
|
|
||||||
|
* Rename directories from bro to zeek (Daniel Thayer)
|
||||||
|
|
||||||
|
1.1-16 | 2019-05-20 19:38:17 -0700
|
||||||
|
|
||||||
|
* Rename Bro to Zeek (Daniel Thayer)
|
||||||
|
|
||||||
|
* Update codegen to use faster val_list and event queue API (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.1-10 | 2019-04-16 11:48:09 -0700
|
||||||
|
|
||||||
|
* Change file extension of auto-generated script files to .zeek (Daniel Thayer)
|
||||||
|
|
||||||
|
* Use ValManager for creating Vals (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Update submodules to use github.com/zeek (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.1 | 2018-08-31 15:23:21 -0500
|
||||||
|
|
||||||
|
* Add Makefile (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
1.0-1 | 2018-07-24 01:58:34 +0000
|
||||||
|
|
||||||
|
* Fix compiler warning. (Robin Sommer, Corelight)
|
||||||
|
|
||||||
|
1.0 | 2018-07-24 01:54:16 +0000
|
||||||
|
|
||||||
|
* bifcl is a now a separate project, starting CHANGES.
|
||||||
71
auxil/bifcl/CMakeLists.txt
Normal file
71
auxil/bifcl/CMakeLists.txt
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR)
|
||||||
|
project(BifCl C CXX)
|
||||||
|
|
||||||
|
include(cmake/CommonCMakeConfig.cmake)
|
||||||
|
|
||||||
|
find_package(BISON REQUIRED)
|
||||||
|
find_package(FLEX REQUIRED)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
add_compile_options(/J) # Similar to -funsigned-char on other platforms
|
||||||
|
set_property(SOURCE bif_lex.cc APPEND_STRING PROPERTY COMPILE_FLAGS "/wd4018")
|
||||||
|
else ()
|
||||||
|
set_property(SOURCE bif_lex.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
include_directories(BEFORE ${BifCl_SOURCE_DIR}/include ${BifCl_BINARY_DIR})
|
||||||
|
|
||||||
|
set(BISON_FLAGS "--debug")
|
||||||
|
|
||||||
|
# BIF parser/scanner
|
||||||
|
bison_target(BIFParser builtin-func.y ${BifCl_BINARY_DIR}/bif_parse.cc
|
||||||
|
DEFINES_FILE ${BifCl_BINARY_DIR}/bif_parse.h COMPILE_FLAGS "${BISON_FLAGS}")
|
||||||
|
flex_target(BIFScanner builtin-func.l ${BifCl_BINARY_DIR}/bif_lex.cc)
|
||||||
|
add_flex_bison_dependency(BIFScanner BIFParser)
|
||||||
|
|
||||||
|
set(bifcl_SRCS
|
||||||
|
${BISON_BIFParser_INPUT}
|
||||||
|
${FLEX_BIFScanner_INPUT}
|
||||||
|
${BISON_BIFParser_OUTPUTS}
|
||||||
|
${FLEX_BIFScanner_OUTPUTS}
|
||||||
|
bif_arg.cc
|
||||||
|
include/bif_arg.h
|
||||||
|
module_util.cc
|
||||||
|
include/module_util.h)
|
||||||
|
|
||||||
|
add_executable(bifcl ${bifcl_SRCS})
|
||||||
|
target_compile_features(bifcl PRIVATE cxx_std_17)
|
||||||
|
set_target_properties(bifcl PROPERTIES CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# If building separately from zeek, we need to add the libunistd subdirectory
|
||||||
|
# so that linking doesn't fail.
|
||||||
|
if ("${CMAKE_PROJECT_NAME}" STREQUAL "BifCl")
|
||||||
|
add_subdirectory(auxil/libunistd EXCLUDE_FROM_ALL)
|
||||||
|
endif ()
|
||||||
|
target_link_libraries(bifcl PRIVATE libunistd)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
install(TARGETS bifcl DESTINATION bin)
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE)
|
||||||
|
string(TOUPPER ${CMAKE_BUILD_TYPE} BuildType)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
message(
|
||||||
|
"\n====================| Bifcl Build Summary |====================="
|
||||||
|
"\n"
|
||||||
|
"\nBuild type: ${CMAKE_BUILD_TYPE}"
|
||||||
|
"\nBuild dir: ${PROJECT_BINARY_DIR}"
|
||||||
|
"\nInstall prefix: ${CMAKE_INSTALL_PREFIX}"
|
||||||
|
"\nDebug mode: ${ENABLE_DEBUG}"
|
||||||
|
"\n"
|
||||||
|
"\nCC: ${CMAKE_C_COMPILER}"
|
||||||
|
"\nCFLAGS: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BuildType}}"
|
||||||
|
"\nCXX: ${CMAKE_CXX_COMPILER}"
|
||||||
|
"\nCXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BuildType}}"
|
||||||
|
"\nCPP: ${CMAKE_CXX_COMPILER}"
|
||||||
|
"\n"
|
||||||
|
"\n================================================================\n")
|
||||||
|
|
||||||
|
include(UserChangedWarning)
|
||||||
34
auxil/bifcl/COPYING
Normal file
34
auxil/bifcl/COPYING
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
Copyright (c) 1995-2018, The Regents of the University of California
|
||||||
|
through the Lawrence Berkeley National Laboratory and the
|
||||||
|
International Computer Science Institute. 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.
|
||||||
|
|
||||||
|
(2) 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.
|
||||||
|
|
||||||
|
(3) Neither the name of the University of California, Lawrence Berkeley
|
||||||
|
National Laboratory, U.S. Dept. of Energy, International Computer
|
||||||
|
Science Institute, nor the names of contributors may be used to endorse
|
||||||
|
or promote products derived from this software without specific prior
|
||||||
|
written permission.
|
||||||
|
|
||||||
|
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 OWNER 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.
|
||||||
|
|
||||||
|
Note that some files in the distribution may carry their own copyright
|
||||||
|
notices.
|
||||||
42
auxil/bifcl/Makefile
Normal file
42
auxil/bifcl/Makefile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#
|
||||||
|
# A simple static wrapper for a number of standard Makefile targets,
|
||||||
|
# mostly just forwarding to build/Makefile. This is provided only for
|
||||||
|
# convenience and supports only a subset of what CMake's Makefile
|
||||||
|
# to offer. For more, execute that one directly.
|
||||||
|
#
|
||||||
|
|
||||||
|
BUILD=build
|
||||||
|
REPO=$$(cd $(CURDIR) && basename $$(git config --get remote.origin.url | sed 's/^[^:]*://g'))
|
||||||
|
VERSION_FULL=$(REPO)-$$(cd $(CURDIR) && cat VERSION)
|
||||||
|
VERSION_MIN=$(REPO)-$$(cd $(CURDIR) && cat VERSION)-minimal
|
||||||
|
GITDIR=$$(test -f .git && echo $$(cut -d" " -f2 .git) || echo .git)
|
||||||
|
|
||||||
|
all: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
install: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
clean: configured
|
||||||
|
$(MAKE) -C $(BUILD) $@
|
||||||
|
|
||||||
|
dist:
|
||||||
|
@test -e ../$(VERSION_FULL) && rm -ri ../$(VERSION_FULL) || true
|
||||||
|
@cp -R . ../$(VERSION_FULL)
|
||||||
|
@for i in . $$(git submodule foreach -q --recursive realpath --relative-to=$$(pwd) .); do ((cd ../$(VERSION_FULL)/$$i && test -f .git && cp -R $(GITDIR) .gitnew && rm -f .git && mv .gitnew .git && sed -i.bak -e 's#[[:space:]]*worktree[[:space:]]*=[[:space:]]*.*##g' .git/config) || true); done
|
||||||
|
@for i in . $$(git submodule foreach -q --recursive realpath --relative-to=$$(pwd) .); do (cd ../$(VERSION_FULL)/$$i && git reset -q --hard && git clean -ffdxq); done
|
||||||
|
@(cd ../$(VERSION_FULL) && find . -name \.git\* | xargs rm -rf)
|
||||||
|
@(cd ../$(VERSION_FULL) && find . -name \.idea -type d | xargs rm -rf)
|
||||||
|
@(cd ../$(VERSION_FULL) && find . -maxdepth 1 -name build\* | xargs rm -rf)
|
||||||
|
@mv ../$(VERSION_FULL) .
|
||||||
|
@tar -czf $(VERSION_FULL).tar.gz $(VERSION_FULL)
|
||||||
|
@echo Package: $(VERSION_FULL).tar.gz
|
||||||
|
@rm -rf $(VERSION_FULL)
|
||||||
|
|
||||||
|
distclean:
|
||||||
|
rm -rf $(BUILD)
|
||||||
|
|
||||||
|
.PHONY : configured
|
||||||
|
configured:
|
||||||
|
@test -d $(BUILD) || ( echo "Error: No build/ directory found. Did you run configure?" && exit 1 )
|
||||||
|
@test -e $(BUILD)/Makefile || ( echo "Error: No build/Makefile found. Did you run configure?" && exit 1 )
|
||||||
19
auxil/bifcl/README
Normal file
19
auxil/bifcl/README
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.. _Zeek: https://www.zeek.org
|
||||||
|
|
||||||
|
=================
|
||||||
|
Zeek BIF Compiler
|
||||||
|
=================
|
||||||
|
|
||||||
|
The ``bifcl`` program simply takes a ``.bif`` file as input and
|
||||||
|
generates C++ header/source files along with a ``.zeek`` script
|
||||||
|
that all-together provide the declaration and implementation of Zeek_
|
||||||
|
Built-In-Functions (BIFs), which can then be compiled and shipped
|
||||||
|
as part of a Zeek plugin.
|
||||||
|
|
||||||
|
A BIF allows one to write arbitrary C++ code and access it via a
|
||||||
|
function call inside a Zeek script. In this way, they can also be
|
||||||
|
used to access parts of Zeek's internal C++ API that aren't already
|
||||||
|
exposed via their own BIFs.
|
||||||
|
|
||||||
|
At the moment, learning the format of a ``.bif`` file is likely easiest
|
||||||
|
by just taking a look at the ``.bif`` files inside the Zeek source-tree.
|
||||||
1
auxil/bifcl/VERSION
Normal file
1
auxil/bifcl/VERSION
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.8.0-27
|
||||||
17
auxil/bifcl/auxil/libunistd/.gitattributes
vendored
Normal file
17
auxil/bifcl/auxil/libunistd/.gitattributes
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Custom for Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
|
||||||
|
# Standard to msysgit
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
||||||
45
auxil/bifcl/auxil/libunistd/.gitignore
vendored
Normal file
45
auxil/bifcl/auxil/libunistd/.gitignore
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
*.pri
|
||||||
|
*.pro.user
|
||||||
|
Makefile
|
||||||
|
Makefile.Release
|
||||||
|
Makefile.Debug
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
bak
|
||||||
|
Backup
|
||||||
|
Release
|
||||||
|
Debug
|
||||||
|
build
|
||||||
|
*.sdf
|
||||||
|
*.filters
|
||||||
|
.vs
|
||||||
|
x64
|
||||||
|
vscode
|
||||||
|
staging
|
||||||
47
auxil/bifcl/auxil/libunistd/CMakeLists.txt
Normal file
47
auxil/bifcl/auxil/libunistd/CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# libunistd/CMakeList.txt
|
||||||
|
|
||||||
|
cmake_minimum_required (VERSION 3.0.0)
|
||||||
|
project(libunistd)
|
||||||
|
message("<<< Parsing libunistd/CMakeList.txt")
|
||||||
|
message("--- Building ${PROJECT_NAME} ${CMAKE_SYSTEM_NAME}:${CMAKE_HOST_SYSTEM_PROCESSOR}:${CMAKE_GENERATOR_TOOLSET} ---")
|
||||||
|
|
||||||
|
option(UE4 "Disable _ITERATOR_DEBUG_LEVEL for UE4 compatibility" OFF)
|
||||||
|
option(WITH_TESTS "Enable this to build the tests / examples as well." OFF)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED FALSE)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS FALSE)
|
||||||
|
#set(CMAKE_GENERATOR_PLATFORM x64)
|
||||||
|
|
||||||
|
add_definitions(-DTRACE_MSG_FUNCTIONS)
|
||||||
|
|
||||||
|
if(UE4)
|
||||||
|
add_definitions(-D_ITERATOR_DEBUG_LEVEL=0)
|
||||||
|
add_definitions(-D_HAS_ITERATOR_DEBUGGING=0)
|
||||||
|
endif(UE4)
|
||||||
|
# cmake -D_HAS_ITERATOR_DEBUGGING=0 -D_ITERATOR_DEBUG_LEVEL=0 -A x64 ..
|
||||||
|
# _HAS_ITERATOR_DEBUGGING=0;_ITERATOR_DEBUG_LEVEL=0;
|
||||||
|
|
||||||
|
include(libunistd-config.cmake)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
include_directories(unistd)
|
||||||
|
add_subdirectory(unistd)
|
||||||
|
link_directories(build/win64)
|
||||||
|
link_libraries(libunistd Ws2_32)
|
||||||
|
message("Linking libunistd")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
if(NOT WIN32 AND NOT APPLE)
|
||||||
|
link_libraries(rt pthread dl)
|
||||||
|
message("Linking rt pthread dl")
|
||||||
|
endif(NOT WIN32 AND NOT APPLE)
|
||||||
|
|
||||||
|
add_subdirectory(portable)
|
||||||
|
add_subdirectory(sqlite)
|
||||||
|
add_subdirectory(uuid)
|
||||||
|
add_subdirectory(regex)
|
||||||
|
add_subdirectory(xxhash)
|
||||||
|
if(WITH_TESTS)
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif()
|
||||||
214
auxil/bifcl/auxil/libunistd/CodingStyle.md
Normal file
214
auxil/bifcl/auxil/libunistd/CodingStyle.md
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
# Gosh C++ Coding Style
|
||||||
|
|
||||||
|
By Robin Rowe 2016/12/18 rev. 2019/3/5
|
||||||
|
|
||||||
|
## Naming Conventions
|
||||||
|
|
||||||
|
File names:
|
||||||
|
|
||||||
|
FirstCap.h
|
||||||
|
FirstCap.cpp
|
||||||
|
|
||||||
|
File layout:
|
||||||
|
|
||||||
|
// MyClass.h Short description here...
|
||||||
|
|
||||||
|
#ifndef MyClass_h
|
||||||
|
#define MyClass_h
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
1. FirstCap class names.
|
||||||
|
2. camelCase variable names.
|
||||||
|
3. ALL_CAPS for enums and #defined constants.
|
||||||
|
4. Braces aligned, not as C-style hanging.
|
||||||
|
5. Header include guards use same case as class name.
|
||||||
|
6. Avoid Microsoft-style Hungarian naming.
|
||||||
|
7. Avoid snake_case. Never leading or trailing underscores.
|
||||||
|
8. Name files the same as the class they contain:
|
||||||
|
|
||||||
|
## Braces
|
||||||
|
|
||||||
|
Use C++ aligned braces, not C-style hanging braces.
|
||||||
|
|
||||||
|
## Complexity and Code Flow
|
||||||
|
|
||||||
|
Elegant simplicity is what's left after removing unnecessary complexity.
|
||||||
|
|
||||||
|
Avoid excessively clever solutions, especially when it relies on obscure C++ language features that will make it difficult for other programmers to read your code.
|
||||||
|
|
||||||
|
Early returns: Use if-not-return C++ code flow, not C-style if-else-return design.
|
||||||
|
|
||||||
|
const bool ok = Foo();
|
||||||
|
if(!ok)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
Bar();
|
||||||
|
|
||||||
|
Not...
|
||||||
|
|
||||||
|
if(ok)
|
||||||
|
{ Bar();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
|
||||||
|
## Class Layout
|
||||||
|
|
||||||
|
class Point
|
||||||
|
{ int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
Trace();
|
||||||
|
public:
|
||||||
|
Point()
|
||||||
|
: x(0)
|
||||||
|
, y(0)
|
||||||
|
, z(0)
|
||||||
|
{}
|
||||||
|
Point(int x,int y,int z)
|
||||||
|
: x(x)
|
||||||
|
, y(y)
|
||||||
|
, z(z)
|
||||||
|
{}
|
||||||
|
Print();
|
||||||
|
};
|
||||||
|
|
||||||
|
1. Use comma-first in initializer (only).
|
||||||
|
|
||||||
|
2. Organize class members with private members first. This is the default for classes, so no need to specify private. (Private members first because it makes code review go faster.)
|
||||||
|
|
||||||
|
## OOP
|
||||||
|
|
||||||
|
Use object-oriented programming.
|
||||||
|
|
||||||
|
When you write a constructor or Open() method for a class that calls several methods on the same member pointer, that is a big hint that your design isn't OOP enough. Move those calls into the constructor of a new class. Any class with an Open() or Close() method that you add functionality should probably be encapsulated in a new class.
|
||||||
|
|
||||||
|
In a GUI app, we typically have an App class and an AppMenu class.
|
||||||
|
|
||||||
|
Use override and final wherever appropriate.
|
||||||
|
|
||||||
|
Delete the copy constructor wherever appropriate:
|
||||||
|
|
||||||
|
MyClass(const MyClass&) = delete;
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
Avoid them. Never throw. Use return false instead.
|
||||||
|
|
||||||
|
Never specify throw in a function declaration.
|
||||||
|
|
||||||
|
## Command-line Args
|
||||||
|
|
||||||
|
We use libunistd portable::CommandLine for parsing. When creating a new program avoid implementing command-line parsing, simply create variables with the test default values. Command-line later.
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
|
To comment out a big block:
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
To silence unused variable warning:
|
||||||
|
|
||||||
|
int Foo(int x,int y)
|
||||||
|
{ (void) y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
1. Don't comment out large sections of code with // or /* */. To comment out large sections of code, for example, because you intend to remove the code later, use preprocessor directive.
|
||||||
|
|
||||||
|
2. Don't comment-out or remove function parameter names to silence compiler warnings about unused variables in function parameters. Cast to void instead. Of course, it's generally best to remove unused parameters entirely.
|
||||||
|
|
||||||
|
## Memory Management
|
||||||
|
|
||||||
|
1. Avoid excessive calls to heap. Don't create a class with lots of pointer members and calls to new when you could simply allocate the whole class, members and all.
|
||||||
|
|
||||||
|
2. Use unique_ptr to avoid memory leaks.
|
||||||
|
|
||||||
|
3. Avoid excessive use of static class data members. (It can become tightly coupled code that's difficult to refactor later.)
|
||||||
|
|
||||||
|
## Const Correctness
|
||||||
|
|
||||||
|
Make code const-correct, that is, use const wherever feasible.
|
||||||
|
|
||||||
|
## Third-Party Libs
|
||||||
|
|
||||||
|
1. Use the open source library libunistd (available on github) that enables Linux POSIX-compatible code to compile on Windows. It also has a set of classes for writing portable apps in a more C++ way than using C-based POSIX. The libunistd library is almost entirely header-only, quite lightweight.
|
||||||
|
|
||||||
|
2. Don't use Boost or other 3rd-party libraries unless directed to do so.
|
||||||
|
|
||||||
|
3. Do not duplicate 3rd party libs into our git. Keep as external libs.
|
||||||
|
|
||||||
|
## Threads
|
||||||
|
|
||||||
|
class Foo
|
||||||
|
{ std::mutex fooMutex;
|
||||||
|
std::condition_variable fooCondition;
|
||||||
|
bool isGo;
|
||||||
|
void Bar();
|
||||||
|
static void Main(Foo* self)
|
||||||
|
{ self->Run();
|
||||||
|
}
|
||||||
|
void Run()
|
||||||
|
{ while(isGo)
|
||||||
|
{ std::unique_lock<std::mutex> lock(fooMutex);
|
||||||
|
fooCondition.wait(lock);
|
||||||
|
Bar();
|
||||||
|
} }
|
||||||
|
public:
|
||||||
|
Foo();
|
||||||
|
void Start()
|
||||||
|
{ if(isGo)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
isGo=true;
|
||||||
|
std::thread worker(Main,this);
|
||||||
|
worker.detach();
|
||||||
|
}
|
||||||
|
void Wake()
|
||||||
|
{ fooCondition.notify_one();
|
||||||
|
}
|
||||||
|
void Stop()
|
||||||
|
{ isGo=false;
|
||||||
|
Wake();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
1. Use std::thread where needed to make app responsive.
|
||||||
|
|
||||||
|
2. Avoid creating more than a few threads.
|
||||||
|
|
||||||
|
3. Use thread(Main,this) to launch a thread on yourself:
|
||||||
|
|
||||||
|
Use unique_lock in your thread loop, lock_guard other threads.
|
||||||
|
|
||||||
|
4. Avoid recursive locks.
|
||||||
|
|
||||||
|
## Networking
|
||||||
|
|
||||||
|
Use POSIX htonl() or relevant functions in libunistd to keep endian consistent.
|
||||||
|
|
||||||
|
## Build System
|
||||||
|
|
||||||
|
Use cmake, unless project is Qt-based. For Qt projects, use its qmake build system, not cmake.
|
||||||
|
|
||||||
|
Set .gitignore to ignore build directory.
|
||||||
|
|
||||||
|
Project should build on Windows without making changes to sln file created by cmake.
|
||||||
|
|
||||||
|
## Use git
|
||||||
|
|
||||||
|
Save your changes to the master branch:
|
||||||
|
|
||||||
|
git pull
|
||||||
|
git status
|
||||||
|
git add SomeFile.cpp
|
||||||
|
git commit -a -m "SomeFile class does something"
|
||||||
|
git push
|
||||||
|
|
||||||
|
Create an appropriate .gitignore file. If everything seems fine, but you can't push, that may be because admin needs to unprotect the master branch in gitlab.
|
||||||
|
|
||||||
|
-000-
|
||||||
56
auxil/bifcl/auxil/libunistd/Contributors.md
Normal file
56
auxil/bifcl/auxil/libunistd/Contributors.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Contributor Merges
|
||||||
|
|
||||||
|
## 2023/2/23 from Tim Wojtulewicz
|
||||||
|
|
||||||
|
$ git pull
|
||||||
|
remote: Enumerating objects: 210, done.
|
||||||
|
remote: Counting objects: 100% (91/91), done.
|
||||||
|
remote: Compressing objects: 100% (49/49), done.
|
||||||
|
remote: Total 210 (delta 60), reused 57 (delta 42), pack-reused 119
|
||||||
|
Receiving objects: 100% (210/210), 43.94 KiB | 1.16 MiB/s, done.
|
||||||
|
Resolving deltas: 100% (119/119), completed with 3 local objects.
|
||||||
|
From https://github.com/robinrowe/libunistd
|
||||||
|
69e8722..923b956 master -> origin/master
|
||||||
|
Updating 69e8722..923b956
|
||||||
|
Fast-forward
|
||||||
|
README.md | 106 +++++++++++++++++++++++++++++++++++++++++++---
|
||||||
|
unistd/CMakeLists.txt | 15 ++++++-
|
||||||
|
unistd/arpa/nameser.h | 51 ++++++++++++++++++++++
|
||||||
|
unistd/fnmatch.cpp | 11 +++++
|
||||||
|
unistd/fnmatch.h | 10 +++++
|
||||||
|
unistd/fts.c | 20 +++++++++
|
||||||
|
unistd/fts.h | 26 ++++++++++++
|
||||||
|
unistd/mem.h | 29 +++++++++++++
|
||||||
|
unistd/net/ethertypes.h | 12 ++++++
|
||||||
|
unistd/net/if_arp.h | 23 ++++++++++
|
||||||
|
unistd/netdb.c | 14 ++++++
|
||||||
|
unistd/netdb.h | 14 +++++-
|
||||||
|
unistd/netinet/icmp6.h | 44 +++++++++++++++++++
|
||||||
|
unistd/netinet/in_systm.h | 0
|
||||||
|
unistd/netinet/ip.h | 48 ++++++++++++++-------
|
||||||
|
unistd/netinet/tcp.h | 47 ++++++++++++++++++++
|
||||||
|
unistd/netinet/udp.h | 20 +++++++++
|
||||||
|
unistd/sys/file.cpp | 92 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
unistd/sys/file.h | 17 ++++++++
|
||||||
|
unistd/sys/random.cpp | 29 +++++++++++++
|
||||||
|
unistd/sys/random.h | 8 ++++
|
||||||
|
unistd/sys/resource.h | 96 +++++++++++++++++++++++++++++++++++++----
|
||||||
|
unistd/syslog.cpp | 29 +++++++------
|
||||||
|
unistd/syslog.h | 5 ++-
|
||||||
|
24 files changed, 719 insertions(+), 47 deletions(-)
|
||||||
|
create mode 100644 unistd/arpa/nameser.h
|
||||||
|
create mode 100644 unistd/fnmatch.cpp
|
||||||
|
create mode 100644 unistd/fnmatch.h
|
||||||
|
create mode 100644 unistd/fts.c
|
||||||
|
create mode 100644 unistd/fts.h
|
||||||
|
create mode 100644 unistd/mem.h
|
||||||
|
create mode 100644 unistd/net/ethertypes.h
|
||||||
|
create mode 100644 unistd/net/if_arp.h
|
||||||
|
create mode 100644 unistd/netdb.c
|
||||||
|
create mode 100644 unistd/netinet/icmp6.h
|
||||||
|
create mode 100644 unistd/netinet/in_systm.h
|
||||||
|
create mode 100644 unistd/netinet/tcp.h
|
||||||
|
create mode 100644 unistd/netinet/udp.h
|
||||||
|
create mode 100644 unistd/sys/file.cpp
|
||||||
|
create mode 100644 unistd/sys/random.cpp
|
||||||
|
create mode 100644 unistd/sys/random.h
|
||||||
2565
auxil/bifcl/auxil/libunistd/Doxyfile
Normal file
2565
auxil/bifcl/auxil/libunistd/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
22
auxil/bifcl/auxil/libunistd/LICENSE
Normal file
22
auxil/bifcl/auxil/libunistd/LICENSE
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Robin Rowe
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
135
auxil/bifcl/auxil/libunistd/README.md
Normal file
135
auxil/bifcl/auxil/libunistd/README.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
# libunistd
|
||||||
|
|
||||||
|
Robin Rowe's libunistd is a lightweight Windows POSIX library that enables typical Linux C/C++ code to build in Windows Microsoft Visual Studio. If you're maintaining C++ code across Windows, Linux and MacOS you need a Windows POSIX library to make single codebase work. This is it.
|
||||||
|
|
||||||
|
Libunistd supports all the common Linux POSIX calls, except fork(). Please don't fork. Use C++ standard threads or libunistd's POSIX pthreads instead.
|
||||||
|
|
||||||
|
Usage: Set the include path in your VC++ project to include the directory libunistd/unistd (where the unistd.h file is). In any Linux code you have that won't compile in VC++, include the following at top of your header file:
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
Doing this will include the magic to make basic Linux APIs work in Windows. Because unistd.h exists in Linux as a standard header file, making this change for Windows will not break Linux code. Avoid #ifdef \_WIN32 ugliness in your code. Simply write C++ code as you would for Linux, and it should build in Visual Studio for Windows.
|
||||||
|
|
||||||
|
Libunisd is more than unistd.h. It implements many other header files that are POSIX standards, including pthreads.h. When porting your Linux program to Windows for the first time, you may have to include more POSIX headers than were necessary in your Linux code. In Linux, some standard headers include other standard header files. As a result, sometimes Linux code will compile that's not strictly legit, that it hasn't explicitly included all necessary header files. If you port Linux code to FreeBSD or Mac OS X, you may have encountered this before, that the compiler sometimes objects to unknown POSIX functions. Simple solution. Look up in the Linux man page the "unknown" function and include all the header files that the Linux man page says it requires.
|
||||||
|
|
||||||
|
Libunistd has some additional small libraries that are not POSIX, but can be useful to those of us developing cross-platform code. Libunistd has no dependencies on these. Use them if you wish.
|
||||||
|
|
||||||
|
1. Portable: System classes, such as StdFile that encapsulates the standard FILE* C API into a C++ class with constructors and destructors.
|
||||||
|
|
||||||
|
2. Qdecoder: A small HTTP library created elsewhere.
|
||||||
|
|
||||||
|
3. Sqlite: A small SQL library created elsewhere.
|
||||||
|
|
||||||
|
4. xxHash: A small hash library created elsewhere.
|
||||||
|
|
||||||
|
5. uuid: A small unique identifier library created elsewhere.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Open Source MIT/BSD. In other words, you may do pretty much whatever you want with libunistd. Not copyleft GNU. Similar for Qdecoder, Sqlite and xxHash, however you should check their license terms yourself as libunistd is not the owner of these other open source libraries.
|
||||||
|
|
||||||
|
## History
|
||||||
|
|
||||||
|
Libunistd was originally created to port Linux CinePaint to Windows in 2002. CinePaint is an open source HDR paint application used in making motion pictures, including the _Harry Potter_ and _Lord of the Rings_ films. Libunistd later moved from SourceForge to github and has been continuously improved, with more and more BSD and System V calls added.
|
||||||
|
|
||||||
|
Libunistd is being used for safety-critical Linux embedded systems. Not to deliver a Windows build on an embedded system, rather for testing and QA of the same embedded system codebase in Windows with access to the superb Microsoft Visual Studio debugger and its excellent static code checker that detects memory overruns.
|
||||||
|
|
||||||
|
Article About Libunistd...
|
||||||
|
|
||||||
|
https://goshrobin.com/cmaker-and-libunistd-presented-to-academy-software-foundation/
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
Although libunistd was predominately written by me, appreciate any good bug fixes, patches or pull requests. Thank you!
|
||||||
|
|
||||||
|
Approach...
|
||||||
|
|
||||||
|
I do single codebase development where the same C/C++ code will build on Linux, Windows, MacOS, BSD and Solaris. Except for Windows, the rest of those operating systems offer BSD or System V operating system libraries that make code fairly portable across UNIX-based systems. For Windows, I started implementing POSIX and pthreads calls I encountered in real world code as I ported Linux code to Windows. Because I've been doing this with libunstd over 20 years, there's a lot implemented. However, not complete coverage. When I come across a fresh group of Linux functions to implement, I often do the ones I need, and stub the rest using my STUB_* macros, as you can see in libunistd source code. I try to at least stub all of the functions in the same group, per Linux man pages. If you encounter a stubbed function and implement it, that's great.
|
||||||
|
|
||||||
|
Copyright and Standard Heading Format on All C/C++ Files...
|
||||||
|
|
||||||
|
When you are the original author, you created the file, you may note yourself as the copyright holder. It doesn't matter to libunistd users as our license is MIT open source. However, for provenance, someone needs to assert as being the copyright owner. If you are making a correction to an existing file, typically don't add your name.
|
||||||
|
|
||||||
|
Like this:
|
||||||
|
|
||||||
|
// arpa/nameser.h
|
||||||
|
// Copyright (c) 2023/2/23 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
...or use your name/email if you created the file. If your email name is vague, not in the format of first.last@company.com, put your name before your email, just to be clear:
|
||||||
|
|
||||||
|
// Copyright (c) 2023/2/23 Your Name <yname@somecompany.com
|
||||||
|
|
||||||
|
Not like this:
|
||||||
|
|
||||||
|
// fnmatch.cpp
|
||||||
|
// Provided by Your Employee Name on 2022/10/19
|
||||||
|
// 2022/10/19 ename@somecompany.com
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
...because using the word Copyright is how an author legally asserts being the original author. Every file should have a Copyright notice, in case there is ever a question of provenance or integrity.
|
||||||
|
|
||||||
|
Assignment of copyright, if necessary because the file is being contributed by a company, and the original author or company doesn't want author's name in public record, perhaps for personal privacy:
|
||||||
|
|
||||||
|
// Copyright (c) 2002/1/14 Robin.Rowe@CinePaint.org
|
||||||
|
// Copyright assigned by Some Company (Your Name <yname@company.com>) on 2023/2/23
|
||||||
|
|
||||||
|
...note that the original copyright date is preserved, although the original author employee's name is not.
|
||||||
|
|
||||||
|
If copying an open source file from another source, when you are not the author or owner, preserve whatever header the file already has, add our standard header format above it, modifying if necessary, and include the URL or wherever this file name from, preserve provenance. When copying a file from somewhere else, are not the author, leave the code formatting as is. You can't assign copyright if you're not the owner. It needs to be clear who the original copyright holder is, where the file came from. To be able to prove that there is no infringement.
|
||||||
|
|
||||||
|
Coding style...
|
||||||
|
|
||||||
|
Try to match the style of existing libunistd code. Align braces, like this:
|
||||||
|
|
||||||
|
if (!memcmp(h, word, word_len))
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Not hanging braces this:
|
||||||
|
|
||||||
|
if (!memcmp(h, word, word_len)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
If your coding style looks too different, don't be surprised if it gets filtered through a beautifier to make it match libunistd style better. Such as...
|
||||||
|
|
||||||
|
* UniversalIndentGUI set to Artistic, Horstman, add-brackets, delete-empty-lines https://universalindent.sourceforge.net/
|
||||||
|
|
||||||
|
Do not use the Microsoft macro #pragma once. For consistency, use traditional C #ifdef guard:
|
||||||
|
|
||||||
|
#ifndef filename_h
|
||||||
|
#define filename_h
|
||||||
|
...
|
||||||
|
#endif
|
||||||
|
|
||||||
|
...where filename is the name of the file.
|
||||||
|
|
||||||
|
Do not use the traditional #ifdef __cplusplus guard, as this makes it difficult to trace oddball C/C++ compile errors:
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Instead, use my CFUNC macro, like libunistd uses everywhere.
|
||||||
|
|
||||||
|
Do not use NULL. Use 0. When returning 0 or -1 from an empty function body just to stub it out, use my STUB_* macros instead. Macros are better because it will print a warning if called at runtime and are searchable.
|
||||||
|
|
||||||
|
Do not use #pragma comment(lib,"filename.lib"). Link libs via cmake, to avoid hiding build commands in C/C++ code pragmas.
|
||||||
|
|
||||||
|
Cast away unused function parameters, to avoid parameter unused warning and to document this is intended. Like this:
|
||||||
|
|
||||||
|
inline
|
||||||
|
struct group *getgrnam(const char *name)
|
||||||
|
{ (void) name;
|
||||||
|
STUB_0(getgrnam);
|
||||||
|
}
|
||||||
|
|
||||||
|
Use inline keyword with any function declared in a header file that is defined (has a function body), to avoid linker errors. Do not inline a function that is non-trivial or has a loop in it. Declare bigger functions in a header file and define in a separate source file.
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
Robin.Rowe@cinepaint.org
|
||||||
|
Los Angeles, California 323-535-0952
|
||||||
|
https://goshrobin.com
|
||||||
|
|
||||||
1
auxil/bifcl/auxil/libunistd/VERSION.txt
Normal file
1
auxil/bifcl/auxil/libunistd/VERSION.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
libunistd v1.2 2021/06/21
|
||||||
17
auxil/bifcl/auxil/libunistd/docs/fork.c
Normal file
17
auxil/bifcl/auxil/libunistd/docs/fork.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
enum {ERROR = -1,CHILD = 0};
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
if(pid==ERROR)
|
||||||
|
{ return FALSE;
|
||||||
|
}
|
||||||
|
if(pid!=CHILD)
|
||||||
|
{ return TRUE;
|
||||||
|
}
|
||||||
|
// execute child code:
|
||||||
|
char* args = {"1","2"};
|
||||||
|
execv("hello.exe",args)
|
||||||
|
return TRUE;
|
||||||
83
auxil/bifcl/auxil/libunistd/libunistd-config.cmake
Normal file
83
auxil/bifcl/auxil/libunistd/libunistd-config.cmake
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
# libunistd/libunistd-config.cmake
|
||||||
|
#-- Could NOT find LIBUNISTD (missing: LIBUNISTD_INCLUDE_DIR LIBUNISTD_LIBRARY)
|
||||||
|
# /code/github/libunistd/build/x64/unistd/Debug/libunistd.lib
|
||||||
|
# Edit CMakeLists.txt:
|
||||||
|
#
|
||||||
|
# find_package(LIBUNISTD REQUIRED
|
||||||
|
# NAMES libunistd
|
||||||
|
# PATHS ${LIBUNISTD_PATH} NO_DEFAULT_PATH
|
||||||
|
# )
|
||||||
|
|
||||||
|
message("<<< Parsing libunistd-config.cmake")
|
||||||
|
message("Found libunistd: CMAKE_CURRENT_LIST_DIR = ${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
|
||||||
|
#set(CMAKE_STATIC_LIBRARY_PREFIX "") #Avoid Linux "liblib__.a"
|
||||||
|
#message("--- Setting output directories ---")
|
||||||
|
if(${LIBUNISTD_DOWNLOAD})
|
||||||
|
# message("Downloading libunistd...")
|
||||||
|
set(OUTPUTDIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
else(${LIBUNISTD_DOWNLOAD})
|
||||||
|
set(OUTPUTDIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
endif(${LIBUNISTD_DOWNLOAD})
|
||||||
|
|
||||||
|
# CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG:
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUTDIR} )
|
||||||
|
#message(" CMAKE_LIBRARY_OUTPUT_DIRECTORY = ${OUTPUTDIR}")
|
||||||
|
foreach( outputconfig ${CMAKE_CONFIGURATION_TYPES} )
|
||||||
|
string( TOUPPER ${outputconfig} OUTPUTCONFIG )
|
||||||
|
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${OUTPUTDIR}/${outputconfig} )
|
||||||
|
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${OUTPUTDIR}/${outputconfig} )
|
||||||
|
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "VALUE" CACHE STRING ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG}})
|
||||||
|
# message(" _${OUTPUTCONFIG} = ${OUTPUTDIR}/${outputconfig}" )
|
||||||
|
endforeach( outputconfig ${CMAKE_CONFIGURATION_TYPES} )
|
||||||
|
# CMAKE_LIBRARY_OUTPUT_DIRECTORY = C:/Code/gitlab/ccLater/build/x64
|
||||||
|
# _DEBUG = C:/Code/gitlab/ccLater/build/x64/Debug
|
||||||
|
# _RELEASE = C:/Code/gitlab/ccLater/build/x64/Release
|
||||||
|
# _MINSIZEREL = C:/Code/gitlab/ccLater/build/x64/MinSizeRel
|
||||||
|
# _RELWITHDEBINFO = C:/Code/gitlab/ccLater/build/x64/RelWithDebInfo
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(CMAKE_STATIC_LIBRARY_PREFIX "")
|
||||||
|
set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
|
||||||
|
else(WIN32)
|
||||||
|
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
|
||||||
|
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
#message("CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG = ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG}")
|
||||||
|
|
||||||
|
if(${LIBUNISTD_DOWNLOAD})
|
||||||
|
set(LIBUNISTD_LIB_DIRS ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
# Adjusting LIBUNISTD_DOWNLOAD path
|
||||||
|
# C:/Code/gitlab/ccLater/build/x64/libunistd/libunistd-src...
|
||||||
|
# /c/code/gitlab/cclater/build/x64/build/x64/libunistd/libunistd-src/unistd/Debug/libunistd.lib
|
||||||
|
message(" Using LIBUNISTD_DOWNLOAD path ${LIBUNISTD_LIB_DIRS}")
|
||||||
|
set(LIBUNISTD_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/unistd)
|
||||||
|
set(LIBUNISTD_LIB_DIRS
|
||||||
|
debug ${LIBUNISTD_LIB_DIRS}/build/x64/unistd/Debug
|
||||||
|
optimized ${LIBUNISTD_LIB_DIRS}/build/x64/unistd/Release )
|
||||||
|
else(${LIBUNISTD_DOWNLOAD})
|
||||||
|
set(LIBUNISTD_LIB_DIRS ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
message(" Using local libunistd path ${LIBUNISTD_LIB_DIRS}")
|
||||||
|
set(LIBUNISTD_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/unistd)
|
||||||
|
set(LIBUNISTD_LIB_DIRS
|
||||||
|
debug ${LIBUNISTD_LIB_DIRS}/build/x64/Debug
|
||||||
|
optimized ${LIBUNISTD_LIB_DIRS}/build/x64/Release )
|
||||||
|
endif(${LIBUNISTD_DOWNLOAD})
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(LIBUNISTD_LIBRARIES libunistd) #${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||||
|
message("--- Windows libunistd paths ---")
|
||||||
|
message(" LIBUNISTD_INCLUDE_DIRS = ${LIBUNISTD_INCLUDE_DIRS}")
|
||||||
|
message(" LIBUNISTD_LIBRARIES = ${LIBUNISTD_LIBRARIES}")
|
||||||
|
message(" LIBUNISTD_LIB_DIRS = ${LIBUNISTD_LIB_DIRS}")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
set(LIBPORTABLE_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
set(LIBPORTABLE_LIBRARIES libuuid liblmdb libregex libsqlite libxxhash libportable )
|
||||||
|
set(LIBPORTABLE_LIB_DIRS ${LIBUNISTD_LIB_DIRS})
|
||||||
|
|
||||||
|
message("--- libportable paths ---")
|
||||||
|
message(" LIBPORTABLE_INCLUDE_DIRS = ${LIBPORTABLE_INCLUDE_DIRS}")
|
||||||
|
message(" LIBPORTABLE_LIBRARIES = ${LIBPORTABLE_LIBRARIES}")
|
||||||
|
message(" LIBPORTABLE_LIB_DIRS = ${LIBPORTABLE_LIB_DIRS}")
|
||||||
22
auxil/bifcl/auxil/libunistd/libunistd.pro
Normal file
22
auxil/bifcl/auxil/libunistd/libunistd.pro
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
#CONFIG += create_prl
|
||||||
|
|
||||||
|
SUBDIRS = portable xxhash
|
||||||
|
include(libunistd.pri)
|
||||||
|
|
||||||
|
win32
|
||||||
|
{ SUBDIRS += unistd
|
||||||
|
}
|
||||||
|
|
||||||
|
message(libunistd SUBDIRS = $$SUBDIRS)
|
||||||
|
message(libunistd INCLUDEPATH = $$INCLUDEPATH)
|
||||||
|
message(libunistd LIBS = $$LIBS)
|
||||||
|
message(libunistd _PRO_FILE_PWD_ = $$_PRO_FILE_PWD_)
|
||||||
|
message(libunistd OUT_PWD = $$OUT_PWD)
|
||||||
|
#C:/Code/github/libunistd/portable
|
||||||
|
|
||||||
|
#message(libunistd OUT_DIR = $$OUT_DIR)
|
||||||
|
#message(DESTDIR = $$DESTDIR)
|
||||||
|
#message(DESTDIR_TARGET = $$DESTDIR_TARGET)
|
||||||
|
#QMAKE_POST_LINK = copy $$OUT_PWD\debug\*.lib ..\my-lib
|
||||||
51
auxil/bifcl/auxil/libunistd/portable/App.h
Normal file
51
auxil/bifcl/auxil/libunistd/portable/App.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// App.h
|
||||||
|
// Created by Robin Rowe 2019-07-10
|
||||||
|
// License Copyright 2019 Robin.Rowe@HeroicRobots.com ***Proprietary***
|
||||||
|
|
||||||
|
#ifndef App_h
|
||||||
|
#define App_h
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "NamerPump.h"
|
||||||
|
#include "ReminderPump.h"
|
||||||
|
|
||||||
|
class App
|
||||||
|
{ App(const App&) = delete;
|
||||||
|
void operator=(const App&) = delete;
|
||||||
|
NamerPump& namerPump;
|
||||||
|
static App* app;
|
||||||
|
static void Stop(int signal)
|
||||||
|
{ (void) signal;
|
||||||
|
if(!app)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
app->namerPump.Stop();
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
std::ostream& Print(std::ostream& os) const
|
||||||
|
{ return os << "App";
|
||||||
|
}
|
||||||
|
App()
|
||||||
|
: namerPump(namerPump)
|
||||||
|
{ if(0!=app)
|
||||||
|
{ puts("ERROR: App twice");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
app = this;
|
||||||
|
signal(SIGINT,Stop);
|
||||||
|
signal(SIGTERM,Stop);
|
||||||
|
}
|
||||||
|
~App()
|
||||||
|
{}
|
||||||
|
bool operator!() const
|
||||||
|
{ return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::ostream& operator<<(std::ostream& os,const App& app)
|
||||||
|
{ return app.Print(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
60
auxil/bifcl/auxil/libunistd/portable/AtomicCounter.h
Normal file
60
auxil/bifcl/auxil/libunistd/portable/AtomicCounter.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// AtomicCounter.h
|
||||||
|
// 2014/3/17
|
||||||
|
|
||||||
|
#ifndef AtomicCounter_h
|
||||||
|
#define AtomicCounter_h
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class AtomicCounter
|
||||||
|
{ std::atomic<T> n;
|
||||||
|
public:
|
||||||
|
AtomicCounter<T>()
|
||||||
|
{ clear();
|
||||||
|
}
|
||||||
|
void clear()
|
||||||
|
{ n=0;
|
||||||
|
}
|
||||||
|
AtomicCounter<T>(T n)
|
||||||
|
{ this->n=n;
|
||||||
|
}
|
||||||
|
AtomicCounter<T>& operator=(const T rhs)
|
||||||
|
{ n=rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
T operator++(int)
|
||||||
|
{ return n.fetch_add(1);
|
||||||
|
}
|
||||||
|
T operator--(int)
|
||||||
|
{ return n.fetch_sub(1);
|
||||||
|
}
|
||||||
|
T operator++()
|
||||||
|
{ const T prev=n.fetch_add(1);
|
||||||
|
return prev+1;
|
||||||
|
}
|
||||||
|
T operator--()
|
||||||
|
{ const T prev=n.fetch_sub(1);
|
||||||
|
return prev-1;
|
||||||
|
}
|
||||||
|
operator T()
|
||||||
|
{ return n;
|
||||||
|
}
|
||||||
|
operator T() const
|
||||||
|
{ return n;
|
||||||
|
}
|
||||||
|
void Set(T n)
|
||||||
|
{ this->n=n;
|
||||||
|
}
|
||||||
|
T Get() const
|
||||||
|
{ return n;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
32
auxil/bifcl/auxil/libunistd/portable/AtomicLock.h
Normal file
32
auxil/bifcl/auxil/libunistd/portable/AtomicLock.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// AtomicLock.h
|
||||||
|
// Robin.Rowe@CinePaint.org 2014/8/22
|
||||||
|
|
||||||
|
#ifndef AtomicLock_h
|
||||||
|
#define AtomicLock_h
|
||||||
|
|
||||||
|
#include "AtomicCounter.h"
|
||||||
|
|
||||||
|
class AtomicLock
|
||||||
|
{ AtomicCounter<int> i;
|
||||||
|
public:
|
||||||
|
AtomicLock()
|
||||||
|
{}
|
||||||
|
bool IsLocked() const
|
||||||
|
{ return i==1;
|
||||||
|
}
|
||||||
|
bool Lock()
|
||||||
|
{ if(i!=0)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const int count=++i;
|
||||||
|
if(count!=1)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void Unlock()
|
||||||
|
{ i=0;
|
||||||
|
} };
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
25
auxil/bifcl/auxil/libunistd/portable/AtomicLock0.h
Normal file
25
auxil/bifcl/auxil/libunistd/portable/AtomicLock0.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// AtomicLock.h
|
||||||
|
// 2014/8/4
|
||||||
|
|
||||||
|
#ifndef AtomicLock_h
|
||||||
|
#define AtomicLock_h
|
||||||
|
|
||||||
|
#include "AtomicCounter.h"
|
||||||
|
|
||||||
|
class AtomicLock
|
||||||
|
{ AtomicCounter<int>& i;
|
||||||
|
int count;
|
||||||
|
public:
|
||||||
|
AtomicLock(AtomicCounter<int>& i)
|
||||||
|
: i(i)
|
||||||
|
{ count=++i;
|
||||||
|
}
|
||||||
|
~AtomicLock()
|
||||||
|
{ --i;
|
||||||
|
}
|
||||||
|
bool operator!() const
|
||||||
|
{ return count!=1;
|
||||||
|
} };
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
49
auxil/bifcl/auxil/libunistd/portable/AtomicMutex.h
Normal file
49
auxil/bifcl/auxil/libunistd/portable/AtomicMutex.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// libportable/AtomicMutex.h
|
||||||
|
// Robin.Rowe@cinepaint.org 2014/11/20
|
||||||
|
|
||||||
|
#ifndef AtomicMutex_h
|
||||||
|
#define AtomicMutex_h
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <AllowWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <HideWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class AtomicMutex
|
||||||
|
{ friend class SoftLock;
|
||||||
|
std::atomic<int> lock;
|
||||||
|
public:
|
||||||
|
AtomicMutex()
|
||||||
|
{ lock=0;
|
||||||
|
}
|
||||||
|
bool IsLocked() const
|
||||||
|
{ return 1==lock;
|
||||||
|
}
|
||||||
|
bool operator!() const
|
||||||
|
{ return !IsLocked();
|
||||||
|
}
|
||||||
|
bool Lock()
|
||||||
|
{ const int lockCount=lock.fetch_add(1,std::memory_order_relaxed)+1;
|
||||||
|
const bool isLocked = (1==lockCount);
|
||||||
|
if(!isLocked)
|
||||||
|
{ Unlock();
|
||||||
|
}
|
||||||
|
return isLocked;
|
||||||
|
}
|
||||||
|
int Unlock()
|
||||||
|
{ const int lockCount=lock.fetch_sub(1,std::memory_order_relaxed)-1;
|
||||||
|
return lockCount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
32
auxil/bifcl/auxil/libunistd/portable/Breakpoint.h
Normal file
32
auxil/bifcl/auxil/libunistd/portable/Breakpoint.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// portable/Breakpoint.h
|
||||||
|
// Created by Robin Rowe on 6/30/2015.
|
||||||
|
// Copyright (c) 2015 Robin.Rowe@CinePaint.org. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if defined(_DEBUG) && defined(_WIN32)
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
inline
|
||||||
|
void Breakpoint()
|
||||||
|
{ DebugBreak();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline
|
||||||
|
void Breakpoint()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/* How to breakpoint a cgi-bin:
|
||||||
|
|
||||||
|
#include "<portable/Breakpoint.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{ Breakpoint();//Launches VC++ and stops on bp here
|
||||||
|
.
|
||||||
|
. // your stuff...
|
||||||
|
.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
53
auxil/bifcl/auxil/libunistd/portable/Buffer.h
Normal file
53
auxil/bifcl/auxil/libunistd/portable/Buffer.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Buffer.h
|
||||||
|
// Copyright 2016/1/16 Robin.Rowe@cinepaint.org
|
||||||
|
// License open source MIT/BSD
|
||||||
|
|
||||||
|
#ifndef Buffer_h
|
||||||
|
#define Buffer_h
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T,unsigned bufsize>
|
||||||
|
class Buffer
|
||||||
|
{ T buffer[bufsize];
|
||||||
|
unsigned size;
|
||||||
|
public:
|
||||||
|
Buffer()
|
||||||
|
{ size=0;
|
||||||
|
}
|
||||||
|
T* get()
|
||||||
|
{ return buffer;
|
||||||
|
}
|
||||||
|
const T* get() const
|
||||||
|
{ return buffer;
|
||||||
|
}
|
||||||
|
unsigned capacity() const
|
||||||
|
{ return bufsize;
|
||||||
|
}
|
||||||
|
unsigned length() const
|
||||||
|
{ return size;
|
||||||
|
}
|
||||||
|
bool Append(T* data,unsigned length)
|
||||||
|
{ if (size + length > bufsize)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
memcpy(buffer+size,data,length);
|
||||||
|
size+=length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Append(T data)
|
||||||
|
{ if (size + sizeof(T) > bufsize)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
buffer[size]=data;
|
||||||
|
size++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
85
auxil/bifcl/auxil/libunistd/portable/CMakeLists.txt
Normal file
85
auxil/bifcl/auxil/libunistd/portable/CMakeLists.txt
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# libunistd/portable/CMakeLists.txt
|
||||||
|
|
||||||
|
project(libportable)
|
||||||
|
message("--- Building library ${PROJECT_NAME} ---")
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
# Astring.h
|
||||||
|
AtomicCounter.h
|
||||||
|
AtomicLock.h
|
||||||
|
AtomicLock0.h
|
||||||
|
AtomicMutex.h
|
||||||
|
Breakpoint.h
|
||||||
|
ipc/BsdMulticast.h
|
||||||
|
ipc/BsdPacketServer.h
|
||||||
|
ipc/BsdSocket.h
|
||||||
|
ipc/BsdSocketClient.h
|
||||||
|
ipc/BsdSocketPool.h
|
||||||
|
ipc/BsdSocketServer.h
|
||||||
|
ipc/BsdSocketStartup.h
|
||||||
|
Buffer.h
|
||||||
|
Cfile.h
|
||||||
|
CommandLine.h
|
||||||
|
Counter.h
|
||||||
|
CppTypes.h
|
||||||
|
endian.h
|
||||||
|
Finder.h
|
||||||
|
Folder.h
|
||||||
|
homedir.h
|
||||||
|
http/HtmlPage.h
|
||||||
|
http/Http.h
|
||||||
|
http/HttpDecoder.h
|
||||||
|
Logger.h
|
||||||
|
MsgBuffer.h
|
||||||
|
Network.h
|
||||||
|
ipc/Packet.h
|
||||||
|
ipc/PacketBuffer.h
|
||||||
|
ipc/PacketMarker.h
|
||||||
|
ipc/PacketQueue.h
|
||||||
|
ipc/PacketReader.h
|
||||||
|
ipc/PacketSizer.h
|
||||||
|
ipc/PacketWriter.h
|
||||||
|
QtHelpers.h
|
||||||
|
pump/Pump.h
|
||||||
|
Random.h
|
||||||
|
SoftLock.h
|
||||||
|
StdBlob.h
|
||||||
|
StdCopy.h
|
||||||
|
StdDevice.h
|
||||||
|
StdFile.h
|
||||||
|
StdPipe.h
|
||||||
|
strcpy.h
|
||||||
|
stub.h
|
||||||
|
SystemCall.h
|
||||||
|
thread_semaphore.h
|
||||||
|
time/Timecode.h
|
||||||
|
pump/TimerPump.h
|
||||||
|
time/Timespan.h
|
||||||
|
time/Timestamp.h
|
||||||
|
UnrealLogger.h
|
||||||
|
time/VariableClock.h
|
||||||
|
Vec3d.h
|
||||||
|
VerboseCounter.h
|
||||||
|
time/WallClock.h
|
||||||
|
time/Watchdog.h
|
||||||
|
WormFile.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCE
|
||||||
|
ipc/BsdPacketServer.cpp
|
||||||
|
ipc/BsdSocket.cpp
|
||||||
|
ipc/BsdSocketClient.cpp
|
||||||
|
ipc/BsdSocketPool.cpp
|
||||||
|
ipc/BsdSocketServer.cpp
|
||||||
|
ipc/BsdSocketStartup.cpp
|
||||||
|
CommandLine.cpp
|
||||||
|
http/Http.cpp
|
||||||
|
Network.cpp
|
||||||
|
ipc/PacketReader.cpp
|
||||||
|
pump/Pump.cpp
|
||||||
|
time/Timestamp.cpp
|
||||||
|
time/VariableClock.cpp
|
||||||
|
WormFile.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} STATIC ${HEADERS} ${SOURCE})
|
||||||
43
auxil/bifcl/auxil/libunistd/portable/Cfile.h
Normal file
43
auxil/bifcl/auxil/libunistd/portable/Cfile.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Cfile.h
|
||||||
|
// Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef Cfile_h
|
||||||
|
#define Cfile_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
|
||||||
|
class Cfile
|
||||||
|
{ FILE* fp;
|
||||||
|
public:
|
||||||
|
~Cfile()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
Cfile()
|
||||||
|
: fp(nullptr)
|
||||||
|
{}
|
||||||
|
bool operator!() const
|
||||||
|
{ return !fp;
|
||||||
|
}
|
||||||
|
Cfile(const char* filename,const char* mode)
|
||||||
|
{ Open(filename,mode);
|
||||||
|
}
|
||||||
|
bool Open(const char* filename,const char* mode)
|
||||||
|
{ fp=fopen(filename,mode);
|
||||||
|
return nullptr!=fp;
|
||||||
|
}
|
||||||
|
void Close()
|
||||||
|
{ if(fp)
|
||||||
|
{ fclose(fp);
|
||||||
|
fp=nullptr;
|
||||||
|
} }
|
||||||
|
operator FILE*()
|
||||||
|
{ return fp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
|
||||||
|
#endif
|
||||||
40
auxil/bifcl/auxil/libunistd/portable/CommandLine.cpp
Normal file
40
auxil/bifcl/auxil/libunistd/portable/CommandLine.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// CommandLine.cpp
|
||||||
|
// Libunistd Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#include "CommandLine.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
void CommandLine::Set(int argc,const char** argv)
|
||||||
|
{ this->argc = argc;
|
||||||
|
this->argv = argv;
|
||||||
|
// skip arg[0] = prog_name
|
||||||
|
for(int i=1;i<argc;i++)
|
||||||
|
{ Append(argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandLine::Append(const char* keyval)
|
||||||
|
{ const char* eq = strchr(keyval,'=');
|
||||||
|
if(eq)
|
||||||
|
{ std::string key(keyval,eq-keyval);
|
||||||
|
data[std::move(key)]=eq+1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data[keyval] = "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CommandLine::toString()
|
||||||
|
{ std::string s;
|
||||||
|
for(int i=0;i<argc;i++)
|
||||||
|
{ if(argv[i])
|
||||||
|
{ s+=argv[i];
|
||||||
|
s+=" ";
|
||||||
|
} }
|
||||||
|
s.pop_back();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//portable
|
||||||
64
auxil/bifcl/auxil/libunistd/portable/CommandLine.h
Normal file
64
auxil/bifcl/auxil/libunistd/portable/CommandLine.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// CommandLine.h
|
||||||
|
// Libunistd Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef CommandLine_h
|
||||||
|
#define CommandLine_h
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class CommandLine
|
||||||
|
{ std::map<std::string,std::string> data;
|
||||||
|
int argc;
|
||||||
|
const char** argv;
|
||||||
|
public:
|
||||||
|
CommandLine()
|
||||||
|
{ argc = 0;
|
||||||
|
argv = nullptr;
|
||||||
|
}
|
||||||
|
CommandLine(int argc,const char** argv)
|
||||||
|
{ Set(argc,argv);
|
||||||
|
}
|
||||||
|
void Set(int argc,const char** argv);
|
||||||
|
void Append(const char* keyval);
|
||||||
|
const char* Get(const char* key) const
|
||||||
|
{ const auto it = data.find(key);
|
||||||
|
if(data.end()==it)
|
||||||
|
{ return nullptr;
|
||||||
|
}
|
||||||
|
const char* value = it->second.c_str();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
bool Get(const char* key,int& i) const
|
||||||
|
{ const char* value = Get(key);
|
||||||
|
if(!value)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
i = atoi(value);
|
||||||
|
return errno != EINVAL;
|
||||||
|
}
|
||||||
|
const char* operator[](int i) const
|
||||||
|
{ if(i<0)
|
||||||
|
{ i = argc+i;
|
||||||
|
}
|
||||||
|
if(i>=argc)
|
||||||
|
{ return "";
|
||||||
|
}
|
||||||
|
return argv[i];
|
||||||
|
}
|
||||||
|
bool IsKey(const char* key) const
|
||||||
|
{ const auto it = data.find(key);
|
||||||
|
return data.end()!=it;
|
||||||
|
}
|
||||||
|
std::string toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
26
auxil/bifcl/auxil/libunistd/portable/Counter.h
Normal file
26
auxil/bifcl/auxil/libunistd/portable/Counter.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Counter.h
|
||||||
|
// Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef Counter_h
|
||||||
|
#define Counter_h
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Counter
|
||||||
|
{ unsigned count;
|
||||||
|
std::string s;
|
||||||
|
public:
|
||||||
|
Counter()
|
||||||
|
: count(0)
|
||||||
|
{}
|
||||||
|
const char* operator ()(const char* msg)
|
||||||
|
{ count++;
|
||||||
|
s=std::to_string(count);
|
||||||
|
s.append(": ");
|
||||||
|
s.append(msg);
|
||||||
|
return s.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
178
auxil/bifcl/auxil/libunistd/portable/CppTypes.h
Normal file
178
auxil/bifcl/auxil/libunistd/portable/CppTypes.h
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
// libportable/CppTypes.h
|
||||||
|
// 2014/11/24 Robin.Rowe@cinepaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef CppTypes_h
|
||||||
|
#define CppTypes_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
namespace portable {
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Bool
|
||||||
|
{ bool tf;
|
||||||
|
public:
|
||||||
|
Bool(const char* cs,bool def=false)
|
||||||
|
: tf(false)
|
||||||
|
{ if(!cs)
|
||||||
|
{ tf=def;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(*cs=='t'||*cs=='T')
|
||||||
|
{ tf=true;
|
||||||
|
} }
|
||||||
|
const char* toString() const
|
||||||
|
{ return tf? "T":"F";
|
||||||
|
}
|
||||||
|
operator bool() const
|
||||||
|
{ return tf;
|
||||||
|
} };
|
||||||
|
|
||||||
|
#pragma warning (disable:4996)
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
size_t StringToType(const char* cs,const char* formatting,T& t)
|
||||||
|
{ const size_t size=sscanf(cs,formatting,&t);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
size_t TypeToString(char* buffer,size_t bufsize,const char* formatting,const T& t)
|
||||||
|
{ const size_t size=snprintf(buffer,bufsize,formatting,t);
|
||||||
|
if(size>0)
|
||||||
|
{ buffer[size]=0;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning (default:4996)
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class CppInBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppInBuffer(const char* cs,short& x)
|
||||||
|
{ StringToType(cs,"%hd",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,unsigned short& x)
|
||||||
|
{ StringToType(cs,"%hu",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,int& x)
|
||||||
|
{ StringToType(cs,"%d",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,unsigned int& x)
|
||||||
|
{ StringToType(cs,"%u",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,long& x)
|
||||||
|
{ StringToType(cs,"%ld",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,unsigned long& x)
|
||||||
|
{ StringToType(cs,"%lu",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,long long& x)
|
||||||
|
{ StringToType(cs,"%lld",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,unsigned long long& x)
|
||||||
|
{ StringToType(cs,"%llu",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,float& x)
|
||||||
|
{ StringToType(cs,"%f",x);
|
||||||
|
}
|
||||||
|
CppInBuffer(const char* cs,double& x)
|
||||||
|
{ StringToType(cs,"%lf",x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class CppOutBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,short& x)
|
||||||
|
{ TypeToString(buffer,size,"%hd",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,unsigned short& x)
|
||||||
|
{ TypeToString(buffer,size,"%hu",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,int& x)
|
||||||
|
{ TypeToString(buffer,size,"%d",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,unsigned int& x)
|
||||||
|
{ TypeToString(buffer,size,"%u",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,long& x)
|
||||||
|
{ TypeToString(buffer,size,"%ld",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,unsigned long& x)
|
||||||
|
{ TypeToString(buffer,size,"%lu",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,long long& x)
|
||||||
|
{ TypeToString(buffer,size,"%lld",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,unsigned long long& x)
|
||||||
|
{ TypeToString(buffer,size,"%llu",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,float& x)
|
||||||
|
{ TypeToString(buffer,size,"%f",x);
|
||||||
|
}
|
||||||
|
CppOutBuffer(char* buffer,unsigned size,double& x)
|
||||||
|
{ TypeToString(buffer,size,"%lf",x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class CppType
|
||||||
|
{ T x;
|
||||||
|
//unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
|
||||||
|
enum {bufsize=28};
|
||||||
|
char buffer[bufsize];
|
||||||
|
public:
|
||||||
|
CppType<T>(T x)
|
||||||
|
: x(x)
|
||||||
|
{}
|
||||||
|
CppType<T>(const char* data)
|
||||||
|
: x(0)
|
||||||
|
{ if(!data)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
strncat(buffer,data,bufsize-1);
|
||||||
|
CppInBuffer<T> temp(buffer,x);
|
||||||
|
}
|
||||||
|
const char* toString()
|
||||||
|
{ if(!buffer[0])
|
||||||
|
{ CppOutBuffer<T> temp(buffer,bufsize,x);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
operator const char*()
|
||||||
|
{ return toString();
|
||||||
|
}
|
||||||
|
operator T() const
|
||||||
|
{ return x;
|
||||||
|
}
|
||||||
|
void SetSeparators(char comma=',')
|
||||||
|
{ const size_t width=strlen(buffer);
|
||||||
|
while(width>3)
|
||||||
|
{ const size_t commas=width/3-1;
|
||||||
|
buffer[buffsize-width-commas]=buffer[bufsize-width];
|
||||||
|
if(1==width%3)
|
||||||
|
{ buffer[buffsize-width-commas+1]=comma;
|
||||||
|
}
|
||||||
|
width--;
|
||||||
|
} }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef CppType<short> Short;
|
||||||
|
typedef CppType<int> Int;
|
||||||
|
typedef CppType<unsigned> Unsigned;
|
||||||
|
typedef CppType<long long> LongLong;
|
||||||
|
typedef CppType<unsigned long long> UnsignedLongLong;
|
||||||
|
typedef CppType<float> Float;
|
||||||
|
typedef CppType<double> Double;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
50
auxil/bifcl/auxil/libunistd/portable/Db.h
Normal file
50
auxil/bifcl/auxil/libunistd/portable/Db.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// portable/Db.h
|
||||||
|
// Robin.Rowe@Cinepaint.org
|
||||||
|
// 2015/8/3
|
||||||
|
|
||||||
|
#ifndef PortableDb_h
|
||||||
|
#define PortableDb_h
|
||||||
|
|
||||||
|
namespace portable {
|
||||||
|
|
||||||
|
class Db
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef int (*DbCallback)(void*,int,char**,char**);
|
||||||
|
virtual ~Db()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
virtual bool IsExist(const char* dbName) const = 0;
|
||||||
|
virtual bool IsOpen() const = 0;
|
||||||
|
virtual bool Open(const char* dbName) = 0;
|
||||||
|
virtual void Close()
|
||||||
|
{}
|
||||||
|
virtual bool Exec(const char* ,DbCallback )
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
bool IsFile(const char* filename) const
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
struct __stat64 st;
|
||||||
|
const int err = _stat64(filename, &st);
|
||||||
|
if(err!=0)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
struct stat st;
|
||||||
|
const int err = stat(filename, &st);
|
||||||
|
if(err!=0)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void DropFile(const char* filename)
|
||||||
|
{ remove(filename);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
124
auxil/bifcl/auxil/libunistd/portable/FieldMap.h
Normal file
124
auxil/bifcl/auxil/libunistd/portable/FieldMap.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// FieldMap.h
|
||||||
|
// Copyright 2018/8/3 Robin.Rowe@cinepaint.org
|
||||||
|
// License MIT open source
|
||||||
|
|
||||||
|
#ifndef FieldMap_h
|
||||||
|
#define FieldMap_h
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string_view>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct string_view_compare
|
||||||
|
{ bool operator() (const T& x, const T& y) const
|
||||||
|
{ return x.compare(y)<0;
|
||||||
|
} };
|
||||||
|
|
||||||
|
class FieldMap
|
||||||
|
{ char* p;
|
||||||
|
std::string_view empty;
|
||||||
|
// std::map<std::string_view,std::string_view,string_view_compare<std::string_view> > m;
|
||||||
|
std::map<unsigned,std::string_view> m;
|
||||||
|
std::string_view StripFieldname(std::string_view text) const
|
||||||
|
{ if(text.empty())
|
||||||
|
{ return text;
|
||||||
|
}
|
||||||
|
auto offset = text.find(": ");
|
||||||
|
if(offset == text.npos)
|
||||||
|
{ return text;
|
||||||
|
}
|
||||||
|
text.remove_prefix(offset+2);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
FieldMap()
|
||||||
|
{ p = nullptr;
|
||||||
|
}
|
||||||
|
void Clear()
|
||||||
|
{ p=0;
|
||||||
|
m.clear();
|
||||||
|
}
|
||||||
|
void Set(char* data)
|
||||||
|
{ p = data;
|
||||||
|
}
|
||||||
|
std::string_view& Find(int key)
|
||||||
|
{ auto it = m.find(key);
|
||||||
|
if(it == m.end())
|
||||||
|
{ return empty;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
const std::string_view& Find(int key) const
|
||||||
|
{ auto it = m.find(key);
|
||||||
|
if(it == m.end())
|
||||||
|
{ return empty;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
std::string_view& operator[](int key)
|
||||||
|
{ return Find(key);
|
||||||
|
}
|
||||||
|
std::string_view operator[](int key) const
|
||||||
|
{ return Find(key);
|
||||||
|
}
|
||||||
|
bool AdvancePast(const char* text)
|
||||||
|
{ char* seek = strstr(p,text);
|
||||||
|
if(!seek)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
p = seek + 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
char* SkipWhitespace()
|
||||||
|
{ while(isspace(*p))
|
||||||
|
{ p++;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
char* Find(char c)
|
||||||
|
{ return strchr(p,c);
|
||||||
|
}
|
||||||
|
bool IsInvalid(unsigned i) const
|
||||||
|
{ return m.size()<=i;
|
||||||
|
}
|
||||||
|
string_view GetFieldData(unsigned i)
|
||||||
|
{ if(IsInvalid(i))
|
||||||
|
{ return empty;
|
||||||
|
}
|
||||||
|
return m[i];
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
string_view GetFieldData(unsigned i) const
|
||||||
|
{ if(IsInvalid(i))
|
||||||
|
{ return empty;
|
||||||
|
}
|
||||||
|
return m[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
string_view operator[](unsigned i)
|
||||||
|
{ return StripFieldname(GetFieldData(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
char* Parse(const char* fieldName,unsigned i)
|
||||||
|
{
|
||||||
|
if(IsInvalid(i))
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
char* found = strstr(p,fieldName);
|
||||||
|
if(!found)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
m[i] = found;
|
||||||
|
p = found + 1;
|
||||||
|
char* ends = strchr(p,'\n');
|
||||||
|
if(ends)
|
||||||
|
{ *ends= 0;
|
||||||
|
p = ends + 1;
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
142
auxil/bifcl/auxil/libunistd/portable/Finder.h
Normal file
142
auxil/bifcl/auxil/libunistd/portable/Finder.h
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// Finder.h
|
||||||
|
// Copyright 2018/11/04 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef Filer_h
|
||||||
|
#define Filer_h
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#pragma comment(lib, "User32.lib")
|
||||||
|
|
||||||
|
#define WIN_NO_ERROR 0 // WIN_NO_ERROR = NO_ERROR As we are undeffing `NO_ERROR` to avoid naming collision in unistd.h
|
||||||
|
|
||||||
|
namespace portable {
|
||||||
|
|
||||||
|
class Finder
|
||||||
|
: public DIR
|
||||||
|
{public:
|
||||||
|
WIN32_FIND_DATA data;
|
||||||
|
HANDLE h;
|
||||||
|
DWORD error;
|
||||||
|
char path[MAX_PATH];
|
||||||
|
long tell;
|
||||||
|
void Reset()
|
||||||
|
{ memset(this,0,sizeof(*this));
|
||||||
|
h = INVALID_HANDLE_VALUE;
|
||||||
|
error = WIN_NO_ERROR;//ERROR_NO_MORE_FILES;
|
||||||
|
}
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
#pragma warning(disable:26495)
|
||||||
|
Finder()
|
||||||
|
{ Reset();
|
||||||
|
}
|
||||||
|
void SetPath(const char* path)
|
||||||
|
{ strcpy(this->path,path);
|
||||||
|
strcat(this->path,"\\*");
|
||||||
|
}
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
#pragma warning(default:26495)
|
||||||
|
bool Open()
|
||||||
|
{ h = FindFirstFile(path,&data);
|
||||||
|
if(INVALID_HANDLE_VALUE == h)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Open(const char* path)
|
||||||
|
{ SetPath(path);
|
||||||
|
return Open();
|
||||||
|
}
|
||||||
|
bool IsDir() const
|
||||||
|
{ if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{ return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
long long GetFileSize() const
|
||||||
|
{ LARGE_INTEGER filesize;
|
||||||
|
filesize.LowPart = data.nFileSizeLow;
|
||||||
|
filesize.HighPart = data.nFileSizeHigh;
|
||||||
|
return filesize.QuadPart;
|
||||||
|
}
|
||||||
|
bool IsGood() const
|
||||||
|
{ if(h == INVALID_HANDLE_VALUE)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
if(error != ERROR_NO_MORE_FILES && error != WIN_NO_ERROR)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool IsEof() const
|
||||||
|
{ return error == ERROR_NO_MORE_FILES;
|
||||||
|
}
|
||||||
|
bool Read()
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
if(!tell)
|
||||||
|
{ tell = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(!FindNextFile(h,&data))
|
||||||
|
{ error = GetLastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tell++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Seek(long pos)
|
||||||
|
{ while(Tell() < pos)
|
||||||
|
{ if(!Read())
|
||||||
|
{ if(Tell() == pos)
|
||||||
|
{ return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void Close()
|
||||||
|
{ if(h != INVALID_HANDLE_VALUE)
|
||||||
|
{ FindClose(h);
|
||||||
|
h = INVALID_HANDLE_VALUE;
|
||||||
|
} }
|
||||||
|
void Rewind()
|
||||||
|
{ Close();
|
||||||
|
Open();
|
||||||
|
}
|
||||||
|
long Tell() const
|
||||||
|
{ return tell;
|
||||||
|
}
|
||||||
|
void Set(dirent* entry)
|
||||||
|
{ if(!entry)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
entry->d_ino = 0;
|
||||||
|
entry->d_reclen = sizeof(data.cFileName);
|
||||||
|
entry->d_type=DT_UNKNOWN;
|
||||||
|
entry->d_name = data.cFileName;
|
||||||
|
entry->d_namlen = (unsigned short) strlen(entry->d_name);
|
||||||
|
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{ entry->d_type = DT_DIR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ entry->d_type = DT_REG;
|
||||||
|
} }
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
146
auxil/bifcl/auxil/libunistd/portable/FixedQueue.h
Normal file
146
auxil/bifcl/auxil/libunistd/portable/FixedQueue.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// queue::push/pop
|
||||||
|
#include <iostream> // std::cin, std::cout
|
||||||
|
#include <queue> // std::queue
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
std::queue<int> myqueue;
|
||||||
|
int myint;
|
||||||
|
|
||||||
|
std::cout << "Please enter some integers (enter 0 to end):\n";
|
||||||
|
|
||||||
|
do {
|
||||||
|
std::cin >> myint;
|
||||||
|
myqueue.push (myint);
|
||||||
|
} while (myint);
|
||||||
|
|
||||||
|
std::cout << "myqueue contains: ";
|
||||||
|
while (!myqueue.empty())
|
||||||
|
{
|
||||||
|
std::cout << ' ' << myqueue.front();
|
||||||
|
myqueue.pop();
|
||||||
|
}
|
||||||
|
std::cout << '\n';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<t> v;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class IpcQueue
|
||||||
|
{ T* data;
|
||||||
|
size_t size;
|
||||||
|
size_t head;
|
||||||
|
size_t tail;
|
||||||
|
public:
|
||||||
|
IpcQueue(T* memory,size_t size)
|
||||||
|
: memory(memory)
|
||||||
|
, size(size)
|
||||||
|
, head(0)
|
||||||
|
, tail(0)
|
||||||
|
{}
|
||||||
|
bool empty() const
|
||||||
|
{ return head == tail;
|
||||||
|
}
|
||||||
|
size_t count() const
|
||||||
|
{ if(head<=tail)
|
||||||
|
{ return tail-head;
|
||||||
|
}
|
||||||
|
return size-head+tail;
|
||||||
|
}
|
||||||
|
bool full() const
|
||||||
|
{ return count() == size();
|
||||||
|
}
|
||||||
|
bool push(T&& x)
|
||||||
|
{ if(full())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
data[tail]=x;
|
||||||
|
tail++;
|
||||||
|
if(tail>=size)
|
||||||
|
{ tail = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
T& front()
|
||||||
|
{ return data[head];
|
||||||
|
}
|
||||||
|
const T& front() const
|
||||||
|
{ return data[head];
|
||||||
|
}
|
||||||
|
bool pop()
|
||||||
|
{ if(empty())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
head++;
|
||||||
|
if(head>=size)
|
||||||
|
{ head = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void enqueue(node_t **head, int val) {
|
||||||
|
node_t *new_node = malloc(sizeof(node_t));
|
||||||
|
if (!new_node) return;
|
||||||
|
|
||||||
|
new_node->val = val;
|
||||||
|
new_node->next = *head;
|
||||||
|
|
||||||
|
*head = new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dequeue(node_t **head) {
|
||||||
|
node_t *current, *prev = NULL;
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
if (*head == NULL) return -1;
|
||||||
|
|
||||||
|
current = *head;
|
||||||
|
while (current->next != NULL) {
|
||||||
|
prev = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = current->val;
|
||||||
|
free(current);
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
prev->next = NULL;
|
||||||
|
else
|
||||||
|
*head = NULL;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_list(node_t *head) {
|
||||||
|
node_t *current = head;
|
||||||
|
|
||||||
|
while (current != NULL) {
|
||||||
|
printf("%d\n", current->val);
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
node_t *head = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
enqueue(&head, 11);
|
||||||
|
enqueue(&head, 22);
|
||||||
|
enqueue(&head, 33);
|
||||||
|
enqueue(&head, 44);
|
||||||
|
|
||||||
|
print_list(head);
|
||||||
|
|
||||||
|
while ((ret=dequeue(&head)) > 0) {
|
||||||
|
printf("dequeued %d\n", ret);
|
||||||
|
}
|
||||||
|
printf("done. head=%p\n", head);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
32
auxil/bifcl/auxil/libunistd/portable/Folder.h
Normal file
32
auxil/bifcl/auxil/libunistd/portable/Folder.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// portable/Folder.h
|
||||||
|
// Copyright 2016/1/16 Robin.Rowe@cinepaint.org
|
||||||
|
// License open source MIT/BSD
|
||||||
|
|
||||||
|
#ifndef Folder_h
|
||||||
|
#define Folder_h
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <ShlObj.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
void GetHomePath(std::string& folderPath,bool isForwardSlashes=true)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
TCHAR path[MAX_PATH];
|
||||||
|
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path)))
|
||||||
|
{ folderPath= path;
|
||||||
|
if(isForwardSlashes)
|
||||||
|
{ std::replace(folderPath.begin(), folderPath.end(), '\\', '/');
|
||||||
|
} }
|
||||||
|
#else
|
||||||
|
//bug
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
13
auxil/bifcl/auxil/libunistd/portable/Hash.h
Normal file
13
auxil/bifcl/auxil/libunistd/portable/Hash.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T Hash_djb2(const char* s)
|
||||||
|
{ if(!s)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
const size_t size = strlen(s);
|
||||||
|
T hash = 5381;
|
||||||
|
for(size_t = 0;i<size;i++)
|
||||||
|
{ hash =<< 5 + hash + s[i];
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
9
auxil/bifcl/auxil/libunistd/portable/Logger.h
Normal file
9
auxil/bifcl/auxil/libunistd/portable/Logger.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Logger.h
|
||||||
|
// Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// Open source license MIT
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include "UnrealLogger.h"
|
||||||
|
#else
|
||||||
|
#include "SystemLog.h"
|
||||||
|
#endif
|
||||||
149
auxil/bifcl/auxil/libunistd/portable/MemPool.h
Normal file
149
auxil/bifcl/auxil/libunistd/portable/MemPool.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// MemPool.h
|
||||||
|
// Created by Robin Rowe on 12/2/2015
|
||||||
|
// Copyright (c) 2015 Robin.Rowe@CinePaint.org
|
||||||
|
|
||||||
|
#ifndef AtomicMemPool_h
|
||||||
|
#define AtomicMemPool_h
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace Atomic
|
||||||
|
{
|
||||||
|
|
||||||
|
// Usage: HiddenMemPool intended for internal use
|
||||||
|
|
||||||
|
class HiddenMemPool
|
||||||
|
{ std::unique_ptr<char[]> data;
|
||||||
|
std::atomic<unsigned> bytes;
|
||||||
|
const unsigned size;
|
||||||
|
static void SetBlockSize(char* block,unsigned blockSize)
|
||||||
|
{ memcpy(block,&blockSize,sizeof(blockSize));
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
HiddenMemPool(unsigned size)
|
||||||
|
: size(size)
|
||||||
|
{ data=std::unique_ptr<char[]>(new char[size]);
|
||||||
|
}
|
||||||
|
bool IsEmpty() const
|
||||||
|
{ return 0==bytes;
|
||||||
|
}
|
||||||
|
static unsigned GetBlockSize(char* block)
|
||||||
|
{ if(!block)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
unsigned blockSize;
|
||||||
|
memcpy(&blockSize,block-sizeof(blockSize),sizeof(blockSize));
|
||||||
|
return blockSize;
|
||||||
|
}
|
||||||
|
char* NewBlock(unsigned blockSize)
|
||||||
|
{ blockSize+=sizeof(blockSize);
|
||||||
|
const unsigned end=bytes.fetch_add(blockSize,std::memory_order_relaxed);
|
||||||
|
if(end>=size)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
char* rawBlock=data.get()+end-blockSize;
|
||||||
|
SetBlockSize(rawBlock,blockSize);
|
||||||
|
return rawBlock+sizeof(blockSize);
|
||||||
|
}
|
||||||
|
void FreeBlock(char* block)
|
||||||
|
{ const int blockSize=GetBlockSize(block);
|
||||||
|
bytes.fetch_sub(blockSize,std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
bool IsMyBlock(char* block)
|
||||||
|
{ block-=sizeof(size);
|
||||||
|
if(block<data.get() || block>=data.get())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Usage: Atomic::MemPool memPool(memoryBufferSize);
|
||||||
|
// const unsigned size=200;
|
||||||
|
// char* block=memPool.NewBlock(size);
|
||||||
|
// memPool.FreeBlock(block);
|
||||||
|
// Note: size==memPool.BlockSize(block);
|
||||||
|
|
||||||
|
class MemPool
|
||||||
|
{ HiddenMemPool a;
|
||||||
|
HiddenMemPool b;
|
||||||
|
HiddenMemPool* activePool;
|
||||||
|
typedef std::lock_guard<std::mutex> LockGuard;
|
||||||
|
std::mutex switchMutex;
|
||||||
|
bool SwitchPools()
|
||||||
|
{ if(&a==activePool)
|
||||||
|
{ if(!b.IsEmpty())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
activePool=&b;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(!a.IsEmpty())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
activePool=&a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
MemPool(unsigned size)
|
||||||
|
: a(size/2)
|
||||||
|
, b(size/2)
|
||||||
|
{ activePool=&a;
|
||||||
|
}
|
||||||
|
char* NewBlock(unsigned blockSize)
|
||||||
|
{ char* data=activePool->NewBlock(blockSize);
|
||||||
|
if(data)
|
||||||
|
{ return data;
|
||||||
|
}
|
||||||
|
LockGuard lockGuard(switchMutex);//Lock only on wrap-around
|
||||||
|
data=activePool->NewBlock(blockSize);//re-entrant
|
||||||
|
if(data)
|
||||||
|
{ return data;
|
||||||
|
}
|
||||||
|
if(!SwitchPools())
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
data=activePool->NewBlock(blockSize);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
bool FreeBlock(char* block)
|
||||||
|
{ if(a.IsMyBlock(block))
|
||||||
|
{ a.FreeBlock(block);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(b.IsMyBlock(block))
|
||||||
|
{ b.FreeBlock(block);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned GetBlockSize(char* block)
|
||||||
|
{ return HiddenMemPool::GetBlockSize(block);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Usage: Atomic::MemPoolBlock memPoolBlock(memPool,packetQueue.Pop());
|
||||||
|
// char* p=memPoolBlock.get();
|
||||||
|
// Note: Destructor will automatically free block
|
||||||
|
|
||||||
|
class MemPoolBlock
|
||||||
|
{ MemPool& memPool;
|
||||||
|
char* block;
|
||||||
|
public:
|
||||||
|
~MemPoolBlock()
|
||||||
|
{ memPool.FreeBlock(block);
|
||||||
|
}
|
||||||
|
MemPoolBlock(MemPool& memPool,char* block)
|
||||||
|
: memPool(memPool)
|
||||||
|
, block(block)
|
||||||
|
{}
|
||||||
|
char* get()
|
||||||
|
{ return block;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
106
auxil/bifcl/auxil/libunistd/portable/MsgBuffer.h
Normal file
106
auxil/bifcl/auxil/libunistd/portable/MsgBuffer.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// MsgBuffer.h
|
||||||
|
// Created by Robin Rowe on 1/2/2016
|
||||||
|
// Copyright (c) 2016 Robin.Rowe@CinePaint.org
|
||||||
|
|
||||||
|
#ifndef MsgBuffer_h
|
||||||
|
#define MsgBuffer_h
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <AllowWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Winsock2.h>
|
||||||
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
template<unsigned bufsize>
|
||||||
|
class MsgBuffer
|
||||||
|
{ char buffer[bufsize];
|
||||||
|
void SetPerErrno()
|
||||||
|
{ char* p=strerror(errno);
|
||||||
|
Append(p);
|
||||||
|
}
|
||||||
|
void SetPerLastError()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
const unsigned len = length();
|
||||||
|
const DWORD num = FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
WSAGetLastError(),
|
||||||
|
0,
|
||||||
|
buffer+len,
|
||||||
|
bufsize-len-1,
|
||||||
|
NULL);
|
||||||
|
#else
|
||||||
|
SetPerErrno();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
MsgBuffer()
|
||||||
|
{ Reset();
|
||||||
|
}
|
||||||
|
void Reset()
|
||||||
|
{ buffer[0]=0;
|
||||||
|
}
|
||||||
|
operator const char*() const
|
||||||
|
{ return buffer;
|
||||||
|
}
|
||||||
|
const char* GetErrnoError()
|
||||||
|
{ SetPerErrno();
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
const char* GetLastError()
|
||||||
|
{ SetPerLastError();
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
int GetErrno()
|
||||||
|
{ return errno;
|
||||||
|
}
|
||||||
|
int GetSocketErrorCode()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return WSAGetLastError();
|
||||||
|
#else
|
||||||
|
return GetErrno();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
unsigned length() const
|
||||||
|
{ return (unsigned) strlen(buffer);
|
||||||
|
}
|
||||||
|
unsigned capacity() const
|
||||||
|
{ return bufsize-1;
|
||||||
|
}
|
||||||
|
void Append(const char* text)
|
||||||
|
{ const unsigned len=length();
|
||||||
|
#pragma warning (disable : 4996)
|
||||||
|
strncpy(buffer+len,text,bufsize-len-1);
|
||||||
|
#pragma warning (default : 4996)
|
||||||
|
buffer[bufsize-1]=0;
|
||||||
|
}
|
||||||
|
void Set(const char* text)
|
||||||
|
{ Reset();
|
||||||
|
Append(text);
|
||||||
|
}
|
||||||
|
void SystemLog() const
|
||||||
|
{ puts(buffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <HideWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
353
auxil/bifcl/auxil/libunistd/portable/Network.cpp
Normal file
353
auxil/bifcl/auxil/libunistd/portable/Network.cpp
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
// Network.cpp
|
||||||
|
// Libunistd Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include "Network.h"
|
||||||
|
#include "StdFile.h"
|
||||||
|
#include "StdBlob.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define SUPPRESS_SECURITY_WARNING __pragma(warning(suppress:4996))
|
||||||
|
#else
|
||||||
|
#define SUPPRESS_SECURITY_WARNING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CHECK(var) if(var!=ifstat->var){ ifstat->var=var; isChanged = true;}
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
const char* output_proc_net_route =
|
||||||
|
"Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT\n"
|
||||||
|
"eth0 00000000 0202000A 0003 0 0 100 00000000 0 0 1\n"
|
||||||
|
"eth1 0002000A 00000000 0001 0 0 100 00FFFFFF 0 0 2\n";
|
||||||
|
|
||||||
|
const char* output_proc_net_dev =
|
||||||
|
"Inter-| Receive | Transmit\n"
|
||||||
|
" face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n"
|
||||||
|
" lo: 13380 87 0 0 0 0 0 0 13380 87 0 0 0 0 0 0\n"
|
||||||
|
" eth0: 279068630 1507895 0 0 0 0 0 0 567397982 852533 0 0 0 0 0 0\n"
|
||||||
|
" eth1: 1090810015 4017054 42 0 0 0 0 0 13975469 134398 0 0 0 0 0 0\n";
|
||||||
|
|
||||||
|
Network::Network(unsigned interfaceCount)
|
||||||
|
: isChanged(false)
|
||||||
|
, interfaces(0)
|
||||||
|
{ ifStats.resize(interfaceCount);
|
||||||
|
route_filename = "/proc/net/route";
|
||||||
|
dev_filename = "/proc/net/dev";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (size = 450 +4 = 77 + 123 + 2*125 + 4 LF)
|
||||||
|
root@vm-ubuntu:/opt/toolchains# cat /proc/net/dev
|
||||||
|
Inter-| Receive | Transmit
|
||||||
|
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
|
||||||
|
enth0: 616352817 446732 0 0 0 0 0 0 13516902 165770 0 0 0 0 0 0
|
||||||
|
enth1: 485454 4814 0 0 0 0 0 0 485454 502 0 0 0 0 0 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool Network::UpdateIfStats()
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
StdBlob proc_net_dev(output_proc_net_dev);
|
||||||
|
#else
|
||||||
|
StdFile proc_net_dev;
|
||||||
|
if(!proc_net_dev.Open(dev_filename, "r"))
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
proc_net_dev.SkipLine();
|
||||||
|
proc_net_dev.SkipLine();
|
||||||
|
unsigned lineCount=3;
|
||||||
|
interfaces = 0;
|
||||||
|
while(!proc_net_dev.IsFeof())
|
||||||
|
{ if(interfaces>=ifStats.size())
|
||||||
|
{ proc_net_dev.SkipLine();
|
||||||
|
interfaces++;
|
||||||
|
}
|
||||||
|
IfStat* ifstat=&ifStats[interfaces];
|
||||||
|
ifstat->Reset();
|
||||||
|
SUPPRESS_SECURITY_WARNING
|
||||||
|
const int items = proc_net_dev.fscanf(
|
||||||
|
" %20[^:]:%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
|
||||||
|
ifstat->ifname,
|
||||||
|
&ifstat->in.bytes,
|
||||||
|
&ifstat->in.packets,
|
||||||
|
&ifstat->in.errors,
|
||||||
|
&ifstat->in.drops,
|
||||||
|
&ifstat->in.overruns,
|
||||||
|
&ifstat->in.in_frame,
|
||||||
|
&ifstat->in.in_compress,
|
||||||
|
&ifstat->in.multicast,
|
||||||
|
&ifstat->out.bytes,
|
||||||
|
&ifstat->out.packets,
|
||||||
|
&ifstat->out.errors,
|
||||||
|
&ifstat->out.drops,
|
||||||
|
&ifstat->out.overruns,
|
||||||
|
&ifstat->out.out_colls,
|
||||||
|
&ifstat->out.out_carrier,
|
||||||
|
&ifstat->out.out_carrier
|
||||||
|
);
|
||||||
|
|
||||||
|
interfaces++;
|
||||||
|
if(-1==items)
|
||||||
|
{ break;
|
||||||
|
}
|
||||||
|
if(items != 17)
|
||||||
|
{ printf("Invalid data read Network::UpdateIfStats() %u:%i\n",lineCount,items);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
UpdateIoctls(ifstat);
|
||||||
|
lineCount++;
|
||||||
|
}
|
||||||
|
UpdateRoute();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProcNetRoute
|
||||||
|
{ char ifname[10];
|
||||||
|
unsigned destination;
|
||||||
|
unsigned gateway;
|
||||||
|
unsigned flags;
|
||||||
|
unsigned refcnt;
|
||||||
|
unsigned use;
|
||||||
|
unsigned metric;
|
||||||
|
unsigned mask;
|
||||||
|
unsigned mtu;
|
||||||
|
unsigned window;
|
||||||
|
unsigned irtt;
|
||||||
|
void Reset()
|
||||||
|
{ ifname[0]=0;
|
||||||
|
destination=0;
|
||||||
|
gateway=0;
|
||||||
|
flags=0;
|
||||||
|
refcnt=0;
|
||||||
|
use=0;
|
||||||
|
metric=0;
|
||||||
|
mask=0;
|
||||||
|
mtu=0;
|
||||||
|
window=0;
|
||||||
|
irtt=0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
$ cat /proc/net/route
|
||||||
|
Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth0 00000000 0202000A 0003 0 0 100 00000000 0 0 0
|
||||||
|
eth1 0002000A 00000000 0001 0 0 100 00FFFFFF 0 0 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Network::UpdateRoute()
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
StdBlob proc_net_route(output_proc_net_route);
|
||||||
|
#else
|
||||||
|
StdFile proc_net_route;
|
||||||
|
if(!proc_net_route.Open(route_filename, "r"))
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
proc_net_route.SkipLine();
|
||||||
|
ProcNetRoute pnr;
|
||||||
|
unsigned lineCount = 2;
|
||||||
|
while(!proc_net_route.IsFeof())
|
||||||
|
{ pnr.Reset();
|
||||||
|
SUPPRESS_SECURITY_WARNING
|
||||||
|
const int items = proc_net_route.fscanf(
|
||||||
|
"%s %x %x %x %x %x %x %x %x %x %x",
|
||||||
|
pnr.ifname,
|
||||||
|
&pnr.destination,
|
||||||
|
&pnr.gateway,
|
||||||
|
&pnr.flags,
|
||||||
|
&pnr.refcnt,
|
||||||
|
&pnr.use,
|
||||||
|
&pnr.metric,
|
||||||
|
&pnr.mask,
|
||||||
|
&pnr.mtu,
|
||||||
|
&pnr.window,
|
||||||
|
&pnr.irtt
|
||||||
|
);
|
||||||
|
|
||||||
|
// printf("Network::ifname=%s gateway=%u\n",pnr.ifname,pnr.gateway);
|
||||||
|
if(pnr.gateway)
|
||||||
|
{ IfStat* ifstat=GetIfStat(pnr.ifname);
|
||||||
|
if(ifstat)
|
||||||
|
{ const unsigned gateway = pnr.gateway;
|
||||||
|
CHECK(gateway)
|
||||||
|
} }
|
||||||
|
if(-1==items)
|
||||||
|
{ break;
|
||||||
|
}
|
||||||
|
if(items != 11)
|
||||||
|
{ printf("Invalid data read Network::UpdateRoute() %u:%i\n",lineCount,items);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lineCount++;
|
||||||
|
} }
|
||||||
|
|
||||||
|
IfStat* Network::GetIfStat(const char* ifname)
|
||||||
|
{ for(unsigned i=0;i<ifStats.size();i++)
|
||||||
|
{ if(!strcmp(ifStats[i].ifname,ifname))
|
||||||
|
{ return &ifStats[i];
|
||||||
|
} }
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
uint32_t GetQuad(sockaddr *addr,bool isGood=true)
|
||||||
|
{ if(!isGood || AF_INET !=addr->sa_family)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
return ((struct sockaddr_in*)addr)->sin_addr.s_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsGood(int retval)
|
||||||
|
{ return -1!=retval || EADDRNOTAVAIL==errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Network::UpdateIoctls(IfStat* ifstat)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
ifstat->address= 0x0100007f;
|
||||||
|
ifstat->broadcast= 0x0000007f;
|
||||||
|
ifstat->netmask= 0x00ffffff;
|
||||||
|
ifstat->gateway= 0x04030201;
|
||||||
|
ifstat->hw_address=0x0102030405060708ULL;
|
||||||
|
ifstat->mtu=32;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
const int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||||
|
if(-1 == sock)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
ifreq req;
|
||||||
|
strncpy(req.ifr_name, ifstat->ifname, IFNAMSIZ);
|
||||||
|
req.ifr_name[IFNAMSIZ - 1] = 0;
|
||||||
|
int retval = ioctl(sock, SIOCGIFADDR, &req);
|
||||||
|
const uint32_t address=GetQuad(&req.ifr_addr,IsGood(retval));
|
||||||
|
CHECK(address)
|
||||||
|
retval += ioctl(sock, SIOCGIFNETMASK, &req);
|
||||||
|
const uint32_t netmask=GetQuad(&req.ifr_addr,IsGood(retval));;
|
||||||
|
CHECK(netmask)
|
||||||
|
retval += ioctl(sock, SIOCGIFBRDADDR, &req);
|
||||||
|
const uint32_t broadcast=GetQuad(&req.ifr_addr,IsGood(retval));
|
||||||
|
CHECK(broadcast)
|
||||||
|
retval += ioctl(sock, SIOCGIFMTU, &req);
|
||||||
|
const int mtu = -1!=retval ? req.ifr_mtu:0;
|
||||||
|
CHECK(mtu)
|
||||||
|
retval += ioctl(sock, SIOCGIFHWADDR, &req);
|
||||||
|
uint64_t hw_address = 0;
|
||||||
|
unsigned char* hwaddr = (unsigned char *) &req.ifr_hwaddr.sa_data;
|
||||||
|
memcpy(&hw_address,hwaddr,6);
|
||||||
|
CHECK(hw_address)
|
||||||
|
close(sock);
|
||||||
|
//printf("Network::ioctl=%i address=%u netmask=%u broadcast=%u mtu=%i hw=%llu\n",retval,address,netmask,broadcast,mtu,hw_address);
|
||||||
|
return !retval;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::PrintStats()
|
||||||
|
{ printf("Network::PrintStats() interfaces=%u isChanged=%i\n",interfaces,isChanged);
|
||||||
|
for(unsigned i=0;i<ifStats.size();i++)
|
||||||
|
{ PrintIfStat(&ifStats[i]);
|
||||||
|
} }
|
||||||
|
|
||||||
|
void Network::PrintStats(const char* ifname)
|
||||||
|
{ printf("Network::PrintStats() interfaces=%u isChanged=%i\n",interfaces,isChanged);
|
||||||
|
IfStat* ifstat = GetIfStat(ifname);
|
||||||
|
if(ifstat)
|
||||||
|
{ PrintIfStat(ifstat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ printf("Interface %s not found\n",ifname);
|
||||||
|
} }
|
||||||
|
|
||||||
|
class Ip4Address
|
||||||
|
{ char data[4*4];
|
||||||
|
public:
|
||||||
|
Ip4Address(uint32_t quad,char sep)
|
||||||
|
{ unsigned char* p = reinterpret_cast<unsigned char*>(&quad);
|
||||||
|
SUPPRESS_SECURITY_WARNING
|
||||||
|
sprintf(data,"%u%c%u%c%u%c%u",unsigned(p[0]),sep,unsigned(p[1]),sep,unsigned(p[2]),sep,unsigned(p[3]));
|
||||||
|
}
|
||||||
|
const char* Get() const
|
||||||
|
{ return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HwAddress
|
||||||
|
{ char data[4*4];
|
||||||
|
public:
|
||||||
|
HwAddress(uint64_t quad2,char sep)
|
||||||
|
{ unsigned char* p = reinterpret_cast<unsigned char*>(&quad2);
|
||||||
|
SUPPRESS_SECURITY_WARNING
|
||||||
|
sprintf(data,"%u%c%u%c%u%c%u%c%u%c%u",// only has 48 bits, ignore p[0] and p[1]
|
||||||
|
unsigned(p[2]),sep,unsigned(p[3]),sep,unsigned(p[4]),sep,unsigned(p[5]),sep,unsigned(p[6]),sep,unsigned(p[7]));
|
||||||
|
}
|
||||||
|
const char* Get() const
|
||||||
|
{ return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Network::PrintIfStat(IfStat* ifstat)
|
||||||
|
{ if(!ifstat || !ifstat->address)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
Ip4Address address(ifstat->address,'.');
|
||||||
|
Ip4Address netmask(ifstat->netmask,':');
|
||||||
|
Ip4Address broadcast(ifstat->broadcast,'.');
|
||||||
|
Ip4Address gateway(ifstat->gateway,'.');
|
||||||
|
HwAddress hw_address(ifstat->hw_address,':');
|
||||||
|
printf("Interface: %s ip=%s mask=%s gateway=%s\n broadcast=%s hw=%s mtu=%i\n",ifstat->ifname,address.Get(),netmask.Get(),gateway.Get(),broadcast.Get(),hw_address.Get(),ifstat->mtu);
|
||||||
|
ifstat->in.Print(true);
|
||||||
|
ifstat->out.Print(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
uint32_t GetInet4(SOCKET sock)
|
||||||
|
{ struct sockaddr_storage addr;
|
||||||
|
char ipstr[INET_ADDRSTRLEN];
|
||||||
|
socklen_t len = sizeof addr;
|
||||||
|
getpeername(sock, (struct sockaddr*)&addr, &len);
|
||||||
|
if (addr.ss_family != AF_INET)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
|
||||||
|
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
|
||||||
|
unsigned ip[4];
|
||||||
|
SUPPRESS_SECURITY_WARNING
|
||||||
|
scanf("%x.%x.%x.%x",ip,ip+1,ip+2,ip+3);
|
||||||
|
|
||||||
|
uint32_t r;
|
||||||
|
unsigned char* p = reinterpret_cast<unsigned char*>(&r);
|
||||||
|
p[0] = (unsigned char) ip[3];
|
||||||
|
p[1] = (unsigned char) ip[2];
|
||||||
|
p[2] = (unsigned char) ip[1];
|
||||||
|
p[3] = (unsigned char) ip[0];
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
f()
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
int sa_len;
|
||||||
|
sa_len = sizeof(sa);
|
||||||
|
if (getsockname(s, &sa, &sa_len) == -1) {
|
||||||
|
perror("getsockname() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("Local IP address is: %s\n", inet_ntoa(sa.sin_add r));
|
||||||
|
printf("Local port is: %d\n", (int) ntohs(sa.sin_port));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
132
auxil/bifcl/auxil/libunistd/portable/Network.h
Normal file
132
auxil/bifcl/auxil/libunistd/portable/Network.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Network.h
|
||||||
|
// Libunistd Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef Network_h
|
||||||
|
#define Network_h
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <string.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
struct IfInterface
|
||||||
|
{ unsigned long long packets;
|
||||||
|
unsigned long long bytes;
|
||||||
|
unsigned long long errors;
|
||||||
|
unsigned long long drops;
|
||||||
|
unsigned long long overruns;
|
||||||
|
unsigned long long multicast;
|
||||||
|
union
|
||||||
|
{ unsigned long long in_frame;
|
||||||
|
unsigned long long out_colls;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{ unsigned long long in_compress;
|
||||||
|
unsigned long long out_carrier;
|
||||||
|
};
|
||||||
|
IfInterface()
|
||||||
|
{ Reset();
|
||||||
|
}
|
||||||
|
void Reset()
|
||||||
|
{ packets=0;
|
||||||
|
bytes=0;
|
||||||
|
errors=0;
|
||||||
|
drops=0;
|
||||||
|
overruns=0;
|
||||||
|
multicast=0;
|
||||||
|
in_frame=0;
|
||||||
|
out_colls=0;
|
||||||
|
}
|
||||||
|
void Print(bool isIn)
|
||||||
|
{ if(isIn)
|
||||||
|
{ printf(" RX packets=%llu bytes=%llu errors=%llu drops=%llu\n overruns==%llu multicast==%llu frame==%llu compress==%llu\n"
|
||||||
|
,packets,bytes,errors,drops,overruns,multicast,in_frame,in_compress);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ printf(" TX packets=%llu bytes=%llu errors=%llu drops=%llu\n overruns==%llu multicast==%llu colls==%llu carrier==%llu\n"
|
||||||
|
,packets,bytes,errors,drops,overruns,multicast,out_colls,out_carrier);
|
||||||
|
} }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IfStat
|
||||||
|
{ char ifname[10];
|
||||||
|
uint32_t address;
|
||||||
|
uint32_t netmask;
|
||||||
|
uint32_t broadcast;
|
||||||
|
int mtu;
|
||||||
|
uint64_t hw_address;
|
||||||
|
uint32_t gateway;
|
||||||
|
IfInterface in;
|
||||||
|
IfInterface out;
|
||||||
|
IfStat()
|
||||||
|
{ Reset();
|
||||||
|
}
|
||||||
|
void Reset()
|
||||||
|
{ ifname[0]=0;
|
||||||
|
address=0;
|
||||||
|
netmask=0;
|
||||||
|
broadcast=0;
|
||||||
|
mtu=0;
|
||||||
|
hw_address=0;
|
||||||
|
gateway=0;
|
||||||
|
in.Reset();
|
||||||
|
out.Reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Network
|
||||||
|
{ bool UpdateIoctls(IfStat* ifstat);
|
||||||
|
void UpdateRoute();
|
||||||
|
const char* route_filename;
|
||||||
|
const char* dev_filename;
|
||||||
|
public:
|
||||||
|
bool isChanged;
|
||||||
|
unsigned interfaces;
|
||||||
|
std::vector<IfStat> ifStats;
|
||||||
|
Network(unsigned interfaceCount);
|
||||||
|
bool UpdateIfStats();
|
||||||
|
IfStat* GetIfStat(const char* ifname);
|
||||||
|
void PrintIfStat(IfStat* ifstat);
|
||||||
|
void PrintStats();
|
||||||
|
void PrintStats(const char* ifname);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IpAddress
|
||||||
|
{ char address[INET6_ADDRSTRLEN+1];
|
||||||
|
unsigned ipType;
|
||||||
|
public:
|
||||||
|
IpAddress(unsigned long ip)
|
||||||
|
: ipType(0)
|
||||||
|
{ address[0] = 0;
|
||||||
|
struct in_addr ipaddr;
|
||||||
|
ipaddr.s_addr = htonl(ip);
|
||||||
|
const char* p = inet_ntop(AF_INET,&ipaddr,address, INET6_ADDRSTRLEN);
|
||||||
|
if(p!=nullptr)
|
||||||
|
{ ipType = 4;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p = inet_ntop(AF_INET6,&ipaddr,address, INET6_ADDRSTRLEN);
|
||||||
|
if(p!=nullptr)
|
||||||
|
{ ipType = 6;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
strncpy(address,strerror(errno),INET6_ADDRSTRLEN);
|
||||||
|
#pragma warning(default : 4996)
|
||||||
|
address[INET6_ADDRSTRLEN] = 0;
|
||||||
|
}
|
||||||
|
operator const char*() const
|
||||||
|
{ return address;
|
||||||
|
}
|
||||||
|
unsigned GetIpType() const
|
||||||
|
{ return ipType;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
28
auxil/bifcl/auxil/libunistd/portable/QtHelpers.h
Normal file
28
auxil/bifcl/auxil/libunistd/portable/QtHelpers.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// QtHelpers.h
|
||||||
|
// Created by Robin Rowe on 11/19/2015.
|
||||||
|
// Copyright (c) 2015 Robin.Rowe@CinePaint.org.
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef QtHelpers_h
|
||||||
|
#define QtHelpers_h
|
||||||
|
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QImageReader>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool QtLoadImage(const char* filename,QLabel& image)
|
||||||
|
{ QPixmap qPixmap;
|
||||||
|
if(!qPixmap.load(filename))
|
||||||
|
{ qDebug()<<"No image "<<filename;
|
||||||
|
qDebug() << QImageReader::supportedImageFormats();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
image.setPixmap(qPixmap.scaled(image.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||||
|
image.setAlignment(Qt::AlignCenter);
|
||||||
|
qDebug()<<"Loaded: "<<filename;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
50
auxil/bifcl/auxil/libunistd/portable/Random.h
Normal file
50
auxil/bifcl/auxil/libunistd/portable/Random.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// MinimalStandardRandom
|
||||||
|
// 2013/9/28
|
||||||
|
// http://c-faq.com/lib/rand.html
|
||||||
|
|
||||||
|
#ifndef MinimalStandardRandom_h
|
||||||
|
#define MinimalStandardRandom_h
|
||||||
|
|
||||||
|
// NOTE: The size of int is 4 bytes and the size of long long is
|
||||||
|
// 8 bytes on Linux, Mac and Windows. The size of long is 4 bytes
|
||||||
|
// on Windows 32/64 and 32-bit Linux/Mac, but is 8 bytes on 64-bit
|
||||||
|
// Linux/Mac. Consequently, we do not use long as shown in the c-faq.
|
||||||
|
// http://software.intel.com/en-us/articles/size-of-long-integer-type-on-different-architecture-and-os
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
class MinimalStandardRandom
|
||||||
|
{ static const int a=48271;//16807;
|
||||||
|
static const int m=2147483647;
|
||||||
|
static const int q=m/a;
|
||||||
|
static const int r=m%a;
|
||||||
|
int seed;
|
||||||
|
public:
|
||||||
|
MinimalStandardRandom(int seed=0)
|
||||||
|
: seed(seed)
|
||||||
|
{ if(!seed)
|
||||||
|
{ time_t seconds;
|
||||||
|
time(&seconds);
|
||||||
|
this->seed=(int) seconds;
|
||||||
|
} }
|
||||||
|
int NextPositive() // range [1, 2147483646], except 0
|
||||||
|
{ const int hi = seed / q;
|
||||||
|
const int lo = seed % q;
|
||||||
|
const int test = a * lo - r * hi;
|
||||||
|
if(test > 0)
|
||||||
|
{ seed = test;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ seed = test + m;
|
||||||
|
}
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
int Next() // range +-2147483646 except 0
|
||||||
|
{ const int hi = seed / q;
|
||||||
|
const int lo = seed % q;
|
||||||
|
seed = a * lo - r * hi;
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
60
auxil/bifcl/auxil/libunistd/portable/RingAllocator.h
Normal file
60
auxil/bifcl/auxil/libunistd/portable/RingAllocator.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// RingAllocator.h
|
||||||
|
// Copyright 2018/4/10 Robin.Rowe@CinePaint.org
|
||||||
|
// License MIT open source
|
||||||
|
|
||||||
|
#ifndef RingAllocator_h
|
||||||
|
#define RingAllocator_h
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace Atomic
|
||||||
|
{
|
||||||
|
// Usage: char buffer[16];
|
||||||
|
// Atomic::RingAllocator a(buffer,4);
|
||||||
|
// char* p = a.Get(12);
|
||||||
|
// strcpy(p,"Hello World)
|
||||||
|
// WakeOtherThread();
|
||||||
|
// a.Free(p);
|
||||||
|
|
||||||
|
class RingAllocator
|
||||||
|
{ std::atomic<int> p;
|
||||||
|
char* buffer;
|
||||||
|
char* bufferEnd;
|
||||||
|
int bitmask;
|
||||||
|
public:
|
||||||
|
RingAllocator(char* buffer,unsigned sizeInBits)
|
||||||
|
: buffer(buffer)
|
||||||
|
, p(0)
|
||||||
|
{ bitmask = (1 << sizeInBits) - 1;
|
||||||
|
bufferEnd = buffer + bitmask;
|
||||||
|
}
|
||||||
|
char* Get(unsigned blockSize)
|
||||||
|
{ blockSize += sizeof(int);
|
||||||
|
int before = p.fetch_add(blockSize,std::memory_order_relaxed);
|
||||||
|
before &= bitmask;
|
||||||
|
if(before + blockSize > bitmask)
|
||||||
|
{ // Buffer overflow, 2nd try:
|
||||||
|
before = p.fetch_add(blockSize,std::memory_order_relaxed);
|
||||||
|
before &= bitmask;
|
||||||
|
}
|
||||||
|
if(before + blockSize > bitmask)
|
||||||
|
{ // Too big
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int* header = (int*) buffer + before;
|
||||||
|
*header = before;
|
||||||
|
return buffer + before + sizeof(int);
|
||||||
|
}
|
||||||
|
int Free(const char* p) const
|
||||||
|
{ p -= sizeof(int);
|
||||||
|
if(p < buffer || p >= bufferEnd)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
int* header = (int*) p;
|
||||||
|
return *header;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
50
auxil/bifcl/auxil/libunistd/portable/SharedMemory.h
Normal file
50
auxil/bifcl/auxil/libunistd/portable/SharedMemory.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class SharedMemory
|
||||||
|
{ int fd;
|
||||||
|
T* t;
|
||||||
|
T err;
|
||||||
|
size_t size;
|
||||||
|
public:
|
||||||
|
~SharedMemory()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
SharedMemory(const char* name,size_t size)
|
||||||
|
: fd(0)
|
||||||
|
, p(0)
|
||||||
|
, size(0)
|
||||||
|
{ int oflags = O_RDWR | O_CREAT;
|
||||||
|
fd = shm_open(name,oflags,0644);
|
||||||
|
if(fd)
|
||||||
|
{ shm_ftruncate(fd,size);
|
||||||
|
p = (t*) mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
|
||||||
|
} }
|
||||||
|
SharedMemory(const char* name)
|
||||||
|
: fd(0)
|
||||||
|
, p(0)
|
||||||
|
, size(0)
|
||||||
|
{ int oflags=O_RDWR;
|
||||||
|
fd = shm_open(name,oflags,0644);
|
||||||
|
if(fd)
|
||||||
|
{ size = shm_size(fd)/sizeof(t);
|
||||||
|
p = (t*) mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
|
||||||
|
} }
|
||||||
|
T& operator[](size_t i)
|
||||||
|
{ if(i>=size)
|
||||||
|
{ return err;
|
||||||
|
}
|
||||||
|
return p[i];
|
||||||
|
}
|
||||||
|
operator t*()
|
||||||
|
{ return p;
|
||||||
|
}
|
||||||
|
bool Flush()
|
||||||
|
{ return shm_flush(fd);
|
||||||
|
}
|
||||||
|
bool Close()
|
||||||
|
{ return shm_close(fd);
|
||||||
|
}
|
||||||
|
size_t Size() const
|
||||||
|
{ return size;
|
||||||
|
}
|
||||||
|
};
|
||||||
12
auxil/bifcl/auxil/libunistd/portable/Shutdown.cpp
Normal file
12
auxil/bifcl/auxil/libunistd/portable/Shutdown.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Shutdown.cpp
|
||||||
|
// Created by Robin Rowe 2019-07-10
|
||||||
|
// License Copyright 2019 Robin.Rowe@HeroicRobots.com ***Proprietary***
|
||||||
|
|
||||||
|
#include "Shutdown.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Shutdown* Shutdown::handler;
|
||||||
|
|
||||||
|
ostream& Shutdown::Print(ostream& os) const
|
||||||
|
{ return os << "Shutdown";
|
||||||
|
}
|
||||||
49
auxil/bifcl/auxil/libunistd/portable/SizeTracker.h
Normal file
49
auxil/bifcl/auxil/libunistd/portable/SizeTracker.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// SizeTracker.h
|
||||||
|
// Copyright 2018/4/10 Robin.Rowe@CinePaint.org
|
||||||
|
// License MIT open source
|
||||||
|
|
||||||
|
#ifndef SizeTracker_h
|
||||||
|
#define SizeTracker_h
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace Atomic
|
||||||
|
{
|
||||||
|
|
||||||
|
class SizeTracker
|
||||||
|
{ std::atomic<int> size;
|
||||||
|
int bitmask;
|
||||||
|
public:
|
||||||
|
SizeTracker(unsigned sizeInBits)
|
||||||
|
: size(0)
|
||||||
|
{ bitmask = (1 << sizeInBits) - 1;
|
||||||
|
}
|
||||||
|
int Add(int qty)
|
||||||
|
{ const int i = size.fetch_add(qty,std::memory_order_relaxed);
|
||||||
|
return i + qty;
|
||||||
|
}
|
||||||
|
int Free(int qty)
|
||||||
|
{ const int i = size.fetch_sub(size,std::memory_order_relaxed);
|
||||||
|
return i - qty;
|
||||||
|
}
|
||||||
|
int GetSize() const
|
||||||
|
{ const int s=size;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
int GetMaxSize() const
|
||||||
|
{ return bitmask;
|
||||||
|
}
|
||||||
|
int GetFreeSize() const
|
||||||
|
{ return GetMaxSize() - GetSize();
|
||||||
|
}
|
||||||
|
bool IsFull() const
|
||||||
|
{ return GetSize() >= GetMaxSize();
|
||||||
|
}
|
||||||
|
bool IsEmpty() const
|
||||||
|
{ return GetSize() <= 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
38
auxil/bifcl/auxil/libunistd/portable/SoftLock.h
Normal file
38
auxil/bifcl/auxil/libunistd/portable/SoftLock.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// libportable/SoftLock.h
|
||||||
|
// Robin.Rowe@cinepaint.org 2014/11/20
|
||||||
|
|
||||||
|
#ifndef SoftLock_h
|
||||||
|
#define SoftLock_h
|
||||||
|
|
||||||
|
#include "AtomicMutex.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class AtomicMutex;
|
||||||
|
|
||||||
|
class SoftLock
|
||||||
|
{ const bool isLocked;
|
||||||
|
AtomicMutex& atomicMutex;
|
||||||
|
SoftLock(SoftLock&);
|
||||||
|
void operator=(SoftLock&);
|
||||||
|
public:
|
||||||
|
~SoftLock()
|
||||||
|
{ if(isLocked)
|
||||||
|
{ atomicMutex.Unlock();
|
||||||
|
} }
|
||||||
|
SoftLock(AtomicMutex& atomicMutex)
|
||||||
|
: atomicMutex(atomicMutex),
|
||||||
|
isLocked(atomicMutex.Lock())
|
||||||
|
{}
|
||||||
|
bool IsLocked() const
|
||||||
|
{ return isLocked;
|
||||||
|
}
|
||||||
|
bool operator!() const
|
||||||
|
{ return !isLocked;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
42
auxil/bifcl/auxil/libunistd/portable/StackTrack.h
Normal file
42
auxil/bifcl/auxil/libunistd/portable/StackTrack.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// StackTrank.h
|
||||||
|
// 2017/6/16
|
||||||
|
|
||||||
|
#ifndef StackTrack_h
|
||||||
|
#define StackTrack_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#if 0
|
||||||
|
template<typename T>
|
||||||
|
class StackTrack
|
||||||
|
{ int count;
|
||||||
|
const char* name;
|
||||||
|
const int size;
|
||||||
|
const T* t;
|
||||||
|
public:
|
||||||
|
StackTrack(const StackTrack&) = delete;
|
||||||
|
StackTrack& operator=(const StackTrack&) = delete;
|
||||||
|
StackTrack(int size,const char* name)
|
||||||
|
: name(name)
|
||||||
|
, size(size)
|
||||||
|
, t(nullptr)
|
||||||
|
{ count++;
|
||||||
|
Print();
|
||||||
|
}
|
||||||
|
~StackTrack()
|
||||||
|
{ count--;
|
||||||
|
Print();
|
||||||
|
}
|
||||||
|
void Print()
|
||||||
|
{ printf("StackTrack(%s): %i (%u bytes)\n",name,count,count*size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STACK_TRACK(t) stackTrack(sizeof(t),#t)
|
||||||
|
#else
|
||||||
|
#define STACK_TRACK(t) {\
|
||||||
|
static int count; \
|
||||||
|
printf("StackTrack(%s): %i (%i bytes)\n", #t, ++count, int(count*sizeof(t)));\
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
133
auxil/bifcl/auxil/libunistd/portable/StdBlob.h
Normal file
133
auxil/bifcl/auxil/libunistd/portable/StdBlob.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// StdBlob.h
|
||||||
|
// Libunistd Copyright (c) 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef StdBlob_h
|
||||||
|
#define StdBlob_h
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class StdBlob
|
||||||
|
{protected:
|
||||||
|
const char* data;
|
||||||
|
size_t bytes;
|
||||||
|
size_t offset;
|
||||||
|
public:
|
||||||
|
StdBlob(const char* data,size_t bytes=0)
|
||||||
|
: data(data)
|
||||||
|
, bytes(bytes)
|
||||||
|
, offset(0)
|
||||||
|
{ if(!bytes)
|
||||||
|
{ bytes = strlen(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~StdBlob()
|
||||||
|
{}
|
||||||
|
bool IsGood() const
|
||||||
|
{ return nullptr!=data;
|
||||||
|
}
|
||||||
|
bool IsFeof()
|
||||||
|
{ return IsGood()? offset>=bytes:false;
|
||||||
|
}
|
||||||
|
bool Open(const char*,const char*)
|
||||||
|
{ return IsGood();
|
||||||
|
}
|
||||||
|
int Read(char* data,size_t length)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
if(length+offset>=bytes)
|
||||||
|
{ length = bytes - offset;
|
||||||
|
}
|
||||||
|
memcpy(data,this->data,length);
|
||||||
|
offset += length;
|
||||||
|
return (int) bytes;
|
||||||
|
}
|
||||||
|
void Skip(unsigned charCount)
|
||||||
|
{ if(charCount+offset>=bytes)
|
||||||
|
{ offset = bytes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ offset += charCount;
|
||||||
|
} }
|
||||||
|
void SkipLine()
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
while(offset<bytes)
|
||||||
|
{ int ch = data[offset];
|
||||||
|
offset++;
|
||||||
|
if (ch == '\n')
|
||||||
|
{ return;
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
void GetLine(std::vector<char>& line)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
for(unsigned i=0;i<line.size();i++)
|
||||||
|
{ if (data[offset]== '\n')
|
||||||
|
{ line[i] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ line[i] = data[offset];
|
||||||
|
}
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
line[line.size()-1] = 0;
|
||||||
|
}
|
||||||
|
void Close()
|
||||||
|
{}
|
||||||
|
bool Seek(long offset)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
if(offset>=(long) bytes)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
this->offset = offset;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SeekEnd()
|
||||||
|
{ this->offset = bytes;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
long Tell() const
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return (long) offset;
|
||||||
|
}
|
||||||
|
void Rewind()
|
||||||
|
{ if(IsGood())
|
||||||
|
{ offset = 0;
|
||||||
|
} }
|
||||||
|
#ifdef __GNUC__
|
||||||
|
int fscanf(const char* const format,...) __attribute__ ((format(scanf, 2, 3)))
|
||||||
|
{ va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
int retval = vsscanf(data+offset,format, args);
|
||||||
|
va_end(args);
|
||||||
|
SkipLine();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int fscanf(const char* const format,...)
|
||||||
|
{ va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
int retval = vsscanf(data+offset,format, args);
|
||||||
|
va_end(args);
|
||||||
|
SkipLine();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
138
auxil/bifcl/auxil/libunistd/portable/StdCopy.h
Normal file
138
auxil/bifcl/auxil/libunistd/portable/StdCopy.h
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// StdCopy.h
|
||||||
|
// Libunistd Copyright (c) 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef StdCopy_h
|
||||||
|
#define StdCopy_h
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <bsd/string.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define ATTRIBUTE(a,b)
|
||||||
|
#else
|
||||||
|
#define ATTRIBUTE(a,b) __attribute__((format(printf, a, b)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* copy(T* first, T* last, T* d_first)
|
||||||
|
{ const unsigned n = last-first-1;
|
||||||
|
if(d_first > last || d_first+n-1 < first)
|
||||||
|
{ memcpy(d_first,first,n*sizeof(T));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ memmove(d_first,first,n*sizeof(T));
|
||||||
|
}
|
||||||
|
return d_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
template <typename T,typename A>
|
||||||
|
T* copy2(T* first, T* last,const A& array,unsigned offset)
|
||||||
|
{ const unsigned n = last-first-1;
|
||||||
|
assert(n<=array.size()-offset);
|
||||||
|
if(n<=array.size()-offset)
|
||||||
|
{ return copy(first,first+array.size()-offset,&array[offset]);
|
||||||
|
}
|
||||||
|
return copy(first,last,&array[offset]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t strlcpy(T& dst, const char *src)
|
||||||
|
{ return strlcpy(&dst[0],src,dst.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t strlcat(T& dst, const char *src)
|
||||||
|
{ return strlcat(&dst[0],src,dst.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
int slprintf(char* const buffer, size_t size,const char* const format,...) //ATTRIBUTE(3,4)
|
||||||
|
{ if(!buffer || !format || !size)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
va_list argList;
|
||||||
|
va_start(argList,format);
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma warning(suppress:4996)
|
||||||
|
const int count = vsnprintf(buffer,size-1,format,argList);
|
||||||
|
#else
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
|
||||||
|
const int count = vsnprintf(buffer,size-1,format,argList);
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
va_end(argList);
|
||||||
|
buffer[size-1]=0;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
int slprintf(T& buffer, const char* const format,...) //ATTRIBUTE(2,3)
|
||||||
|
{ const size_t size = buffer.size();
|
||||||
|
if(!format || !size)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
va_list argList;
|
||||||
|
va_start(argList,format);
|
||||||
|
char* p = &buffer[0];
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma warning(suppress:4996)
|
||||||
|
const int count = vsnprintf(p,size-1,format,argList);
|
||||||
|
#else
|
||||||
|
//__pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
|
||||||
|
const int count = vsnprintf(p,size-1,format,argList);
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
va_end(argList);
|
||||||
|
buffer[size-1]=0;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t strlen(const T& buffer)
|
||||||
|
{ const char* p = &buffer[0];
|
||||||
|
return strlen(p);
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
inline
|
||||||
|
void* memcpy(char* dest, const char* src, size_t size)
|
||||||
|
{ return memcpy((void*)dest,(const void*) src,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
char* memcpy(T& dest,const void* src,size_t size)
|
||||||
|
{ memcpy(&dest[0], src, size);
|
||||||
|
return &dest[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
char* memcpy(void* dest,T& src,size_t size)
|
||||||
|
{ memcpy(dest, &src[0], size);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
char* memcpy(T& dest,T& src,size_t size)
|
||||||
|
{ memcpy(&dest[0], &src[0], size);
|
||||||
|
return &dest;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
|
||||||
|
#endif
|
||||||
118
auxil/bifcl/auxil/libunistd/portable/StdDevice.h
Normal file
118
auxil/bifcl/auxil/libunistd/portable/StdDevice.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// StdDevice.h
|
||||||
|
// Created by Robin Rowe on 2016/7/5
|
||||||
|
// Copyright (c) 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef StdDevice_h
|
||||||
|
#define StdDevice_h
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class StdDevice
|
||||||
|
{protected:
|
||||||
|
int fd;
|
||||||
|
size_t bytes;
|
||||||
|
#ifndef WIN32
|
||||||
|
static const int O_BINARY = 0;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
StdDevice()
|
||||||
|
: fd(-1)
|
||||||
|
, bytes(0)
|
||||||
|
{}
|
||||||
|
StdDevice(int fd)
|
||||||
|
: fd(fd)
|
||||||
|
, bytes(0)
|
||||||
|
{}
|
||||||
|
~StdDevice()
|
||||||
|
{// Close(); //Do not close devices implicitly, may live beyond temporary StdDevice.
|
||||||
|
}
|
||||||
|
operator int() const
|
||||||
|
{ return fd;
|
||||||
|
}
|
||||||
|
bool IsGood() const
|
||||||
|
{ return 0 <= fd;
|
||||||
|
}
|
||||||
|
bool operator!() const
|
||||||
|
{ return !IsGood();
|
||||||
|
}
|
||||||
|
// O_RDWR | O_NOCTTY | O_NDELAY...
|
||||||
|
#pragma warning (disable : 4996)
|
||||||
|
void Close()
|
||||||
|
{ if(IsGood())
|
||||||
|
{ close(fd);
|
||||||
|
fd = -1;
|
||||||
|
} }
|
||||||
|
bool Open(const char* filename,int flags)
|
||||||
|
{ fd = open(filename,flags);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
bool Open(const char* filename,int flags, mode_t mode)
|
||||||
|
{ fd = open(filename, flags, mode);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
bool OpenReadOnly(const char* filename)
|
||||||
|
{ return Open(filename, O_BINARY | O_RDONLY);
|
||||||
|
}
|
||||||
|
bool OpenWriteOnly(const char* filename)
|
||||||
|
{ return Open(filename,O_BINARY | O_WRONLY);
|
||||||
|
}
|
||||||
|
bool OpenAppend(const char* filename)
|
||||||
|
{ return Open(filename,O_WRONLY | O_APPEND);
|
||||||
|
}
|
||||||
|
int Read(char* data,size_t length)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
bytes=read(fd,data,length);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
int Read(char& c)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
bytes=read(fd,&c,1);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
int Write(const char* data,size_t length)
|
||||||
|
{ if(!data || !IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
bytes=write(fd,data,length);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
bool Create(const char *pathname, mode_t mode)
|
||||||
|
{ fd = creat(pathname,mode);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
off_t Seek(off_t offset, int origin)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
return lseek(fd,offset,origin);
|
||||||
|
}
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
int Write(char c)
|
||||||
|
{ return Write(&c,1);
|
||||||
|
}
|
||||||
|
int Write(const char* string)
|
||||||
|
{ if(!string)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const size_t length=strlen(string);
|
||||||
|
return Write(string,length);
|
||||||
|
}
|
||||||
|
int WriteNull()
|
||||||
|
{ return Write("",1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // portable
|
||||||
|
|
||||||
|
#endif
|
||||||
309
auxil/bifcl/auxil/libunistd/portable/StdFile.h
Normal file
309
auxil/bifcl/auxil/libunistd/portable/StdFile.h
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
// StdFile.h
|
||||||
|
// Created by Robin Rowe on 12/5/2015
|
||||||
|
// Libunistd Copyright (c) 2015 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef StdFile_h
|
||||||
|
#define StdFile_h
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "SystemLog.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class StdFile
|
||||||
|
{protected:
|
||||||
|
FILE* fp;
|
||||||
|
size_t bytes;
|
||||||
|
public:
|
||||||
|
StdFile(const StdFile&) = delete;
|
||||||
|
~StdFile()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
StdFile()
|
||||||
|
: fp(nullptr)
|
||||||
|
, bytes(0)
|
||||||
|
{}
|
||||||
|
void Close()
|
||||||
|
{ if(IsGood())
|
||||||
|
{ fclose(fp);
|
||||||
|
}
|
||||||
|
fp=nullptr;
|
||||||
|
bytes = 0;
|
||||||
|
}
|
||||||
|
FILE* GetFp()
|
||||||
|
{ return fp;
|
||||||
|
}
|
||||||
|
#pragma warning(disable:4458)
|
||||||
|
void SetFp(FILE* fp)
|
||||||
|
{ Close();
|
||||||
|
this->fp = fp;
|
||||||
|
}
|
||||||
|
size_t GetLastBytes() const
|
||||||
|
{ return bytes;
|
||||||
|
}
|
||||||
|
bool IsGood() const
|
||||||
|
{ return nullptr!=fp;
|
||||||
|
}
|
||||||
|
bool IsFeof()
|
||||||
|
{ return IsGood()? 0!=feof(fp):false;
|
||||||
|
}
|
||||||
|
/* flags:
|
||||||
|
"r" read only: file must exist
|
||||||
|
"w" write only: delete then create an empty
|
||||||
|
"a" append: create file if doesn't exist, write at end, no seek
|
||||||
|
"r+" read/write: existing file only
|
||||||
|
"w+" read/write: delete and create empty file
|
||||||
|
"a+" same as w+ but only write to end and write repositions at end
|
||||||
|
"rb" read binary...
|
||||||
|
*/
|
||||||
|
#pragma warning (disable : 4996)
|
||||||
|
bool Open(const char* filename,const char* flags)
|
||||||
|
{ fp = fopen(filename,flags);
|
||||||
|
if(!IsGood())
|
||||||
|
{ TRACE(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#pragma warning (default : 4996)
|
||||||
|
bool OpenReadOnly(const char* filename)
|
||||||
|
{ return Open(filename,"rb");
|
||||||
|
}
|
||||||
|
bool OpenWriteOnly(const char* filename)
|
||||||
|
{ return Open(filename,"wb");
|
||||||
|
}
|
||||||
|
bool OpenAppend(const char* filename)
|
||||||
|
{ return Open(filename,"ab");
|
||||||
|
}
|
||||||
|
bool Read(char* data,size_t length)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
bytes=fread(data,1,length,fp);
|
||||||
|
if(bytes < 0)
|
||||||
|
{ TRACE(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#define READ(T) bool Read(T x){ return Read((char*) &x,sizeof(x)); }
|
||||||
|
READ(unsigned)
|
||||||
|
#undef READ
|
||||||
|
void Skip(unsigned charCount)
|
||||||
|
{ for(unsigned i=0;i<charCount && IsGood();i++)
|
||||||
|
{ (void) getc(fp);
|
||||||
|
bytes++;
|
||||||
|
} }
|
||||||
|
void SkipLine()
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
for(;;)
|
||||||
|
{ int ch = getc(fp);
|
||||||
|
bytes++;
|
||||||
|
if (ch == '\n' || ch == EOF)
|
||||||
|
{ return;
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
bool GetLine(char* s,size_t size)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return nullptr != fgets(s,(int) size,fp);
|
||||||
|
}
|
||||||
|
bool GetLine(std::vector<char>& line)
|
||||||
|
{ return GetLine(&line[0],line.size());
|
||||||
|
}
|
||||||
|
bool Write(const char* data,size_t length)
|
||||||
|
{ if(!data || !IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
bytes=fwrite(data,1,length,fp);
|
||||||
|
if(bytes != length)
|
||||||
|
{ TRACE(0);
|
||||||
|
}
|
||||||
|
return bytes==length;
|
||||||
|
}
|
||||||
|
#define WRITE(T) bool Write(T x){ return Write((const char*) &x,sizeof(x)); }
|
||||||
|
bool Write(char c)
|
||||||
|
{ return Write(&c,1);
|
||||||
|
}
|
||||||
|
WRITE(unsigned)
|
||||||
|
#undef WRITE
|
||||||
|
bool Write(const char* string)
|
||||||
|
{ if(!string)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const size_t length=strlen(string);
|
||||||
|
return Write(string,length);
|
||||||
|
}
|
||||||
|
bool WriteNull()
|
||||||
|
{ return Write("",1);
|
||||||
|
}
|
||||||
|
bool Seek(long offset,int where=SEEK_CUR)
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const int err=fseek(fp,offset,where);
|
||||||
|
if(err)
|
||||||
|
{ TRACE(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool SeekEnd()
|
||||||
|
{ return Seek(0,SEEK_END);
|
||||||
|
}
|
||||||
|
bool SeekStart()
|
||||||
|
{ return Seek(0,SEEK_SET);
|
||||||
|
}
|
||||||
|
long Tell() const
|
||||||
|
{ if(!IsGood())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const long size=ftell(fp);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
void Rewind()
|
||||||
|
{ if(IsGood())
|
||||||
|
{ rewind(fp);
|
||||||
|
} }
|
||||||
|
#ifdef __GNUC__
|
||||||
|
int fscanf(const char* const format,...) __attribute__ ((format(scanf, 2, 3)))
|
||||||
|
#else
|
||||||
|
int fscanf(const char* const format,...)
|
||||||
|
#endif
|
||||||
|
{ va_list argList;
|
||||||
|
va_start(argList,format);
|
||||||
|
bytes = vfscanf(fp, format, argList);
|
||||||
|
va_end(argList);
|
||||||
|
return (int) bytes; // Should return the number of input items assigned or EOF
|
||||||
|
}
|
||||||
|
#ifdef __GNUC__
|
||||||
|
int fprintf(const char* const format,...) __attribute__ ((format(printf, 2, 3)))
|
||||||
|
#else
|
||||||
|
int fprintf(const char* const format,...)
|
||||||
|
#endif
|
||||||
|
{ va_list argList;
|
||||||
|
va_start(argList,format);
|
||||||
|
bytes = vfprintf(fp, format, argList);
|
||||||
|
va_end(argList);
|
||||||
|
return (int)bytes; // Should return the number of input items assigned or EOF
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Slurp StdFile or StdDevice:
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool Slurp(T& file,std::vector<char>& buffer)
|
||||||
|
{ if(!file.SeekEnd())
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const long size=file.Tell();
|
||||||
|
file.Rewind();
|
||||||
|
buffer.resize(size);
|
||||||
|
char* data=&buffer[0];
|
||||||
|
return file.Read(data,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool Slurp(T& file,std::vector<std::string>& line)
|
||||||
|
{ std::vector<char> buffer;
|
||||||
|
if(!Slurp(file,buffer))
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const char* p = &buffer[0];
|
||||||
|
const char* end = p+buffer.size();
|
||||||
|
const char* word = p;
|
||||||
|
while(p<end)
|
||||||
|
{ switch(*p)
|
||||||
|
{default:
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
|
line.push_back(std::string(word,p-word));// not std::move(), "error: moving a temporary object prevents copy elision"
|
||||||
|
|
||||||
|
if('\r'==*p)
|
||||||
|
{ word=p+2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ word=p+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsFile(const char* filename)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
struct __stat64 st;
|
||||||
|
const int err = _stat64(filename, &st);
|
||||||
|
#else
|
||||||
|
struct stat st;
|
||||||
|
const int err = stat(filename, &st);
|
||||||
|
#endif
|
||||||
|
if(err!=0)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return 0!=S_ISREG(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool IsDir(const char* path)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
struct __stat64 st;
|
||||||
|
const int err = _stat64(path, &st);
|
||||||
|
#else
|
||||||
|
struct stat st;
|
||||||
|
const int err = stat(path, &st);
|
||||||
|
#endif
|
||||||
|
if(err!=0)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return 0!=S_ISDIR(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
long long GetFileSize(const char* filename)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
struct __stat64 st;
|
||||||
|
const int err = _stat64(filename, &st);
|
||||||
|
#else
|
||||||
|
struct stat st;
|
||||||
|
const int err = stat(filename, &st);
|
||||||
|
#endif
|
||||||
|
if(err!=0)
|
||||||
|
{ return -1;
|
||||||
|
}
|
||||||
|
return st.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool DeleteFile(const char* filename)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
const int err=_unlink(filename);
|
||||||
|
return err!=0;
|
||||||
|
#else
|
||||||
|
const int err=unlink(filename);
|
||||||
|
return err!=0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#pragma warning(default:4458)
|
||||||
|
|
||||||
|
#endif
|
||||||
37
auxil/bifcl/auxil/libunistd/portable/StdPipe.h
Normal file
37
auxil/bifcl/auxil/libunistd/portable/StdPipe.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// StdPipe.h
|
||||||
|
// Created by Robin Rowe on 12/5/2015
|
||||||
|
// Copyright (c) 2015 Robin.Rowe@CinePaint.org
|
||||||
|
|
||||||
|
#ifndef StdPipe_h
|
||||||
|
#define StdPipe_h
|
||||||
|
|
||||||
|
#include "StdFile.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class StdPipe
|
||||||
|
: public StdFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~StdPipe()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
bool Open(const char* filename)
|
||||||
|
{ fp = popen(filename,"w");
|
||||||
|
return 0!=fp;
|
||||||
|
}
|
||||||
|
int Close()
|
||||||
|
{ if(!fp)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
const int retval=pclose(fp);
|
||||||
|
fp=0;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
142
auxil/bifcl/auxil/libunistd/portable/SystemCall.h
Normal file
142
auxil/bifcl/auxil/libunistd/portable/SystemCall.h
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// SystemCall.h
|
||||||
|
// Libunist Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef SystemCall_h
|
||||||
|
#define SystemCall_h
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
inline
|
||||||
|
void OpenConsole()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
AllocConsole();
|
||||||
|
#pragma warning(disable: 4996)
|
||||||
|
freopen("CONOUT$", "w", stdout);
|
||||||
|
#pragma warning(default: 4996)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrintTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PrintTask(const char* functionName,const char* description = "")
|
||||||
|
{ if(!functionName || !description)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
#ifdef TRACE_TASKS
|
||||||
|
static unsigned i;
|
||||||
|
i++;
|
||||||
|
printf("Thread(%u): %s() %s\n",i,functionName,description);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[[ noreturn ]]
|
||||||
|
inline
|
||||||
|
void StubExit(int errorlevel,const char* msg,const char* file,const char* function,int line)
|
||||||
|
{ printf("exit(%i): %s %s\n%s:%i",errorlevel,msg,function,file,line);
|
||||||
|
exit(errorlevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ noreturn ]]
|
||||||
|
inline
|
||||||
|
void StubAssert(int errorlevel,const char* msg,const char* file,const char* function,int line)
|
||||||
|
{ printf("assert(%s): %s\n%s:%i",msg,function,file,line);
|
||||||
|
exit(errorlevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
int SystemCall(const char* cmd)
|
||||||
|
{ (void)cmd;
|
||||||
|
#ifdef TRACE_SYSTEM_CALLS
|
||||||
|
static int i;
|
||||||
|
printf("[%i] system(%s)\n",++i,cmd);
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
return system(cmd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool memcopy(T& dest,const char* start,unsigned size)
|
||||||
|
{ const auto p=dest.data();
|
||||||
|
if(dest.size()*sizeof(*p) < size*sizeof(char) )
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
memcpy(dest.data(),start,size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool std_cpy(const char* start,const char* end,T& dest)
|
||||||
|
{ const unsigned size = (end-start)*sizeof(char);
|
||||||
|
const auto p=dest.data();
|
||||||
|
if(dest.size()*sizeof(*p) < size*sizeof(char) )
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
memcpy(dest.data(),start,size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class OS {unknown_os,android_os,linux_os,ios_os,mac_os,windows_os};
|
||||||
|
|
||||||
|
inline
|
||||||
|
OS OperatingSystem()
|
||||||
|
{
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
return OS::android_os;
|
||||||
|
#elif defined(__gnu_linux__) || defined(__linux__)
|
||||||
|
return OS::linux_os;
|
||||||
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#if defined(TARGET_OS_IPHONE)
|
||||||
|
return OS::ios_os;
|
||||||
|
#else
|
||||||
|
return OS::mac_os;
|
||||||
|
#endif
|
||||||
|
#elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || defined(WIN32)
|
||||||
|
return OS::windows_os;
|
||||||
|
#else
|
||||||
|
return OS::unknown_os;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} //portable
|
||||||
|
|
||||||
|
#define SystemExit(errorlevel) portable::StubExit(errorlevel,"Exit ",__FILE__, __FUNCTION__, __LINE__)
|
||||||
|
|
||||||
|
#define SystemAssert(expression) (void)( (!!(expression)) || portable::StubAssert(-1,#expression,__FILE__, __FUNCTION__, __LINE__) )
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define ANSI_RED
|
||||||
|
#define ANSI_GRN
|
||||||
|
#define ANSI_YEL
|
||||||
|
#define ANSI_BLU
|
||||||
|
#define ANSI_MAG
|
||||||
|
#define ANSI_CYN
|
||||||
|
#define ANSI_WHT
|
||||||
|
#define ANSI_CLR
|
||||||
|
#else
|
||||||
|
#define ANSI_RED "\x1B[31m"
|
||||||
|
#define ANSI_GRN "\x1B[32m"
|
||||||
|
#define ANSI_YEL "\x1B[33m"
|
||||||
|
#define ANSI_BLU "\x1B[34m"
|
||||||
|
#define ANSI_MAG "\x1B[35m"
|
||||||
|
#define ANSI_CYN "\x1B[36m"
|
||||||
|
#define ANSI_WHT "\x1B[37m"
|
||||||
|
#define ANSI_CLR "\x1B[0m"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// printf(ANSI_RED "red" ANSI_CLR);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
251
auxil/bifcl/auxil/libunistd/portable/SystemLog.h
Normal file
251
auxil/bifcl/auxil/libunistd/portable/SystemLog.h
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
// portable/SystemLog.h
|
||||||
|
// Copyright 2018/4/3 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef SystemLog_h
|
||||||
|
#define SystemLog_h
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef QT
|
||||||
|
#include <QStringView>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace portable {
|
||||||
|
|
||||||
|
#ifdef OLD_SYSLOG
|
||||||
|
|
||||||
|
#ifdef SYSTEM_LOGFILE
|
||||||
|
extern FILE* systemLogfile;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline
|
||||||
|
void SysLogMsg(const char* msg,const char* function)
|
||||||
|
{ printf("TRACE: %s, %s\n",msg,function);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
inline
|
||||||
|
void SysLogError(const char* msg,const char* function)
|
||||||
|
{ printf("ERROR: %s, %s (%s)\n",msg,function,strerror(errno));
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
DebugBreak();
|
||||||
|
#else
|
||||||
|
raise(SIGTRAP);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void LogMsg(const char* msg)
|
||||||
|
{ puts(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void LogMsg(const std::string& msg)
|
||||||
|
{ puts(msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void LogError(const std::string& msg)
|
||||||
|
{ printf("ERROR: %s\n",msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOGGER_QUIET
|
||||||
|
#define SYSLOG(msg)
|
||||||
|
#define SYSERR(msg)
|
||||||
|
#else
|
||||||
|
#define SYSLOG(msg) SysLogMsg(msg,__FUNCTION__)
|
||||||
|
#define SYSERR(msg) SysLogError(msg,__FUNCTION__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
__attribute__((__format__(__printf__, 2,3)))
|
||||||
|
void debugLogf(const char * functionName, const char * format, ...)
|
||||||
|
{ va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
char buffer[1024];
|
||||||
|
vsnprintf(buffer, sizeof(buffer) / sizeof(*buffer), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline
|
||||||
|
void SystemLog(const char* filename,int lineNo,const char* msg)
|
||||||
|
{/*OutputDebugStringA("My output string.");
|
||||||
|
_RPTF2(_CRT_WARN, "In NameOfThisFunc( )," " someVar= %d, otherVar= %d\n", someVar, otherVar );
|
||||||
|
_CRT_WARN, _CRT_ERROR, and _CRT_ASSERT.*/
|
||||||
|
if(!filename)
|
||||||
|
{ filename = "unknown";
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
enum {len = 60};
|
||||||
|
char buffer[len];
|
||||||
|
buffer[0] = 0;
|
||||||
|
const int wsaError = WSAGetLastError();
|
||||||
|
const DWORD num = FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
wsaError,
|
||||||
|
0,//MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPSTR)&buffer,
|
||||||
|
len-1,
|
||||||
|
NULL);
|
||||||
|
if(!msg && *buffer)
|
||||||
|
{ msg = buffer;
|
||||||
|
buffer[len-1] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
if(!msg || !*msg)
|
||||||
|
{ msg = strerror(errno);
|
||||||
|
}
|
||||||
|
printf("%s@%i: %s\n",filename,lineNo,msg);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#ifdef QT
|
||||||
|
qDebug() << filename << "@" << lineNo << ": " << msg;
|
||||||
|
#else
|
||||||
|
_CrtDbgReport( _CRT_WARN,filename,lineNo,msg,NULL);
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_BREAK
|
||||||
|
DebugBreak();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef SYSTEM_LOGFILE
|
||||||
|
if(systemLogfile)
|
||||||
|
{ fprintf(systemLogfile,"%s@%s: %s\n",filename,lineNo,msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void StatusMsg(const char* msg)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#ifdef QT
|
||||||
|
qDebug() << msg;
|
||||||
|
#else
|
||||||
|
OutputDebugStringA(msg);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
printf("Status: %s\n",msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define TRACE(msg) portable::SystemLog(__FILE__,__LINE__,msg)
|
||||||
|
#else
|
||||||
|
#define TRACE(msg)
|
||||||
|
#endif
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
|
||||||
|
inline
|
||||||
|
unsigned IsArg(const char* mode,int argc,char* argv[],bool isTerse = true)
|
||||||
|
{ if(!mode)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
for(unsigned i=1; i < (unsigned) argc; i++)
|
||||||
|
{ const char* arg = argv[i];
|
||||||
|
if((mode[0] != arg[0]) || (mode[1] != arg[1]))
|
||||||
|
{ continue;
|
||||||
|
}
|
||||||
|
if(isTerse)
|
||||||
|
{ return i;
|
||||||
|
}
|
||||||
|
if(!strcmp(mode,argv[i]+1))
|
||||||
|
{ return i;
|
||||||
|
} }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IsArgMode(mode) portable::IsArg(mode,argc,argv)
|
||||||
|
|
||||||
|
inline
|
||||||
|
void tty_msg(const char* tag,const char* msg,const char* functionName=0,int lineNo=0)
|
||||||
|
{ static int tty_state = -1;
|
||||||
|
if(-1 == tty_state)
|
||||||
|
{ tty_state = isatty(fileno(stdout));
|
||||||
|
}
|
||||||
|
if(!tty_state)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
if(functionName)
|
||||||
|
{ printf("%s: %s (%s:%i)\n",tag,msg,functionName,lineNo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("%s: %s\n",tag,msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const char* Safe(const char* msg)
|
||||||
|
{ if(!msg)
|
||||||
|
{ return "unknown";
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void syslog_function(int level,const char* tag,const char* msg,const char* function,int lineno)
|
||||||
|
{ if(!function)
|
||||||
|
{ syslog(level,"%s: %s",Safe(tag),Safe(msg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
syslog(level,"%s: %s (%s:%i)",Safe(tag),Safe(msg),function,lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void status_msg(const char* msg,const char* function=0,int lineno=0)
|
||||||
|
{ syslog_function(LOG_NOTICE,"Status",msg,function,lineno);
|
||||||
|
tty_msg("Status",msg,function,lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void warning_msg(const char* msg,const char* function=0,int lineno=0)
|
||||||
|
{ syslog(LOG_WARNING,"Warning: %s",msg);
|
||||||
|
tty_msg("Warning",msg,function,lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void trace_msg(const char* msg,const char* function=0,int lineno=0)
|
||||||
|
{ tty_msg("Trace",msg,function,lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void error_msg(const char* msg,const char* function,int lineno)
|
||||||
|
{ syslog(LOG_ERR,"Error: %s, %s:%i",msg,function,lineno);
|
||||||
|
tty_msg("Error",msg,function,lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRACE_MSG_FUNCTIONS
|
||||||
|
#define status_msg(msg) portable::status_msg(msg,__FUNCTION__,__LINE__)
|
||||||
|
#define warning_msg(msg) portable::warning_msg(msg,__FUNCTION__,__LINE__)
|
||||||
|
#define trace_msg(msg) portable::trace_msg(msg,__FUNCTION__,__LINE__)
|
||||||
|
#else
|
||||||
|
#define status_msg(msg) portable::status_msg(msg)
|
||||||
|
#define warning_msg(msg) portable::warning_msg(msg)
|
||||||
|
#define trace_msg(msg) portable::trace_msg(msg)
|
||||||
|
#endif
|
||||||
|
#define error_msg(msg) portable::error_msg(msg,__FUNCTION__,__LINE__)
|
||||||
|
#define return_msg(enum_name) status_msg(#enum_name);return int(enum_name)
|
||||||
|
#define show_msg(enum_name) status_msg(#enum_name)
|
||||||
|
|
||||||
|
inline
|
||||||
|
void signal_safe_puts(const char* msg)
|
||||||
|
{ if(msg)
|
||||||
|
{ write(fileno(stdout),msg,(int) strlen(msg));
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
||||||
144
auxil/bifcl/auxil/libunistd/portable/Text.h
Normal file
144
auxil/bifcl/auxil/libunistd/portable/Text.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// Text.h
|
||||||
|
// Libunistd Copyright (c) 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef Text_h
|
||||||
|
#define Text_h
|
||||||
|
|
||||||
|
//#include <array>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
template <unsigned width>
|
||||||
|
class Text
|
||||||
|
//: public std::array<char,width+1>
|
||||||
|
{ char data[width+1];
|
||||||
|
bool IsOverflow(size_t pos) const
|
||||||
|
{ return pos > width;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Text()
|
||||||
|
{ clear();
|
||||||
|
}
|
||||||
|
Text(const char* s)
|
||||||
|
{ assign(s);
|
||||||
|
}
|
||||||
|
Text(const char* s,size_t count)
|
||||||
|
{ assign(s, 0, count);
|
||||||
|
}
|
||||||
|
Text(const char* s,size_t pos,size_t count)
|
||||||
|
{ assign(s,pos,count);
|
||||||
|
}
|
||||||
|
Text(const Text& s)
|
||||||
|
{ assign(s);
|
||||||
|
}
|
||||||
|
void clear()
|
||||||
|
{ data[0] = 0;
|
||||||
|
}
|
||||||
|
bool empty() const
|
||||||
|
{ return 0 == data[0];
|
||||||
|
}
|
||||||
|
size_t size() const
|
||||||
|
{ return strlen(data);
|
||||||
|
}
|
||||||
|
size_t length() const
|
||||||
|
{ return size();
|
||||||
|
}
|
||||||
|
size_t capacity() const
|
||||||
|
{ return width;
|
||||||
|
}
|
||||||
|
const char* c_str() const
|
||||||
|
{ return this->data();
|
||||||
|
}
|
||||||
|
operator const char*() const
|
||||||
|
{ return c_str();
|
||||||
|
}
|
||||||
|
void ends(size_t len = width)
|
||||||
|
{ if(len > width)
|
||||||
|
{ len = width;
|
||||||
|
}
|
||||||
|
data[len] = 0;
|
||||||
|
}
|
||||||
|
Text& append(const char* s)
|
||||||
|
{ strncat(data,s,width);
|
||||||
|
ends();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Text& append(const Text& s)
|
||||||
|
{ return append(s.data);
|
||||||
|
}
|
||||||
|
Text& operator+=(const char* s)
|
||||||
|
{ return append(s);
|
||||||
|
}
|
||||||
|
Text& operator+=(const Text& s)
|
||||||
|
{ return append(s);
|
||||||
|
}
|
||||||
|
Text& assign(const char* s)
|
||||||
|
{ strncpy(data,s,width);
|
||||||
|
ends();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Text& assign(const char* s,size_t pos)
|
||||||
|
{ return assign(s+pos);
|
||||||
|
}
|
||||||
|
Text& assign(const char* s,size_t pos,size_t count)
|
||||||
|
{ s+=pos;
|
||||||
|
const size_t len = (count <= width) ? count:width;
|
||||||
|
strncpy(data,s,len);
|
||||||
|
ends(len);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Text& assign(const Text& s,size_t pos,size_t count)
|
||||||
|
{ return assign(s.data,pos,count);
|
||||||
|
}
|
||||||
|
Text& assign(const Text& s)
|
||||||
|
{ return assign(s.data);
|
||||||
|
}
|
||||||
|
Text& operator=(const char* s)
|
||||||
|
{ return assign(s);
|
||||||
|
}
|
||||||
|
Text& operator=(const Text& s)
|
||||||
|
{ return assign(s);
|
||||||
|
}
|
||||||
|
char* operator[](size_t pos)
|
||||||
|
{ if(IsOverflow(pos))
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
return data[pos];
|
||||||
|
}
|
||||||
|
const char* operator[](size_t pos) const
|
||||||
|
{ if(IsOverflow(pos))
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
return data[pos];
|
||||||
|
}
|
||||||
|
bool operator==(const char* s) const
|
||||||
|
{ if(!s)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return !strcmp(data,s);
|
||||||
|
}
|
||||||
|
bool operator==(const Text& s) const
|
||||||
|
{ return *this == s.data;
|
||||||
|
}
|
||||||
|
bool operator!=(const char* s) const
|
||||||
|
{ if(!s)
|
||||||
|
{ return true;
|
||||||
|
}
|
||||||
|
return 0 != strcmp(data,s);
|
||||||
|
}
|
||||||
|
bool operator!=(const Text& s) const
|
||||||
|
{ return *this != s.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
|
||||||
|
#endif
|
||||||
74
auxil/bifcl/auxil/libunistd/portable/UnrealLogger.h
Normal file
74
auxil/bifcl/auxil/libunistd/portable/UnrealLogger.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// UnrealLogger.h
|
||||||
|
// Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// Open source license MIT
|
||||||
|
|
||||||
|
/* Add this to your UE project header:
|
||||||
|
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(homStream, Log, All);
|
||||||
|
|
||||||
|
Add to project source file:
|
||||||
|
|
||||||
|
#include <portable/Logger.h>
|
||||||
|
DEFINE_LOG_CATEGORY(your_plugin_name);
|
||||||
|
UnrealLogger logger("your_plugin_name");
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UnrealLogger_h
|
||||||
|
#define UnrealLogger_h
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <AllowWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#include <Runtime/CoreUObject/Public/UObject/ObjectBase.h>
|
||||||
|
#include <portable/Counter.h>
|
||||||
|
#include <crtdbg.h>
|
||||||
|
|
||||||
|
class UnrealLogger
|
||||||
|
{ FString s;
|
||||||
|
FName categoryName;
|
||||||
|
Counter c;
|
||||||
|
void Puts(const char* filename,int lineNo,const char* msg,ELogVerbosity::Type t)
|
||||||
|
{ s=c(msg);
|
||||||
|
puts(msg);
|
||||||
|
FMsg::Logf_Internal(filename, lineNo, categoryName, t, *s);
|
||||||
|
s.Reset();
|
||||||
|
}
|
||||||
|
void OutputWindow(const char* filename,int lineNo,const char* msg)
|
||||||
|
{//OutputDebugStringA("My output string.");
|
||||||
|
//_RPTF2(_CRT_WARN, "In NameOfThisFunc( )," " someVar= %d, otherVar= %d\n", someVar, otherVar );
|
||||||
|
//_CRT_WARN, _CRT_ERROR, and _CRT_ASSERT.
|
||||||
|
#ifdef _DEBUG
|
||||||
|
_CrtDbgReport( _CRT_WARN,filename,lineNo,msg,NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
UnrealLogger(const char* loggerName)
|
||||||
|
{ categoryName = loggerName;
|
||||||
|
OutputWindow(loggerName,0,"_CrtDbgReport enabled");
|
||||||
|
}
|
||||||
|
void Log(const char* filename,int lineNo,const char* msg)
|
||||||
|
{ OutputWindow(filename,lineNo,msg);
|
||||||
|
Puts(filename,lineNo,msg,ELogVerbosity::Display);
|
||||||
|
}
|
||||||
|
void Error(const char* filename,int lineNo,const char* msg)
|
||||||
|
{ s="LogError: ";
|
||||||
|
s+=msg;
|
||||||
|
Puts(filename,lineNo,TCHAR_TO_ANSI(*s),ELogVerbosity::Warning);
|
||||||
|
s.Reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern UnrealLogger logger;
|
||||||
|
|
||||||
|
#define LogMsg(msg) logger.Log(__FILE__, __LINE__,msg)
|
||||||
|
#define LogError(msg) logger.Error(__FILE__, __LINE__,msg)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <HideWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
32
auxil/bifcl/auxil/libunistd/portable/VBuffer.h
Normal file
32
auxil/bifcl/auxil/libunistd/portable/VBuffer.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// VBuffer.h
|
||||||
|
// Copyright 2018/7/25 Robin.Rowe@cinepaint.org
|
||||||
|
// License open source MIT/BSD
|
||||||
|
|
||||||
|
#ifndef VBuffer_h
|
||||||
|
#define VBuffer_h
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class VBuffer
|
||||||
|
: public std::vector<char>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VBuffer()
|
||||||
|
{}
|
||||||
|
VBuffer(size_t bufsize)
|
||||||
|
{ resize(bufsize);
|
||||||
|
}
|
||||||
|
operator char*()
|
||||||
|
{ return &(*this)[0];
|
||||||
|
}
|
||||||
|
operator const char*() const
|
||||||
|
{ return &(*this)[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
48
auxil/bifcl/auxil/libunistd/portable/Vec3d.h
Normal file
48
auxil/bifcl/auxil/libunistd/portable/Vec3d.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// portable/Vec3d.h
|
||||||
|
// Copyright 2016/1/16 Robin.Rowe@cinepaint.org
|
||||||
|
// License open source MIT/BSD
|
||||||
|
|
||||||
|
#ifndef Vec3d_h
|
||||||
|
#define Vec3d_h
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Vec3d
|
||||||
|
{ double x;
|
||||||
|
double y;
|
||||||
|
double z;
|
||||||
|
int size() const
|
||||||
|
{ return sizeof(*this) == 3*sizeof(double) ? sizeof(*this) : 0;
|
||||||
|
}
|
||||||
|
void Copy(const Vec3d& v)
|
||||||
|
{ x=v.x;
|
||||||
|
y=v.y;
|
||||||
|
z=v.z;
|
||||||
|
}
|
||||||
|
void Copy(const double* v)
|
||||||
|
{ x=v[0];
|
||||||
|
y=v[1];
|
||||||
|
z=v[2];
|
||||||
|
}
|
||||||
|
Vec3d()
|
||||||
|
: x(0.)
|
||||||
|
, y(0.)
|
||||||
|
, z(0.)
|
||||||
|
{}
|
||||||
|
Vec3d(const Vec3d& v)
|
||||||
|
{ Copy(v);
|
||||||
|
}
|
||||||
|
Vec3d& operator=(const Vec3d& v)
|
||||||
|
{ Copy(v);
|
||||||
|
}
|
||||||
|
bool operator!=(const Vec3d& v) const
|
||||||
|
{ if(x!=v.x || y!=v.y || z!=v.z)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
30
auxil/bifcl/auxil/libunistd/portable/VerboseCounter.h
Normal file
30
auxil/bifcl/auxil/libunistd/portable/VerboseCounter.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// VerboseCounter.h
|
||||||
|
// Created by Robin Rowe on 8/26/2016
|
||||||
|
// Libunistd Copyright (c) 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef VerboseCounter_h
|
||||||
|
#define VerboseCounter_h
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class VerboseCounter
|
||||||
|
{ unsigned counter;
|
||||||
|
unsigned maxMod;
|
||||||
|
public:
|
||||||
|
VerboseCounter(unsigned maxMod)
|
||||||
|
: counter(0)
|
||||||
|
, maxMod(maxMod)
|
||||||
|
{}
|
||||||
|
VerboseCounter& operator++(int)
|
||||||
|
{ counter++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
operator bool() const
|
||||||
|
{ return !(counter % maxMod);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
108
auxil/bifcl/auxil/libunistd/portable/WormFile.cpp
Normal file
108
auxil/bifcl/auxil/libunistd/portable/WormFile.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// WormFile.cpp compressed WORM file using Snappy or Brotli
|
||||||
|
// Copyright 2017/3/14 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#include "WormFile.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
bool WormFile::WriteFileHeader()
|
||||||
|
{ if(!ioFile.Write(fileSig))
|
||||||
|
{ lastError = WRITE_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WormFile::ReadFileHeader()
|
||||||
|
{ const unsigned length = 8;
|
||||||
|
char buffer[length+1];
|
||||||
|
if(!ioFile.Read(buffer,length))
|
||||||
|
{ lastError = READ_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffer[length] = 0;
|
||||||
|
if(strcmp(buffer,fileSig))
|
||||||
|
{ lastError = INVALID_FORMAT;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WormFile::WriteBlockHeader(unsigned size,unsigned crc)
|
||||||
|
{ if(!ioFile.Write(blockSig,4))
|
||||||
|
{ lastError = WRITE_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ioFile.Write(size))
|
||||||
|
{ lastError = WRITE_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!ioFile.Write(crc))
|
||||||
|
{ lastError = WRITE_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned WormFile::ReadBlockHeader()
|
||||||
|
{ char buffer[5];
|
||||||
|
if (!ioFile.Read(buffer, 4))
|
||||||
|
{ lastError = READ_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffer[4]=0;
|
||||||
|
if(strcmp(blockSig,buffer))
|
||||||
|
{ lastError = BLOCK_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned size = 0;
|
||||||
|
if (!ioFile.Read(size))
|
||||||
|
{ lastError = READ_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned crc = 0;
|
||||||
|
if (!ioFile.Read(crc))
|
||||||
|
{ lastError = READ_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned WormFile::Write(const char* data,size_t length)
|
||||||
|
{ // returns blob offset
|
||||||
|
offset = ioFile.Tell();
|
||||||
|
if(!offset)
|
||||||
|
{ if(!WriteFileHeader())
|
||||||
|
{ return 0;
|
||||||
|
} }
|
||||||
|
if(!WriteBlockHeader((unsigned)length))
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
if(!ioFile.Write(data,length))
|
||||||
|
{ lastError=WRITE_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned WormFile::Seek(unsigned offset)
|
||||||
|
{ // returns blob size
|
||||||
|
if(!ioFile.Seek(offset))
|
||||||
|
{ lastError = SEEK_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ReadBlockHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WormFile::Read(char* buffer,size_t len)
|
||||||
|
{ // uncompressed data
|
||||||
|
if(!ioFile.Read(buffer,len))
|
||||||
|
{ lastError = READ_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
57
auxil/bifcl/auxil/libunistd/portable/WormFile.h
Normal file
57
auxil/bifcl/auxil/libunistd/portable/WormFile.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// WormFile.h compressed WORM file using Snappy or Brotli
|
||||||
|
// Copyright 2017/3/14 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
// File extension: 2017_Q1_mail.wrm
|
||||||
|
|
||||||
|
#ifndef WormFile_h
|
||||||
|
#define WormFile_h
|
||||||
|
|
||||||
|
#include "StdFile.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class WormFile
|
||||||
|
{ StdFile ioFile;
|
||||||
|
unsigned offset;
|
||||||
|
const char* fileSig;
|
||||||
|
const char* blockSig;
|
||||||
|
bool WriteFileHeader();
|
||||||
|
bool ReadFileHeader();
|
||||||
|
bool WriteBlockHeader(unsigned size, unsigned crc = 0);
|
||||||
|
unsigned ReadBlockHeader();
|
||||||
|
public:
|
||||||
|
enum LastError
|
||||||
|
{ NONE,
|
||||||
|
FILE_NOT_FOUND,
|
||||||
|
WRITE_ERROR,
|
||||||
|
SEEK_ERROR,
|
||||||
|
READ_ERROR,
|
||||||
|
INVALID_FORMAT,
|
||||||
|
BLOCK_ERROR
|
||||||
|
};
|
||||||
|
LastError lastError;
|
||||||
|
WormFile()
|
||||||
|
{ lastError=NONE;
|
||||||
|
offset=0;
|
||||||
|
fileSig="WRM:None";
|
||||||
|
blockSig = "WRM:";
|
||||||
|
}
|
||||||
|
bool Open(const char* filename)
|
||||||
|
{ if(!ioFile.Open(filename,"ab+"))
|
||||||
|
{ lastError = FILE_NOT_FOUND;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
unsigned Write(const char* data,size_t length);// returns blob offset
|
||||||
|
unsigned Seek(unsigned offset);// returns blob size
|
||||||
|
bool Read(char* buffer,size_t len);// uncompressed data
|
||||||
|
void Close()
|
||||||
|
{ ioFile.Close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
37
auxil/bifcl/auxil/libunistd/portable/bsd_string.h
Normal file
37
auxil/bifcl/auxil/libunistd/portable/bsd_string.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* bsd/string.h
|
||||||
|
Copyright 2018/02/01 Robin.Rowe@CinePaint.org
|
||||||
|
License MIT (http://opensource.org/licenses/mit-license.php)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef bsd_string_h
|
||||||
|
#define bsd_string_h
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
inline
|
||||||
|
size_t strlcpy(char *dst, const char *src, size_t size)
|
||||||
|
{ if(!dst || !src)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
const char* end = strncpy(dst,src,size);
|
||||||
|
const size_t length = end - dst;
|
||||||
|
if(length>=size)
|
||||||
|
{ dst[size-1] = 0;
|
||||||
|
return size-1;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
size_t strlcat(char *dst, const char *src, size_t size)
|
||||||
|
{ if(!dst || !src)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
const size_t length = strlen(dst);
|
||||||
|
char* p = dst + length;
|
||||||
|
return length + strlcpy(p,src,size - length);
|
||||||
|
}
|
||||||
|
#pragma warning(default:4996)
|
||||||
|
|
||||||
|
#endif
|
||||||
13
auxil/bifcl/auxil/libunistd/portable/endian.h
Normal file
13
auxil/bifcl/auxil/libunistd/portable/endian.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// endian.h
|
||||||
|
// Copyright 2016 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef endian_h
|
||||||
|
#define endian_h
|
||||||
|
|
||||||
|
class endian
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
53
auxil/bifcl/auxil/libunistd/portable/homedir.h
Normal file
53
auxil/bifcl/auxil/libunistd/portable/homedir.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// homedir.h
|
||||||
|
// Copyright 2016 Robin.Rowe@cinepaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef Homedir_h
|
||||||
|
#define Homedir_h
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <AllowWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool GetHomedir(std::string& path)
|
||||||
|
{ wchar_t wbuffer[MAX_PATH+1];
|
||||||
|
if (SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, wbuffer) != S_OK)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
char buffer[MAX_PATH*4+1];
|
||||||
|
const int buflen = WideCharToMultiByte(CP_UTF8, 0, wbuffer, lstrlenW(wbuffer), buffer, MAX_PATH*4, NULL, NULL);
|
||||||
|
if (buflen <= 0)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
buffer[buflen] = 0;
|
||||||
|
path = buffer;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UNREAL_ENGINE
|
||||||
|
#include <HideWindowsPlatformTypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool GetHomedir(std::string& path)
|
||||||
|
{ const char* dir = getenv("HOMEDIR");
|
||||||
|
if(!dir)
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
path = dir;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
145
auxil/bifcl/auxil/libunistd/portable/http/HtmlPage.h
Normal file
145
auxil/bifcl/auxil/libunistd/portable/http/HtmlPage.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// libportable/HtmlPage.h
|
||||||
|
// Created by Robin Rowe on 2015/6/9
|
||||||
|
// License MIT Open Source
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HtmlPage_h
|
||||||
|
#define HtmlPage_h
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class HtmlHeader
|
||||||
|
{public:
|
||||||
|
HtmlHeader()
|
||||||
|
{ cout<<"<header>/n";
|
||||||
|
}
|
||||||
|
~HtmlHeader()
|
||||||
|
{ cout<<"</header>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlTitle
|
||||||
|
{public:
|
||||||
|
HtmlTitle()
|
||||||
|
{ cout<<"<title>\n";
|
||||||
|
}
|
||||||
|
~HtmlTitle()
|
||||||
|
{ cout<<"</title>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlPage
|
||||||
|
{public:
|
||||||
|
HtmlPage(const char* contentType=0)
|
||||||
|
{ if(contentType)
|
||||||
|
{ cout<<"Content-Type: "<<contentType<<"\n"
|
||||||
|
"\n";
|
||||||
|
}
|
||||||
|
cout<<"<html>\n";
|
||||||
|
}
|
||||||
|
~HtmlPage()
|
||||||
|
{ cout<<"<html>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlBody
|
||||||
|
{public:
|
||||||
|
HtmlBody()
|
||||||
|
{ cout<<"<body>\n";
|
||||||
|
}
|
||||||
|
~HtmlBody()
|
||||||
|
{ cout<<"</body>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlP
|
||||||
|
{public:
|
||||||
|
HtmlP()
|
||||||
|
{ cout<<"\n<p>";
|
||||||
|
}
|
||||||
|
~HtmlP()
|
||||||
|
{ cout<<"</p>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlTable
|
||||||
|
{public:
|
||||||
|
HtmlTable(unsigned border=0)
|
||||||
|
{ cout<<"<table border=\""<<border<<"\">\n";
|
||||||
|
}
|
||||||
|
~HtmlTable()
|
||||||
|
{ cout<<"</table>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlTr
|
||||||
|
{public:
|
||||||
|
HtmlTr()
|
||||||
|
{ cout<<"<tr>\n";
|
||||||
|
}
|
||||||
|
~HtmlTr()
|
||||||
|
{ cout<<"</tr>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlTd
|
||||||
|
{public:
|
||||||
|
HtmlTd()
|
||||||
|
{ cout<<"<td>";
|
||||||
|
}
|
||||||
|
~HtmlTd()
|
||||||
|
{ cout<<"</td>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlList
|
||||||
|
{public:
|
||||||
|
HtmlList()
|
||||||
|
{ cout<<"<ol>\n";
|
||||||
|
}
|
||||||
|
~HtmlList()
|
||||||
|
{ cout<<"</ol>\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlListI
|
||||||
|
{public:
|
||||||
|
HtmlListI()
|
||||||
|
{ cout<<"<li>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlHeading
|
||||||
|
{ unsigned level;
|
||||||
|
public:
|
||||||
|
HtmlHeading(unsigned level)
|
||||||
|
: level(level)
|
||||||
|
{ cout<<"<h"<<level<<">";
|
||||||
|
}
|
||||||
|
~HtmlHeading()
|
||||||
|
{ cout<<"</h"<<level<<">";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlFormat
|
||||||
|
{ const char* format;
|
||||||
|
public:
|
||||||
|
HtmlFormat(const char* format)
|
||||||
|
: format(format)
|
||||||
|
{ cout<<"<"<<format<<">";
|
||||||
|
}
|
||||||
|
~HtmlFormat()
|
||||||
|
{ cout<<"</"<<format<<">";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HtmlHref
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HtmlHref(const char* description,const char* link)
|
||||||
|
{ cout<<"<a href=\""<<link<<"\">"<<description<<"</a>";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
426
auxil/bifcl/auxil/libunistd/portable/http/Http.cpp
Normal file
426
auxil/bifcl/auxil/libunistd/portable/http/Http.cpp
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
// Http.cpp
|
||||||
|
// 2013/11/20
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include "Http.h"
|
||||||
|
|
||||||
|
//#define VERBOSE
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* read a line from file descriptor
|
||||||
|
* returns the number of bytes read. negative if a read error occured
|
||||||
|
* before the end of line or the max.
|
||||||
|
* cariage returns (CR) are ignored.
|
||||||
|
*/
|
||||||
|
int Http::http_read_line (int fd,char *buffer,int max)
|
||||||
|
{ /* not efficient on long lines (multiple unbuffered 1 char reads) */
|
||||||
|
int n=0;
|
||||||
|
while (n<max) {
|
||||||
|
if (read(fd,buffer,1)!=1) {
|
||||||
|
n= -n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
if (*buffer=='\015') continue; /* ignore CR */
|
||||||
|
if (*buffer=='\012') break; /* LF is the separator */
|
||||||
|
buffer++;
|
||||||
|
}
|
||||||
|
*buffer=0;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read data from file descriptor
|
||||||
|
* retries reading until the number of bytes requested is read.
|
||||||
|
* returns the number of bytes read. negative if a read error (EOF) occured
|
||||||
|
* before the requested length.
|
||||||
|
*/
|
||||||
|
int Http::http_read_buffer (int fd,char *buffer,int length)
|
||||||
|
{ if(!buffer)
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
const int bytes=read(fd,buffer,length);
|
||||||
|
if(bytes==length)
|
||||||
|
{ buffer[length-1]=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ buffer[bytes]=0;
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* beware that filename+type+rest of header must not exceed MAXBUF */
|
||||||
|
/* so we limit filename to 256 and type to 64 chars in put & get */
|
||||||
|
#define MAXBUF 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pseudo general http query
|
||||||
|
*
|
||||||
|
* send a command and additional headers to the http server.
|
||||||
|
* optionally through the proxy (if http_proxy_server and http_proxy_port are
|
||||||
|
* set).
|
||||||
|
*
|
||||||
|
* Limitations: the url is truncated to first 256 chars and
|
||||||
|
* the server name to 128 in case of proxy request.
|
||||||
|
*/
|
||||||
|
bool Http::http_query(const char *command, const char *url,const char *additional_header, querymode mode, char* data, int length, int *pfd)
|
||||||
|
{ struct sockaddr_in server;
|
||||||
|
char header[MAXBUF];
|
||||||
|
int hlg;
|
||||||
|
if (pfd)
|
||||||
|
{ *pfd=-1;
|
||||||
|
}
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
hostent* hp = gethostbyname( http_proxy_server.size() ? http_proxy_server.c_str() : http_server.c_str() );
|
||||||
|
if(!hp)
|
||||||
|
{ ret = ERRHOST;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
memset((char *) &server,0, sizeof(server));
|
||||||
|
memmove((char *) &server.sin_addr, hp->h_addr, hp->h_length);
|
||||||
|
server.sin_family = hp->h_addrtype;
|
||||||
|
server.sin_port = htons( http_proxy_server.size() ? u_short(http_proxy_port):u_short(http_port) );
|
||||||
|
int s = (int) socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(s < 0)
|
||||||
|
{ ret = ERRSOCK;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
|
||||||
|
if (connect(s, (const sockaddr*) &server, sizeof(server)) < 0)
|
||||||
|
{ ret=ERRCONN;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
if(pfd)
|
||||||
|
{ *pfd=s;
|
||||||
|
}
|
||||||
|
if (http_proxy_server.size())
|
||||||
|
{ sprintf(header, "%s http://%.128s:%d/%.256s HTTP/1.1\r\n"
|
||||||
|
"Host: %s:%i\r\n"
|
||||||
|
"Connection: close\r\n"
|
||||||
|
"User-Agent: %s\r\n"
|
||||||
|
"%s\r\n\r\n",
|
||||||
|
command,http_server.c_str(), http_port, url,
|
||||||
|
http_server.c_str(),http_port,
|
||||||
|
http_user_agent,
|
||||||
|
additional_header);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ sprintf(header, "%s %.256s HTTP/1.1\r\n"
|
||||||
|
"Host: %s:%i\r\n"
|
||||||
|
"Connection: close\r\n"
|
||||||
|
"User-Agent: %s\r\n"
|
||||||
|
"%s\r\n\r\n",
|
||||||
|
command,url,
|
||||||
|
http_server.c_str(), http_port,
|
||||||
|
http_user_agent,
|
||||||
|
additional_header);
|
||||||
|
}
|
||||||
|
hlg=(int)strlen(header);
|
||||||
|
if(write(s,header,hlg)!=hlg)
|
||||||
|
{ ret=ERRWRHD;
|
||||||
|
close(s);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
if(length && data && (write(s,data,length)!=length) )
|
||||||
|
{ ret=ERRWRDT;
|
||||||
|
close(s);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
const int bytes = http_read_line(s,header,MAXBUF-1);
|
||||||
|
#ifdef VERBOSE
|
||||||
|
fputs(header,stderr);
|
||||||
|
putc('\n',stderr);
|
||||||
|
#endif
|
||||||
|
if(bytes<=0)
|
||||||
|
{ ret=ERRRDHD;
|
||||||
|
close(s);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
if(sscanf(header,"HTTP/1.%*d %03d",(int*)&ret)!=1)
|
||||||
|
{ ret=ERRPAHD;
|
||||||
|
close(s);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
if(mode==KEEP_OPEN)
|
||||||
|
{ return IsGood();
|
||||||
|
}
|
||||||
|
close(s);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Put data on the server
|
||||||
|
*
|
||||||
|
* This function sends data to the http data server.
|
||||||
|
* The data will be stored under the ressource name filename.
|
||||||
|
* returns a negative error code or a positive code from the server
|
||||||
|
*
|
||||||
|
* limitations: filename is truncated to first 256 characters
|
||||||
|
* and type to 64.
|
||||||
|
*/
|
||||||
|
bool Http::http_put(char *data,int length,int overwrite,char *type)
|
||||||
|
{
|
||||||
|
char header[MAXBUF];
|
||||||
|
if (type)
|
||||||
|
sprintf(header,"Content-length: %d\015\012Content-type: %.64s\015\012%s",
|
||||||
|
length,
|
||||||
|
type ,
|
||||||
|
overwrite ? "Control: overwrite=1\015\012" : ""
|
||||||
|
);
|
||||||
|
else
|
||||||
|
sprintf(header,"Content-length: %d\015\012%s",length,
|
||||||
|
overwrite ? "Control: overwrite=1\015\012" : ""
|
||||||
|
);
|
||||||
|
return http_query("PUT",filename.c_str(),header,CLOSE, data, length, NULL);
|
||||||
|
}
|
||||||
|
#pragma warning(default : 4996)
|
||||||
|
/*
|
||||||
|
* Get data from the server
|
||||||
|
*
|
||||||
|
* This function gets data from the http data server.
|
||||||
|
* The data is read from the ressource named filename.
|
||||||
|
* Address of new new allocated memory block is filled in pdata
|
||||||
|
* whose length is returned via plength.
|
||||||
|
*
|
||||||
|
* returns a negative error code or a positive code from the server
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* limitations: filename is truncated to first 256 characters
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
|
||||||
|
bool Http::http_get(char *pdata,int *plength,char *typebuf)
|
||||||
|
{ char header[MAXBUF];
|
||||||
|
char *pc;
|
||||||
|
int fd;
|
||||||
|
int n,length=-1;
|
||||||
|
if (!pdata)
|
||||||
|
{ ret = ERRNULL;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
*pdata=0;
|
||||||
|
if (typebuf)
|
||||||
|
{ *typebuf='\0';
|
||||||
|
}
|
||||||
|
http_query("GET",filename.c_str(),"",KEEP_OPEN, NULL, 0, &fd);
|
||||||
|
if(ret!=200)
|
||||||
|
{ if (ret>=0)
|
||||||
|
{ close(fd);
|
||||||
|
}
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
for(;;)
|
||||||
|
{ n=http_read_line(fd,header,MAXBUF-1);
|
||||||
|
#ifdef VERBOSE
|
||||||
|
fputs(header,stderr);
|
||||||
|
putc('\n',stderr);
|
||||||
|
#endif
|
||||||
|
if (n<=0)
|
||||||
|
{ close(fd);
|
||||||
|
ret = ERRRDHD;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
/* empty line ? (=> end of header) */
|
||||||
|
if ( n>0 && (*header)=='\0')
|
||||||
|
{ break;
|
||||||
|
}
|
||||||
|
length+=n;
|
||||||
|
/* try to parse some keywords : */
|
||||||
|
/* convert to lower case 'till a : is found or end of String */
|
||||||
|
for (pc=header; (*pc!=':' && *pc) ; pc++)
|
||||||
|
{ *pc=char(tolower(*pc));
|
||||||
|
}
|
||||||
|
// sscanf(header,"content-length: %d",&length);
|
||||||
|
if (typebuf)
|
||||||
|
{ sscanf(header,"content-type: %s",typebuf);
|
||||||
|
} }
|
||||||
|
if (length<=0)
|
||||||
|
{ close(fd);
|
||||||
|
ret = ERRNOLG;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
if(*plength<length)
|
||||||
|
{ length=*plength;
|
||||||
|
}
|
||||||
|
n=http_read_buffer(fd,pdata,length);
|
||||||
|
close(fd);
|
||||||
|
if (n<0)
|
||||||
|
{ ret=ERRRDDT;
|
||||||
|
}
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Request the header
|
||||||
|
*
|
||||||
|
* This function outputs the header of thehttp data server.
|
||||||
|
* The header is from the ressource named filename.
|
||||||
|
* The length and type of data is eventually returned (like for http_get(3))
|
||||||
|
*
|
||||||
|
* returns a negative error code or a positive code from the server
|
||||||
|
*
|
||||||
|
* limitations: filename is truncated to first 256 characters
|
||||||
|
*/
|
||||||
|
bool Http::http_head(int *plength,char *typebuf)
|
||||||
|
{
|
||||||
|
char header[MAXBUF];
|
||||||
|
char *pc;
|
||||||
|
int fd;
|
||||||
|
int n,length=-1;
|
||||||
|
|
||||||
|
if (plength) *plength=0;
|
||||||
|
if (typebuf) *typebuf='\0';
|
||||||
|
|
||||||
|
http_query("HEAD",filename.c_str(),"",KEEP_OPEN, NULL, 0, &fd);
|
||||||
|
if (ret==200) {
|
||||||
|
for(;;) {
|
||||||
|
n=http_read_line(fd,header,MAXBUF-1);
|
||||||
|
#ifdef VERBOSE
|
||||||
|
fputs(header,stderr);
|
||||||
|
putc('\n',stderr);
|
||||||
|
#endif
|
||||||
|
if (n<=0) {
|
||||||
|
close(fd);
|
||||||
|
ret = ERRRDHD;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
/* empty line ? (=> end of header) */
|
||||||
|
if ( n>0 && (*header)=='\0') break;
|
||||||
|
/* try to parse some keywords : */
|
||||||
|
/* convert to lower case 'till a : is found or end of String */
|
||||||
|
for (pc=header; (*pc!=':' && *pc) ; pc++) *pc=char(tolower(*pc));
|
||||||
|
sscanf(header,"content-length: %d",&length);
|
||||||
|
if (typebuf) sscanf(header,"content-type: %s",typebuf);
|
||||||
|
}
|
||||||
|
if (plength) *plength=length;
|
||||||
|
close(fd);
|
||||||
|
} else if (ret>=0) close(fd);
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete data on the server
|
||||||
|
*
|
||||||
|
* This function request a DELETE on the http data server.
|
||||||
|
*
|
||||||
|
* returns a negative error code or a positive code from the server
|
||||||
|
*
|
||||||
|
* limitations: filename is truncated to first 256 characters
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool Http::http_delete()
|
||||||
|
{ return http_query("DELETE",filename.c_str(),"",CLOSE, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parses an url : setting the http_server and http_port global variables
|
||||||
|
* and returning the filename to pass to http_get/put/...
|
||||||
|
* returns a negative error code or 0 if sucessfully parsed.
|
||||||
|
*/
|
||||||
|
bool Http::http_parse_url(const char *url)
|
||||||
|
{ if (strncasecmp("http://",url,7))
|
||||||
|
{
|
||||||
|
#ifdef VERBOSE
|
||||||
|
fprintf(stderr,"invalid url (must start with 'http://')\n");
|
||||||
|
#endif
|
||||||
|
ret = ERRURLH;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
// http://server:port/
|
||||||
|
url+=7;
|
||||||
|
http_server.erase();
|
||||||
|
filename.erase();
|
||||||
|
http_port=80;
|
||||||
|
const char* domain=url;
|
||||||
|
char* endOf=const_cast<char*>(strchr(domain,':'));
|
||||||
|
if(endOf)
|
||||||
|
{ http_server=String(domain,endOf-domain);
|
||||||
|
endOf++;
|
||||||
|
if (sscanf(endOf,"%d",&http_port)!=1)
|
||||||
|
{
|
||||||
|
#ifdef VERBOSE
|
||||||
|
fprintf(stderr,"invalid port in url\n");
|
||||||
|
#endif
|
||||||
|
ret = ERRURLP;
|
||||||
|
return IsGood();
|
||||||
|
} }
|
||||||
|
endOf= const_cast<char*>(strchr(domain,'/'));
|
||||||
|
if(!http_server.size())
|
||||||
|
{ if(endOf)
|
||||||
|
{ http_server=String(domain,endOf-domain);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ http_server=String(domain);
|
||||||
|
ret = OK0;
|
||||||
|
return IsGood();
|
||||||
|
} }
|
||||||
|
filename=String(endOf);
|
||||||
|
#ifdef VERBOSE
|
||||||
|
fprintf(stderr,"host=%s, port=%d, filename=%s\n",
|
||||||
|
http_server.c_str(),http_port,filename.c_str());
|
||||||
|
#endif
|
||||||
|
ret = OK0;
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Http::read(int s,char*buf,int len)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
int size=recv(s,buf,len,0);
|
||||||
|
#if 0
|
||||||
|
if(size==SOCKET_ERROR)
|
||||||
|
{ const int err=WSAGetLastError();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(size==16384)
|
||||||
|
{ size+=recv(s,buf+16384,len,0);
|
||||||
|
}
|
||||||
|
// cout<<"Read bytes: "<<size<<endl;
|
||||||
|
#else
|
||||||
|
const int size=::read(s,buf,len);
|
||||||
|
#endif
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Http::write(int s,const char*buf,int len)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
return send(s,buf,len,0);
|
||||||
|
#else
|
||||||
|
return ::write(s,buf,len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Http::close(int s)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
closesocket(s);
|
||||||
|
#else
|
||||||
|
::close(s);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
int Http::GetSystemError()
|
||||||
|
{ return WSAGetLastError();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int Http::GetSystemError()
|
||||||
|
{ return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
93
auxil/bifcl/auxil/libunistd/portable/http/Http.h
Normal file
93
auxil/bifcl/auxil/libunistd/portable/http/Http.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Http.h
|
||||||
|
// 2013/11/20
|
||||||
|
|
||||||
|
#ifndef Http_h
|
||||||
|
#define Http_h
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class Http
|
||||||
|
{ typedef std::string String;
|
||||||
|
enum http_retcode
|
||||||
|
{ /* Client side errors */
|
||||||
|
ERRHOST=-1, /* No such host */
|
||||||
|
ERRSOCK=-2, /* Can't create socket */
|
||||||
|
ERRCONN=-3, /* Can't connect to host */
|
||||||
|
ERRWRHD=-4, /* Write error on socket while writing header */
|
||||||
|
ERRWRDT=-5, /* Write error on socket while writing data */
|
||||||
|
ERRRDHD=-6, /* Read error on socket while reading result */
|
||||||
|
ERRPAHD=-7, /* Invalid answer from data server */
|
||||||
|
ERRNULL=-8, /* Null data pointer */
|
||||||
|
ERRNOLG=-9, /* No/Bad length in header */
|
||||||
|
ERRMEM=-10, /* Can't allocate memory */
|
||||||
|
ERRRDDT=-11,/* Read error while reading data */
|
||||||
|
ERRURLH=-12,/* Invalid url - must start with 'http://' */
|
||||||
|
ERRURLP=-13,/* Invalid port in url */
|
||||||
|
/* Return code by the server */
|
||||||
|
ERR400=400, /* Invalid query */
|
||||||
|
ERR403=403, /* Forbidden */
|
||||||
|
ERR408=408, /* Request timeout */
|
||||||
|
ERR500=500, /* Server error */
|
||||||
|
ERR501=501, /* Not implemented */
|
||||||
|
ERR503=503, /* Service overloaded */
|
||||||
|
/* Succesful results */
|
||||||
|
OK0 = 0, /* successfull parse */
|
||||||
|
OK201=201, /* Ressource succesfully created */
|
||||||
|
OK200=200 /* Ressource succesfully read */
|
||||||
|
};
|
||||||
|
enum querymode
|
||||||
|
{ CLOSE, /* Close the socket after the query (for put) */
|
||||||
|
KEEP_OPEN /* Keep it open */
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
String http_server;
|
||||||
|
int http_port;
|
||||||
|
String http_proxy_server;
|
||||||
|
int http_proxy_port;
|
||||||
|
String filename;
|
||||||
|
const char* http_user_agent;
|
||||||
|
http_retcode ret;
|
||||||
|
private:
|
||||||
|
bool IsGood() const
|
||||||
|
{ return ret>=0;
|
||||||
|
}
|
||||||
|
int http_read_line (int fd,char *buffer, int max);
|
||||||
|
int http_read_buffer (int fd,char *buffer, int max);
|
||||||
|
bool http_put(char *data, int length, int overwrite, char *type) ;
|
||||||
|
bool http_get(char *data,int *plength, char *typebuf);
|
||||||
|
bool http_parse_url(const char *url);
|
||||||
|
bool http_delete();
|
||||||
|
bool http_head(int *plength, char *typebuf);
|
||||||
|
bool http_query(const char *command, const char *url,const char *additional_header, querymode mode, char* data, int length, int *pfd);
|
||||||
|
int read(int s,char*buf,int len);
|
||||||
|
int write(int s,const char*buf,int len);
|
||||||
|
void close(int s);
|
||||||
|
int GetSystemError();
|
||||||
|
public:
|
||||||
|
Http(const char* http_user_agent=0)
|
||||||
|
: http_port(0),
|
||||||
|
http_proxy_port(0),
|
||||||
|
http_user_agent(http_user_agent),
|
||||||
|
ret(OK0)
|
||||||
|
{ if(!http_user_agent)
|
||||||
|
{ http_user_agent="Http lib/1.0";
|
||||||
|
} }
|
||||||
|
int Get(const String& url,char* data,int length)
|
||||||
|
{ const bool ok=http_parse_url(url.c_str());
|
||||||
|
if(!ok)
|
||||||
|
{ return -1;
|
||||||
|
}
|
||||||
|
char typebuf[70];
|
||||||
|
if(!http_get(data,&length,typebuf))
|
||||||
|
{ return -1;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
56
auxil/bifcl/auxil/libunistd/portable/http/HttpDecoder.h
Normal file
56
auxil/bifcl/auxil/libunistd/portable/http/HttpDecoder.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// HttpDecoder.h
|
||||||
|
// Copyright Robin.Rowe@Cinepaint.org 2015/6/14
|
||||||
|
// License MIT Open Source
|
||||||
|
//
|
||||||
|
#ifndef HttpDecoder_h
|
||||||
|
#define HttpDecoder_h
|
||||||
|
|
||||||
|
#ifdef ENABLE_FASTCGI
|
||||||
|
#include "fcgi_stdio.h"
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
//#include <stdbool.h>
|
||||||
|
#include <qdecoder/src/qdecoder.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_FASTCGI
|
||||||
|
# define FASTCGI_START while(FCGI_Accept() >= 0) {
|
||||||
|
# define FASTCGI_STOP }
|
||||||
|
#else
|
||||||
|
# define FASTCGI_START
|
||||||
|
# define FASTCGI_STOP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class HttpDecoder
|
||||||
|
{ qentry_t* req;
|
||||||
|
public:
|
||||||
|
~HttpDecoder()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
HttpDecoder()
|
||||||
|
{ req = 0;
|
||||||
|
}
|
||||||
|
void Close()
|
||||||
|
{ if(!req)
|
||||||
|
{ return;
|
||||||
|
}
|
||||||
|
req->free(req);
|
||||||
|
req=0;
|
||||||
|
}
|
||||||
|
void Open()
|
||||||
|
{ req = qcgireq_parse(NULL,Q_CGI_ALL);
|
||||||
|
}
|
||||||
|
const char* GetValue(const char* key) const
|
||||||
|
{ const char* value=(const char *)req->getstr(req,key,false);
|
||||||
|
return value ? value:"";
|
||||||
|
}
|
||||||
|
const char* operator[](const char* key) const
|
||||||
|
{ return GetValue(key);
|
||||||
|
}
|
||||||
|
void SetContentType(const char* contentType)
|
||||||
|
{ qcgires_setcontenttype(req, contentType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
63
auxil/bifcl/auxil/libunistd/portable/ipc/BsdMulticast.h
Normal file
63
auxil/bifcl/auxil/libunistd/portable/ipc/BsdMulticast.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// portable/BsdMulticast.h
|
||||||
|
// Created by Robin Rowe on 11/27/2015
|
||||||
|
// Copyright (c) 2015 Robin.Rowe@CinePaint.org
|
||||||
|
// License open source MIT
|
||||||
|
|
||||||
|
#ifndef BsdMulticast_h
|
||||||
|
#define BsdMulticast_h
|
||||||
|
|
||||||
|
#include "../pump/TimerPump.h"
|
||||||
|
#include "Packet.h"
|
||||||
|
#include "BsdSocketPool.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class BsdMulticast
|
||||||
|
: public TimerPump
|
||||||
|
{ Packet* headerPacket;
|
||||||
|
Packet* framePacket;
|
||||||
|
BsdSocketPool& socketPool;
|
||||||
|
protected:
|
||||||
|
#if 1
|
||||||
|
virtual void Action() override
|
||||||
|
{ if(framePacket)
|
||||||
|
{ socketPool.DirectMulticast(framePacket);
|
||||||
|
}
|
||||||
|
// puts("Unexpected call to pool Action");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
BsdMulticast(BsdSocketPool& socketPool)
|
||||||
|
: TimerPump("BsdMultiPump")
|
||||||
|
, headerPacket(nullptr)
|
||||||
|
, framePacket(nullptr)
|
||||||
|
, socketPool(socketPool)
|
||||||
|
{ TimerPump::Start();
|
||||||
|
}
|
||||||
|
~BsdMulticast()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
void Close()
|
||||||
|
{ socketPool.Close();
|
||||||
|
}
|
||||||
|
void SetIsStreaming(bool isStreaming = true)
|
||||||
|
{ socketPool.SetIsStreaming(isStreaming);
|
||||||
|
}
|
||||||
|
void SetHeaderPacket(Packet* packet)
|
||||||
|
{ headerPacket=packet;
|
||||||
|
}
|
||||||
|
void SetFramePacket(Packet* packet)
|
||||||
|
{ framePacket=packet;
|
||||||
|
}
|
||||||
|
void AddSkipped(unsigned skipped)
|
||||||
|
{ socketPool.stats.AddSkipped(skipped);
|
||||||
|
}
|
||||||
|
void PrintStats()
|
||||||
|
{ socketPool.stats.Print();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
64
auxil/bifcl/auxil/libunistd/portable/ipc/BsdPacketServer.cpp
Normal file
64
auxil/bifcl/auxil/libunistd/portable/ipc/BsdPacketServer.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// portable/BsdPacketServer.cpp
|
||||||
|
// Created by Robin Rowe on 2016/06/24
|
||||||
|
// License MIT Open Source
|
||||||
|
|
||||||
|
#include "BsdPacketServer.h"
|
||||||
|
#include "../Logger.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
bool BsdPacketServer::Start(int serverPort,unsigned maxStreams)
|
||||||
|
{ const bool isReceive=false;
|
||||||
|
if(!Open(serverPort,maxStreams,isReceive))
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
const bool isBlocking=true;
|
||||||
|
isVerbose = false;//true; //bug - should pass in as param
|
||||||
|
BsdSocketServer::Start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BsdPacketServer::LogSocketError(const PacketSocket& bsdSocket)
|
||||||
|
{ std::string msg;
|
||||||
|
bsdSocket.GetPeerName(msg);
|
||||||
|
msg+=" SendTo error: ";
|
||||||
|
msg+=bsdSocket.errorMsg;
|
||||||
|
error_msg(msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
bool BsdPacketServer::Login(SOCKET* slot,SOCKET fd)
|
||||||
|
{ if(!slot)
|
||||||
|
{ puts("No slot");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(unsigned i=0;i<pool.socketfd.size();i++)
|
||||||
|
{ if(IsInvalid(pool.socketfd[i]))
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if(!isStreaming)
|
||||||
|
{ if(!SendHeaderPacket(fd))
|
||||||
|
{ return false;
|
||||||
|
}
|
||||||
|
pool.isHeaderSent[i] = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
pool.socketfd[i] = fd;
|
||||||
|
pool.counter++;
|
||||||
|
#if 0
|
||||||
|
std::string msg;
|
||||||
|
BsdSocket bsdSocket(fd);
|
||||||
|
bsdSocket.GetPeerName(msg);
|
||||||
|
msg+=" Connected";
|
||||||
|
LogMsg(msg);
|
||||||
|
#endif
|
||||||
|
return SendHeaderPacket(fd);
|
||||||
|
} }
|
||||||
|
LogMsg("Can't subscribe");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
115
auxil/bifcl/auxil/libunistd/portable/ipc/BsdPacketServer.h
Normal file
115
auxil/bifcl/auxil/libunistd/portable/ipc/BsdPacketServer.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// portable/BsdPacketServer.h
|
||||||
|
// Created by Robin Rowe on 2016/06/24
|
||||||
|
// License MIT Open Source
|
||||||
|
|
||||||
|
#ifndef PacketServer_h
|
||||||
|
#define PacketServer_h
|
||||||
|
|
||||||
|
#include "Packet.h"
|
||||||
|
#include "BsdSocketServer.h"
|
||||||
|
#include "BsdMulticast.h"
|
||||||
|
#include "PacketQueue.h"
|
||||||
|
|
||||||
|
namespace portable
|
||||||
|
{
|
||||||
|
|
||||||
|
class BsdPacketServer
|
||||||
|
: public BsdSocketServer
|
||||||
|
{ bool isVerbose;
|
||||||
|
const char* programVersion;
|
||||||
|
std::vector<char> headerBuffer;
|
||||||
|
bool SendTo(PacketWriter& packet,SOCKET fd)
|
||||||
|
{ PacketSocket bsdSocket(fd);
|
||||||
|
if(bsdSocket.SendTo(packet))
|
||||||
|
{ return true;
|
||||||
|
}
|
||||||
|
LogSocketError(bsdSocket);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool IsInvalid(SOCKET fd)
|
||||||
|
{ return fd<=0;
|
||||||
|
}
|
||||||
|
void LogSocketError(const PacketSocket& bsdSocket);
|
||||||
|
bool Login(SOCKET fd) override
|
||||||
|
{ return SendHeaderPacket(fd);
|
||||||
|
}
|
||||||
|
bool Subscribe(SOCKET fd);
|
||||||
|
BsdMulticast multicast;
|
||||||
|
// bool isStreaming;
|
||||||
|
static const unsigned bufSize = 64*1024;
|
||||||
|
public:
|
||||||
|
PacketWriter headerPacket;
|
||||||
|
PacketQueue<bufSize> framePacket;
|
||||||
|
BsdPacketServer(const char* programVersion)
|
||||||
|
: BsdSocketServer(bufSize)
|
||||||
|
, isVerbose(false)
|
||||||
|
, programVersion(programVersion)
|
||||||
|
, headerBuffer(bufSize)
|
||||||
|
, headerPacket(&headerBuffer[0],bufSize)
|
||||||
|
, multicast(pool)
|
||||||
|
// , isStreaming(false)
|
||||||
|
{}
|
||||||
|
~BsdPacketServer()
|
||||||
|
{ Close();
|
||||||
|
}
|
||||||
|
void Close() override
|
||||||
|
{ BsdSocketServer::Close();
|
||||||
|
multicast.Close();
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
void MulticastHeaderPacket()
|
||||||
|
{ multicast.SetHeaderPacket(&headerPacket);
|
||||||
|
MulticastFramePacket();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
void MulticastFramePacket()
|
||||||
|
{ if(pool.IsEmpty())
|
||||||
|
{ //puts("pool empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
multicast.SetFramePacket(&framePacket.GetBaked());
|
||||||
|
multicast.Wake();
|
||||||
|
}
|
||||||
|
bool SendFramePacket(SOCKET fd)
|
||||||
|
{ if(framePacket.GetBaked().GetPacketSize()<=4)
|
||||||
|
{ puts("Packet not ready");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const unsigned packetId = framePacket.GetBaked().GetPacketId();
|
||||||
|
if(!packetId)
|
||||||
|
{ puts("Frame packet has invalid packetID, not sent");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
printf("Send Frame #%d size=%u\n",packetId, framePacket.GetBaked().header.packetSize);
|
||||||
|
return SendTo(framePacket.GetBaked(),fd);
|
||||||
|
}
|
||||||
|
bool SendHeaderPacket(SOCKET fd)
|
||||||
|
{ if(headerPacket.GetPacketSize()<=sizeof(unsigned))
|
||||||
|
{ puts("Packet not ready");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!SendTo(headerPacket,fd))
|
||||||
|
{ puts("Paket send failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string ip;
|
||||||
|
PacketSocket::GetPeerName(fd,ip);
|
||||||
|
printf("Send header packet to %s size=%u\n",ip.c_str(), headerPacket.header.packetSize);
|
||||||
|
return SendFramePacket(fd);
|
||||||
|
}
|
||||||
|
void SetIsStreaming(bool isStreaming = true)
|
||||||
|
{ multicast.SetIsStreaming(isStreaming);
|
||||||
|
}
|
||||||
|
void AddSkipped(unsigned skipped)
|
||||||
|
{ multicast.AddSkipped(skipped);
|
||||||
|
}
|
||||||
|
void PrintStats()
|
||||||
|
{ multicast.PrintStats();
|
||||||
|
}
|
||||||
|
bool Start(int serverPort,unsigned maxStreams);
|
||||||
|
//virtual void OnStop() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user