Add mechanisms to reformant and check code style (#128)

Use an internal version of astyle (astyle 3.0). Scripts taken from QGIS.
astyle.options from https://github.com/uclouvain/openjpeg/issues/128

scripts/prepare-commit.sh can be used locally to automatically reformat
edited files.

Travis-CI will run scripts/verify-indentation.sh to verify committed files.
This commit is contained in:
Even Rouault 2017-05-09 15:28:09 +02:00
parent 8650b70e06
commit d4e54e9f35
26 changed files with 20242 additions and 21 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ cmake_install.cmake
/src/bin/common/opj_apps_config.h
/src/lib/openjp2/opj_config.h
/src/lib/openjp2/opj_config_private.h
scripts/opjstyle*
# Ignore directories made by `make`.
/bin/

View File

@ -1,4 +1,4 @@
language: c
language: cpp
matrix:
include:
@ -6,20 +6,32 @@ matrix:
compiler: clang
env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_CI_INCLUDE_IF_DEPLOY=1
- os: linux
compiler: gcc
compiler: clang-3.8
env: OPJ_CI_CC=clang-3.8 OPJ_CI_CXX=clang-3.8 OPJ_CI_CHECK_STYLE=1 OPJ_CI_SKIP_TESTS=1
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages:
- clang-3.8
- flip
- os: linux
compiler: g++
env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_CI_INCLUDE_IF_DEPLOY=1 OPJ_CI_PERF_TESTS=1
- os: linux
compiler: gcc
compiler: g++
env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_NUM_THREADS=2
- os: linux
compiler: gcc
compiler: g++
env: OPJ_CI_ARCH=i386 OPJ_CI_BUILD_CONFIGURATION=Release
addons:
apt:
packages:
- gcc-multilib
- g++-multilib
- os: linux
compiler: gcc
compiler: g++
env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Debug OPJ_CI_PROFILE=1
addons:
apt:
@ -30,7 +42,7 @@ matrix:
env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Debug OPJ_CI_ASAN=1
- os: linux
compiler: clang-3.8
env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_CI_PERF_TESTS=1
env: OPJ_CI_CC=clang-3.8 OPJ_CI_CXX=clang-3.8 OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release OPJ_CI_PERF_TESTS=1
addons:
apt:
sources:
@ -39,18 +51,8 @@ matrix:
packages:
- clang-3.8
- os: linux
compiler: x86_64-w64-mingw32-gcc
env: OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-x86-64
- gcc-mingw-w64-x86-64
- gcc-mingw-w64
- os: linux
compiler: x86_64-w64-mingw32-gcc
env: OPJ_CI_ARCH=i386 OPJ_CI_BUILD_CONFIGURATION=Release
compiler: x86_64-w64-mingw32-g++
env: OPJ_CI_CC=x86_64-w64-mingw32-gcc OPJ_CI_CXX=x86_64-w64-mingw32-g++ OPJ_CI_ARCH=i386 OPJ_CI_BUILD_CONFIGURATION=Release
addons:
apt:
packages:
@ -58,15 +60,30 @@ matrix:
- binutils-mingw-w64-i686
- gcc-mingw-w64-i686
- gcc-mingw-w64
- g++-mingw-w64-i686
- gcc-multilib
- g++-multilib
- os: linux
compiler: gcc-4.8
env: OPJ_CI_ABI_CHECK=1
compiler: x86_64-w64-mingw32-g++
env: OPJ_CI_CC=x86_64-w64-mingw32-gcc OPJ_CI_CXX=x86_64-w64-mingw32-g++ OPJ_CI_ARCH=x86_64 OPJ_CI_BUILD_CONFIGURATION=Release
addons:
apt:
packages:
- gcc-mingw-w64-base
- binutils-mingw-w64-x86-64
- gcc-mingw-w64-x86-64
- gcc-mingw-w64
- g++-mingw-w64-x86-64
- os: linux
compiler: g++-4.8
env: OPJ_CI_CC=gcc-4.8 OPJ_CI_CXX=g++-4.8 OPJ_CI_ABI_CHECK=1
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.8
- g++-4.8
- libelf-dev
- elfutils
- texinfo

View File

@ -24,7 +24,7 @@ endif()
#string(TOLOWER ${OPENJPEG_NAMESPACE} OPENJPEG_LIBRARY_NAME)
set(OPENJPEG_LIBRARY_NAME openjp2)
project(${OPENJPEG_NAMESPACE} C)
project(${OPENJPEG_NAMESPACE})
# Do full dependency headers.
include_regular_expression("^.*$")
@ -386,3 +386,6 @@ if(BUILD_PKGCONFIG_FILES)
endif()
#-----------------------------------------------------------------------------
# build our version of astyle
SET (WITH_ASTYLE FALSE CACHE BOOL "If you plan to contribute you should reindent with scripts/prepare-commit.sh (using 'our' astyle)")

View File

@ -31,6 +31,7 @@ Main available cmake flags:
* To build the shared libraries and links the executables against it: '-DBUILD\_SHARED\_LIBS:bool=on' (default: 'ON')
> Note: when using this option, static libraries are not built and executables are dynamically linked.
* To build the CODEC executables: '-DBUILD\_CODEC:bool=on' (default: 'ON')
* To build opjstyle (internal version of astyle) for OpenJPEG development: '-DWITH_ASTYLE=ON'
* [OBSOLETE] To build the MJ2 executables: '-DBUILD\_MJ2:bool=on' (default: 'OFF')
* [OBSOLETE] To build the JPWL executables and JPWL library: '-DBUILD\_JPWL:bool=on' (default: 'OFF')
* [OBSOLETE] To build the JPIP client (java compiler recommended) library and executables: '-DBUILD\_JPIP:bool=on' (default: 'OFF')
@ -62,6 +63,11 @@ Note 4 : On MacOS, if it does not work, try adding the following flag to the cma
You can use cmake to generate the project files for the IDE you are using (VC2010, XCode, etc).
Type 'cmake --help' for available generators on your platform.
# Modifying OpenJPEG
Before committing changes, run:
scripts/prepare-commit.sh
# Using OpenJPEG
To use openjpeg exported cmake file, simply create your application doing:

View File

@ -49,6 +49,7 @@ The library is developed and maintained by the Image and Signal Processing Group
* doc: doxygen documentation setup file and man pages
* tests: configuration files and utilities for the openjpeg test suite. All test images are located in [openjpeg-data](https://github.com/uclouvain/openjpeg-data) repository.
* cmake: cmake related files
* scripts: scripts for developers
See [LICENSE][link-license] for license and copyright information.

11
scripts/astyle.options Normal file
View File

@ -0,0 +1,11 @@
--convert-tabs
--lineend=linux
--indent=spaces=4
--style=kr
--add-brackets
--max-code-length=80
--break-after-logical
--pad-header
--pad-oper
--unpad-paren
--suffix=none

117
scripts/astyle.sh Executable file
View File

@ -0,0 +1,117 @@
#!/bin/bash
###########################################################################
# astyle.sh
# ---------------------
# Date : August 2008
# Copyright : (C) 2008 by Juergen E. Fischer
# Email : jef at norbit dot de
###########################################################################
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
###########################################################################
for ASTYLE in ${OPJSTYLE} $(dirname $0)/opjstyle $(dirname $0)/RelWithDebInfo/opjstyle
do
if type -p $ASTYLE >/dev/null; then
break
fi
ASTYLE=
done
if [ -z "$ASTYLE" ]; then
echo "opjstyle not found - please enable WITH_ASTYLE in cmake and build it" >&2
exit 1
fi
if type -p tput >/dev/null; then
elcr="$ASTYLEPROGRESS$(tput el)$(tput cr)"
else
elcr="$ASTYLEPROGRESS \r"
fi
if ! type -p flip >/dev/null; then
if type -p dos2unix >/dev/null; then
flip() {
dos2unix -k $2
}
else
echo "flip not found" >&2
flip() {
:
}
fi
fi
if ! type -p autopep8 >/dev/null; then
echo "autopep8 not found" >&2
autopep8() {
:
}
fi
ASTYLEOPTS=$(dirname $0)/astyle.options
if type -p cygpath >/dev/null; then
ASTYLEOPTS="$(cygpath -w $ASTYLEOPTS)"
fi
set -e
astyleit() {
$ASTYLE --options="$ASTYLEOPTS" "$1"
#modified=$1.unify_includes_modified
#cp "$1" "$modified"
#scripts/unify_includes.pl "$modified"
#scripts/doxygen_space.pl "$modified"
#diff "$1" "$modified" >/dev/null || mv "$modified" "$1"
#rm -f "$modified"
}
for f in "$@"; do
case "$f" in
thirdparty/*)
echo -ne "$f skipped $elcr"
continue
;;
*.cpp|*.h|*.c|*.h|*.cxx|*.hxx|*.c++|*.h++|*.cc|*.hh|*.C|*.H|*.hpp)
if [ -x "$f" ]; then
chmod a-x "$f"
fi
cmd=astyleit
;;
*.py)
#cmd="autopep8 --in-place --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701"
echo -ne "Formatting $f $elcr"
cmd="autopep8 --in-place --ignore=E261,E265,E402,E501"
;;
*)
echo -ne "$f skipped $elcr"
continue
;;
esac
if ! [ -f "$f" ]; then
echo "$f not found" >&2
continue
fi
if [[ -f $f && `head -c 3 $f` == $'\xef\xbb\xbf' ]]; then
mv $f $f.bom
tail -c +4 $f.bom > $f
echo "removed BOM from $f"
fi
modified=$f.flip_modified
cp "$f" "$modified"
flip -ub "$modified"
diff "$f" "$modified" >/dev/null || mv "$modified" "$f"
rm -f "$modified"
eval "$cmd '$f'"
done

112
scripts/prepare-commit.sh Executable file
View File

@ -0,0 +1,112 @@
#!/usr/bin/env bash
###########################################################################
# prepare-commit.sh
# ---------------------
# Date : August 2008
# Copyright : (C) 2008 by Juergen E. Fischer
# Email : jef at norbit dot de
###########################################################################
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
###########################################################################
TOPLEVEL=$(git rev-parse --show-toplevel)
PATH=$TOPLEVEL/scripts:$PATH
cd $TOPLEVEL
# GNU prefix command for mac os support (gsed, gsplit)
GP=
if [[ "$OSTYPE" =~ darwin* ]]; then
GP=g
fi
if ! type -p astyle.sh >/dev/null; then
echo astyle.sh not found
exit 1
fi
if ! type -p colordiff >/dev/null; then
colordiff()
{
cat "$@"
}
fi
if [ "$1" = "-c" ]; then
echo "Cleaning..."
remove_temporary_files.sh
fi
set -e
# determine changed files
MODIFIED=$(git status --porcelain| ${GP}sed -ne "s/^ *[MA] *//p" | sort -u)
#MODIFIED=$(find src -name "*.c")
if [ -z "$MODIFIED" ]; then
echo nothing was modified
exit 0
fi
# save original changes
REV=$(git log -n1 --pretty=%H)
git diff >sha-$REV.diff
ASTYLEDIFF=astyle.$REV.diff
>$ASTYLEDIFF
# reformat
i=0
N=$(echo $MODIFIED | wc -w)
for f in $MODIFIED; do
(( i++ )) || true
case "$f" in
thirdparty/*)
echo $f skipped
continue
;;
*.cpp|*.c|*.h|*.cxx|*.hxx|*.c++|*.h++|*.cc|*.hh|*.C|*.H|*.sip|*.py)
;;
*)
continue
;;
esac
m=$f.$REV.prepare
cp $f $m
ASTYLEPROGRESS=" [$i/$N]" astyle.sh $f
if diff -u $m $f >>$ASTYLEDIFF; then
# no difference found
rm $m
fi
done
if [ -s "$ASTYLEDIFF" ]; then
if tty -s; then
# review astyle changes
colordiff <$ASTYLEDIFF | less -r
else
echo "Files changed (see $ASTYLEDIFF)"
fi
exit 1
else
rm $ASTYLEDIFF
fi
# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached HEAD --
exit 0
# vim: set ts=8 noexpandtab :

View File

@ -0,0 +1,41 @@
#!/bin/bash
###########################################################################
# remove_git_confict_files.sh
# ---------------------
# Date : April 2012
# Copyright : (C) 2012 by Tim Sutton
# Email : tim at kartoza dot com
###########################################################################
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
###########################################################################
#
# A simple script to get rid of QGIS related temporary files left in
# your QGIS source folder by git
# Tim Sutton, May 2008
find . \
\( \
-name "*.orig" \
-o -name "*.prepare" \
-o -name "*.sortinc" \
-o -name "*.unify_includes_modified" \
-o -name "*.nocopyright" \
-o -name "astyle*.diff" \
-o -name "sha-*.diff" \
-o -name "*.astyle" \
-o -name "sha*.diff" \
-o -name "*.bom" \
-o -name "*.bak" \
-o -name "*.rej" \
-o -name "*.orig" \
-o -name "*.new" \
-o -name "*~" \
\) \
-print \
-delete

79
scripts/verify-indentation.sh Executable file
View File

@ -0,0 +1,79 @@
#!/bin/bash
cd $(git rev-parse --show-toplevel)
export PATH=$PATH:$PWD/scripts
if [ -z "$TRAVIS_COMMIT_RANGE" ]; then
echo "No commit range given"
exit 0
fi
if ! type -p astyle.sh >/dev/null; then
echo astyle.sh not found
exit 1
fi
set -e
ASTYLEDIFF=/tmp/astyle.diff
>$ASTYLEDIFF
if [[ ! -z $TRAVIS_PULL_REQUEST_BRANCH ]]; then
# if on a PR, just analyse the changed files
echo "TRAVIS PR BRANCH: $TRAVIS_PULL_REQUEST_BRANCH"
FILES=$(git diff --diff-filter=AM --name-only $(git merge-base HEAD master) | tr '\n' ' ' )
elif [[ ! -z $TRAVIS_COMMIT_RANGE ]]; then
echo "TRAVIS COMMIT RANGE: $TRAVIS_COMMIT_RANGE"
FILES=$(git diff --diff-filter=AM --name-only ${TRAVIS_COMMIT_RANGE/.../..} | tr '\n' ' ' )
fi
for f in $FILES; do
if ! [ -f "$f" ]; then
echo "$f was removed." >>/tmp/ctest-important.log
continue
fi
echo "Checking $f" >>/tmp/ctest-important.log
case "$f" in
thirdparty*)
echo "$f skipped"
continue
;;
*.cpp|*.c|*.h|*.cxx|*.hxx|*.c++|*.h++|*.cc|*.hh|*.C|*.H|*.sip|*.py)
;;
*)
continue
;;
esac
m="$f.prepare"
cp "$f" "$m"
astyle.sh "$f"
if diff -u "$m" "$f" >>$ASTYLEDIFF; then
rm "$m"
else
echo "File $f needs indentation"
fi
done
if [ -s "$ASTYLEDIFF" ]; then
echo
echo "Required indentation updates:"
cat "$ASTYLEDIFF"
cat <<EOF
Tips to prevent and resolve:
* Enable WITH_ASTYLE in your cmake configuration to format C++ code
* Install autopep8 (>= 1.2.1) to format python code
* Use "scripts/astyle.sh file" to fix the now badly indented files
* Consider using scripts/prepare-commit.sh as pre-commit hook to avoid this
in the future (ln -s scripts/prepare-commit.sh .git/hooks/pre-commit) or
run it manually before each commit.
EOF
exit 1
fi

View File

@ -116,3 +116,9 @@ else(BUILD_THIRDPARTY)
endif(LCMS_FOUND)
endif(LCMS2_FOUND)
endif(BUILD_THIRDPARTY)
#------------
IF (WITH_ASTYLE)
ADD_SUBDIRECTORY(astyle)
ENDIF(WITH_ASTYLE)

3659
thirdparty/astyle/ASBeautifier.cpp vendored Executable file

File diff suppressed because it is too large Load Diff

797
thirdparty/astyle/ASEnhancer.cpp vendored Executable file
View File

@ -0,0 +1,797 @@
// ASEnhancer.cpp
// Copyright (c) 2017 by Jim Pattee <jimp03@email.com>.
// This code is licensed under the MIT License.
// License.md describes the conditions under which this software may be distributed.
//-----------------------------------------------------------------------------
// headers
//-----------------------------------------------------------------------------
#include "astyle.h"
//-----------------------------------------------------------------------------
// astyle namespace
//-----------------------------------------------------------------------------
namespace astyle {
//
//-----------------------------------------------------------------------------
// ASEnhancer class
//-----------------------------------------------------------------------------
/**
* ASEnhancer constructor
*/
ASEnhancer::ASEnhancer()
{
}
/**
* Destructor of ASEnhancer
*/
ASEnhancer::~ASEnhancer()
{
}
/**
* initialize the ASEnhancer.
*
* init() is called each time an ASFormatter object is initialized.
*/
void ASEnhancer::init(int _fileType,
int _indentLength,
int _tabLength,
bool _useTabs,
bool _forceTab,
bool _namespaceIndent,
bool _caseIndent,
bool _preprocBlockIndent,
bool _preprocDefineIndent,
bool _emptyLineFill,
vector<const pair<const string, const string>* >* _indentableMacros)
{
// formatting variables from ASFormatter and ASBeautifier
ASBase::init(_fileType);
indentLength = _indentLength;
tabLength = _tabLength;
useTabs = _useTabs;
forceTab = _forceTab;
namespaceIndent = _namespaceIndent;
caseIndent = _caseIndent;
preprocBlockIndent = _preprocBlockIndent;
preprocDefineIndent = _preprocDefineIndent;
emptyLineFill = _emptyLineFill;
indentableMacros = _indentableMacros;
quoteChar = '\'';
// unindent variables
lineNumber = 0;
braceCount = 0;
isInComment = false;
isInQuote = false;
switchDepth = 0;
eventPreprocDepth = 0;
lookingForCaseBrace = false;
unindentNextLine = false;
shouldUnindentLine = false;
shouldUnindentComment = false;
// switch struct and vector
sw.switchBraceCount = 0;
sw.unindentDepth = 0;
sw.unindentCase = false;
switchStack.clear();
// other variables
nextLineIsEventIndent = false;
isInEventTable = false;
nextLineIsDeclareIndent = false;
isInDeclareSection = false;
}
/**
* additional formatting for line of source code.
* every line of source code in a source code file should be sent
* one after the other to this function.
* indents event tables
* unindents the case blocks
*
* @param line the original formatted line will be updated if necessary.
*/
void ASEnhancer::enhance(string& line, bool isInNamespace, bool isInPreprocessor, bool isInSQL)
{
shouldUnindentLine = true;
shouldUnindentComment = false;
lineNumber++;
// check for beginning of event table
if (nextLineIsEventIndent)
{
isInEventTable = true;
nextLineIsEventIndent = false;
}
// check for beginning of SQL declare section
if (nextLineIsDeclareIndent)
{
isInDeclareSection = true;
nextLineIsDeclareIndent = false;
}
if (line.length() == 0
&& !isInEventTable
&& !isInDeclareSection
&& !emptyLineFill)
return;
// test for unindent on attached braces
if (unindentNextLine)
{
sw.unindentDepth++;
sw.unindentCase = true;
unindentNextLine = false;
}
// parse characters in the current line
parseCurrentLine(line, isInPreprocessor, isInSQL);
// check for SQL indentable lines
if (isInDeclareSection)
{
size_t firstText = line.find_first_not_of(" \t");
if (firstText == string::npos || line[firstText] != '#')
indentLine(line, 1);
}
// check for event table indentable lines
if (isInEventTable
&& (eventPreprocDepth == 0
|| (namespaceIndent && isInNamespace)))
{
size_t firstText = line.find_first_not_of(" \t");
if (firstText == string::npos || line[firstText] != '#')
indentLine(line, 1);
}
if (shouldUnindentComment && sw.unindentDepth > 0)
unindentLine(line, sw.unindentDepth - 1);
else if (shouldUnindentLine && sw.unindentDepth > 0)
unindentLine(line, sw.unindentDepth);
}
/**
* convert a force-tab indent to spaces
*
* @param line a reference to the line that will be converted.
*/
void ASEnhancer::convertForceTabIndentToSpaces(string& line) const
{
// replace tab indents with spaces
for (size_t i = 0; i < line.length(); i++)
{
if (!isWhiteSpace(line[i]))
break;
if (line[i] == '\t')
{
line.erase(i, 1);
line.insert(i, tabLength, ' ');
i += tabLength - 1;
}
}
}
/**
* convert a space indent to force-tab
*
* @param line a reference to the line that will be converted.
*/
void ASEnhancer::convertSpaceIndentToForceTab(string& line) const
{
assert(tabLength > 0);
// replace leading spaces with tab indents
size_t newSpaceIndentLength = line.find_first_not_of(" \t");
size_t tabCount = newSpaceIndentLength / tabLength; // truncate extra spaces
line.replace(0U, tabCount * tabLength, tabCount, '\t');
}
/**
* find the colon following a 'case' statement
*
* @param line a reference to the line.
* @param caseIndex the line index of the case statement.
* @return the line index of the colon.
*/
size_t ASEnhancer::findCaseColon(const string& line, size_t caseIndex) const
{
size_t i = caseIndex;
bool isInQuote_ = false;
char quoteChar_ = ' ';
for (; i < line.length(); i++)
{
if (isInQuote_)
{
if (line[i] == '\\')
{
i++;
continue;
}
else if (line[i] == quoteChar_) // check ending quote
{
isInQuote_ = false;
quoteChar_ = ' ';
continue;
}
else
{
continue; // must close quote before continuing
}
}
if (line[i] == '"' // check opening quote
|| (line[i] == '\'' && !isDigitSeparator(line, i)))
{
isInQuote_ = true;
quoteChar_ = line[i];
continue;
}
if (line[i] == ':')
{
if ((i + 1 < line.length()) && (line[i + 1] == ':'))
i++; // bypass scope resolution operator
else
break; // found it
}
}
return i;
}
/**
* indent a line by a given number of tabsets
* by inserting leading whitespace to the line argument.
*
* @param line a reference to the line to indent.
* @param indent the number of tabsets to insert.
* @return the number of characters inserted.
*/
int ASEnhancer::indentLine(string& line, int indent) const
{
if (line.length() == 0
&& !emptyLineFill)
return 0;
size_t charsToInsert = 0;
if (forceTab && indentLength != tabLength)
{
// replace tab indents with spaces
convertForceTabIndentToSpaces(line);
// insert the space indents
charsToInsert = indent * indentLength;
line.insert(line.begin(), charsToInsert, ' ');
// replace leading spaces with tab indents
convertSpaceIndentToForceTab(line);
}
else if (useTabs)
{
charsToInsert = indent;
line.insert(line.begin(), charsToInsert, '\t');
}
else // spaces
{
charsToInsert = indent * indentLength;
line.insert(line.begin(), charsToInsert, ' ');
}
return charsToInsert;
}
/**
* check for SQL "BEGIN DECLARE SECTION".
* must compare case insensitive and allow any spacing between words.
*
* @param line a reference to the line to indent.
* @param index the current line index.
* @return true if a hit.
*/
bool ASEnhancer::isBeginDeclareSectionSQL(const string& line, size_t index) const
{
string word;
size_t hits = 0;
size_t i;
for (i = index; i < line.length(); i++)
{
i = line.find_first_not_of(" \t", i);
if (i == string::npos)
return false;
if (line[i] == ';')
break;
if (!isCharPotentialHeader(line, i))
continue;
word = getCurrentWord(line, i);
for (size_t j = 0; j < word.length(); j++)
word[j] = (char) toupper(word[j]);
if (word == "EXEC" || word == "SQL")
{
i += word.length() - 1;
continue;
}
if (word == "DECLARE" || word == "SECTION")
{
hits++;
i += word.length() - 1;
continue;
}
if (word == "BEGIN")
{
hits++;
i += word.length() - 1;
continue;
}
return false;
}
if (hits == 3)
return true;
return false;
}
/**
* check for SQL "END DECLARE SECTION".
* must compare case insensitive and allow any spacing between words.
*
* @param line a reference to the line to indent.
* @param index the current line index.
* @return true if a hit.
*/
bool ASEnhancer::isEndDeclareSectionSQL(const string& line, size_t index) const
{
string word;
size_t hits = 0;
size_t i;
for (i = index; i < line.length(); i++)
{
i = line.find_first_not_of(" \t", i);
if (i == string::npos)
return false;
if (line[i] == ';')
break;
if (!isCharPotentialHeader(line, i))
continue;
word = getCurrentWord(line, i);
for (size_t j = 0; j < word.length(); j++)
word[j] = (char) toupper(word[j]);
if (word == "EXEC" || word == "SQL")
{
i += word.length() - 1;
continue;
}
if (word == "DECLARE" || word == "SECTION")
{
hits++;
i += word.length() - 1;
continue;
}
if (word == "END")
{
hits++;
i += word.length() - 1;
continue;
}
return false;
}
if (hits == 3)
return true;
return false;
}
/**
* check if a one-line brace has been reached,
* i.e. if the currently reached '{' character is closed
* with a complimentary '}' elsewhere on the current line,
*.
* @return false = one-line brace has not been reached.
* true = one-line brace has been reached.
*/
bool ASEnhancer::isOneLineBlockReached(const string& line, int startChar) const
{
assert(line[startChar] == '{');
bool isInComment_ = false;
bool isInQuote_ = false;
int _braceCount = 1;
int lineLength = line.length();
char quoteChar_ = ' ';
char ch = ' ';
for (int i = startChar + 1; i < lineLength; ++i)
{
ch = line[i];
if (isInComment_)
{
if (line.compare(i, 2, "*/") == 0)
{
isInComment_ = false;
++i;
}
continue;
}
if (ch == '\\')
{
++i;
continue;
}
if (isInQuote_)
{
if (ch == quoteChar_)
isInQuote_ = false;
continue;
}
if (ch == '"'
|| (ch == '\'' && !isDigitSeparator(line, i)))
{
isInQuote_ = true;
quoteChar_ = ch;
continue;
}
if (line.compare(i, 2, "//") == 0)
break;
if (line.compare(i, 2, "/*") == 0)
{
isInComment_ = true;
++i;
continue;
}
if (ch == '{')
++_braceCount;
else if (ch == '}')
--_braceCount;
if (_braceCount == 0)
return true;
}
return false;
}
/**
* parse characters in the current line to determine if an indent
* or unindent is needed.
*/
void ASEnhancer::parseCurrentLine(string& line, bool isInPreprocessor, bool isInSQL)
{
bool isSpecialChar = false; // is a backslash escape character
for (size_t i = 0; i < line.length(); i++)
{
char ch = line[i];
// bypass whitespace
if (isWhiteSpace(ch))
continue;
// handle special characters (i.e. backslash+character such as \n, \t, ...)
if (isSpecialChar)
{
isSpecialChar = false;
continue;
}
if (!(isInComment) && line.compare(i, 2, "\\\\") == 0)
{
i++;
continue;
}
if (!(isInComment) && ch == '\\')
{
isSpecialChar = true;
continue;
}
// handle quotes (such as 'x' and "Hello Dolly")
if (!isInComment
&& (ch == '"'
|| (ch == '\'' && !isDigitSeparator(line, i))))
{
if (!isInQuote)
{
quoteChar = ch;
isInQuote = true;
}
else if (quoteChar == ch)
{
isInQuote = false;
continue;
}
}
if (isInQuote)
continue;
// handle comments
if (!(isInComment) && line.compare(i, 2, "//") == 0)
{
// check for windows line markers
if (line.compare(i + 2, 1, "\xf0") > 0)
lineNumber--;
// unindent if not in case braces
if (line.find_first_not_of(" \t") == i
&& sw.switchBraceCount == 1
&& sw.unindentCase)
shouldUnindentComment = true;
break; // finished with the line
}
else if (!(isInComment) && line.compare(i, 2, "/*") == 0)
{
// unindent if not in case braces
if (sw.switchBraceCount == 1 && sw.unindentCase)
shouldUnindentComment = true;
isInComment = true;
size_t commentEnd = line.find("*/", i);
if (commentEnd == string::npos)
i = line.length() - 1;
else
i = commentEnd - 1;
continue;
}
else if ((isInComment) && line.compare(i, 2, "*/") == 0)
{
// unindent if not in case braces
if (sw.switchBraceCount == 1 && sw.unindentCase)
shouldUnindentComment = true;
isInComment = false;
i++;
continue;
}
if (isInComment)
{
// unindent if not in case braces
if (sw.switchBraceCount == 1 && sw.unindentCase)
shouldUnindentComment = true;
size_t commentEnd = line.find("*/", i);
if (commentEnd == string::npos)
i = line.length() - 1;
else
i = commentEnd - 1;
continue;
}
// if we have reached this far then we are NOT in a comment or string of special characters
if (line[i] == '{')
braceCount++;
if (line[i] == '}')
braceCount--;
// check for preprocessor within an event table
if (isInEventTable && line[i] == '#' && preprocBlockIndent)
{
string preproc;
preproc = line.substr(i + 1);
if (preproc.substr(0, 2) == "if") // #if, #ifdef, #ifndef)
eventPreprocDepth += 1;
if (preproc.substr(0, 5) == "endif" && eventPreprocDepth > 0)
eventPreprocDepth -= 1;
}
bool isPotentialKeyword = isCharPotentialHeader(line, i);
// ---------------- wxWidgets and MFC macros ----------------------------------
if (isPotentialKeyword)
{
for (size_t j = 0; j < indentableMacros->size(); j++)
{
// 'first' is the beginning macro
if (findKeyword(line, i, indentableMacros->at(j)->first))
{
nextLineIsEventIndent = true;
break;
}
}
for (size_t j = 0; j < indentableMacros->size(); j++)
{
// 'second' is the ending macro
if (findKeyword(line, i, indentableMacros->at(j)->second))
{
isInEventTable = false;
eventPreprocDepth = 0;
break;
}
}
}
// ---------------- process SQL -----------------------------------------------
if (isInSQL)
{
if (isBeginDeclareSectionSQL(line, i))
nextLineIsDeclareIndent = true;
if (isEndDeclareSectionSQL(line, i))
isInDeclareSection = false;
break;
}
// ---------------- process switch statements ---------------------------------
if (isPotentialKeyword && findKeyword(line, i, ASResource::AS_SWITCH))
{
switchDepth++;
switchStack.emplace_back(sw); // save current variables
sw.switchBraceCount = 0;
sw.unindentCase = false; // don't clear case until end of switch
i += 5; // bypass switch statement
continue;
}
// just want unindented case statements from this point
if (caseIndent
|| switchDepth == 0
|| (isInPreprocessor && !preprocDefineIndent))
{
// bypass the entire word
if (isPotentialKeyword)
{
string name = getCurrentWord(line, i);
i += name.length() - 1;
}
continue;
}
i = processSwitchBlock(line, i);
} // end of for loop * end of for loop * end of for loop * end of for loop
}
/**
* process the character at the current index in a switch block.
*
* @param line a reference to the line to indent.
* @param index the current line index.
* @return the new line index.
*/
size_t ASEnhancer::processSwitchBlock(string& line, size_t index)
{
size_t i = index;
bool isPotentialKeyword = isCharPotentialHeader(line, i);
if (line[i] == '{')
{
sw.switchBraceCount++;
if (lookingForCaseBrace) // if 1st after case statement
{
sw.unindentCase = true; // unindenting this case
sw.unindentDepth++;
lookingForCaseBrace = false; // not looking now
}
return i;
}
lookingForCaseBrace = false; // no opening brace, don't indent
if (line[i] == '}')
{
sw.switchBraceCount--;
assert(sw.switchBraceCount <= braceCount);
if (sw.switchBraceCount == 0) // if end of switch statement
{
int lineUnindent = sw.unindentDepth;
if (line.find_first_not_of(" \t") == i
&& !switchStack.empty())
lineUnindent = switchStack[switchStack.size() - 1].unindentDepth;
if (shouldUnindentLine)
{
if (lineUnindent > 0)
i -= unindentLine(line, lineUnindent);
shouldUnindentLine = false;
}
switchDepth--;
sw = switchStack.back();
switchStack.pop_back();
}
return i;
}
if (isPotentialKeyword
&& (findKeyword(line, i, ASResource::AS_CASE)
|| findKeyword(line, i, ASResource::AS_DEFAULT)))
{
if (sw.unindentCase) // if unindented last case
{
sw.unindentCase = false; // stop unindenting previous case
sw.unindentDepth--;
}
i = findCaseColon(line, i);
i++;
for (; i < line.length(); i++) // bypass whitespace
{
if (!isWhiteSpace(line[i]))
break;
}
if (i < line.length())
{
if (line[i] == '{')
{
braceCount++;
sw.switchBraceCount++;
if (!isOneLineBlockReached(line, i))
unindentNextLine = true;
return i;
}
}
lookingForCaseBrace = true;
i--; // need to process this char
return i;
}
if (isPotentialKeyword)
{
string name = getCurrentWord(line, i); // bypass the entire name
i += name.length() - 1;
}
return i;
}
/**
* unindent a line by a given number of tabsets
* by erasing the leading whitespace from the line argument.
*
* @param line a reference to the line to unindent.
* @param unindent the number of tabsets to erase.
* @return the number of characters erased.
*/
int ASEnhancer::unindentLine(string& line, int unindent) const
{
size_t whitespace = line.find_first_not_of(" \t");
if (whitespace == string::npos) // if line is blank
whitespace = line.length(); // must remove padding, if any
if (whitespace == 0)
return 0;
size_t charsToErase = 0;
if (forceTab && indentLength != tabLength)
{
// replace tab indents with spaces
convertForceTabIndentToSpaces(line);
// remove the space indents
size_t spaceIndentLength = line.find_first_not_of(" \t");
charsToErase = unindent * indentLength;
if (charsToErase <= spaceIndentLength)
line.erase(0, charsToErase);
else
charsToErase = 0;
// replace leading spaces with tab indents
convertSpaceIndentToForceTab(line);
}
else if (useTabs)
{
charsToErase = unindent;
if (charsToErase <= whitespace)
line.erase(0, charsToErase);
else
charsToErase = 0;
}
else // spaces
{
charsToErase = unindent * indentLength;
if (charsToErase <= whitespace)
line.erase(0, charsToErase);
else
charsToErase = 0;
}
return charsToErase;
}
} // end namespace astyle

7714
thirdparty/astyle/ASFormatter.cpp vendored Executable file

File diff suppressed because it is too large Load Diff

1092
thirdparty/astyle/ASLocalizer.cpp vendored Executable file

File diff suppressed because it is too large Load Diff

159
thirdparty/astyle/ASLocalizer.h vendored Executable file
View File

@ -0,0 +1,159 @@
// ASLocalizer.h
// Copyright (c) 2017 by Jim Pattee <jimp03@email.com>.
// This code is licensed under the MIT License.
// License.md describes the conditions under which this software may be distributed.
#ifndef ASLOCALIZER_H
#define ASLOCALIZER_H
#include <string>
#include <vector>
namespace astyle {
using namespace std;
#ifndef ASTYLE_LIB
//-----------------------------------------------------------------------------
// ASLocalizer class for console build.
// This class encapsulates all language-dependent settings and is a
// generalization of the C locale concept.
//-----------------------------------------------------------------------------
class Translation;
class ASLocalizer
{
public: // functions
ASLocalizer();
virtual ~ASLocalizer();
string getLanguageID() const;
const Translation* getTranslationClass() const;
#ifdef _WIN32
void setLanguageFromLCID(size_t lcid);
#endif
void setLanguageFromName(const char* langID);
const char* settext(const char* textIn) const;
private: // functions
void setTranslationClass();
private: // variables
Translation* m_translation; // pointer to a polymorphic Translation class
string m_langID; // language identifier from the locale
string m_subLangID; // sub language identifier, if needed
string m_localeName; // name of the current locale (Linux only)
size_t m_lcid; // LCID of the user locale (Windows only)
};
//----------------------------------------------------------------------------
// Translation base class.
//----------------------------------------------------------------------------
class Translation
// This base class is inherited by the language translation classes.
// Polymorphism is used to call the correct language translator.
// This class contains the translation vector and settext translation method.
// The language vector is built by the language sub classes.
// NOTE: This class must have virtual methods for typeid() to work.
// typeid() is used by AStyleTestI18n_Localizer.cpp.
{
public:
Translation() {}
virtual ~Translation() {}
string convertToMultiByte(const wstring& wideStr) const;
size_t getTranslationVectorSize() const;
bool getWideTranslation(const string& stringIn, wstring& wideOut) const;
string& translate(const string& stringIn) const;
protected:
void addPair(const string& english, const wstring& translated);
// variables
vector<pair<string, wstring> > m_translation; // translation vector
private:
mutable string m_mbTranslation;
};
//----------------------------------------------------------------------------
// Translation classes
// One class for each language.
// These classes have only a constructor which builds the language vector.
//----------------------------------------------------------------------------
class Bulgarian : public Translation
{ public: Bulgarian(); };
class ChineseSimplified : public Translation
{ public: ChineseSimplified(); };
class ChineseTraditional : public Translation
{ public: ChineseTraditional(); };
class Dutch : public Translation
{ public: Dutch(); };
class English : public Translation
{ public: English(); };
class Estonian : public Translation
{ public: Estonian(); };
class Finnish : public Translation
{ public: Finnish(); };
class French : public Translation
{ public: French(); };
class German : public Translation
{ public: German(); };
class Greek : public Translation
{ public: Greek(); };
class Hindi : public Translation
{ public: Hindi(); };
class Hungarian : public Translation
{ public: Hungarian(); };
class Italian : public Translation
{ public: Italian(); };
class Japanese : public Translation
{ public: Japanese(); };
class Korean : public Translation
{ public: Korean(); };
class Norwegian : public Translation
{ public: Norwegian(); };
class Polish : public Translation
{ public: Polish(); };
class Portuguese : public Translation
{ public: Portuguese(); };
class Romanian : public Translation
{ public: Romanian(); };
class Russian : public Translation
{ public: Russian(); };
class Spanish : public Translation
{ public: Spanish(); };
class Swedish : public Translation
{ public: Swedish(); };
class Ukrainian : public Translation
{ public: Ukrainian(); };
#endif // ASTYLE_LIB
} // namespace astyle
#endif // ASLOCALIZER_H

833
thirdparty/astyle/ASResource.cpp vendored Executable file
View File

@ -0,0 +1,833 @@
// ASResource.cpp
// Copyright (c) 2017 by Jim Pattee <jimp03@email.com>.
// This code is licensed under the MIT License.
// License.md describes the conditions under which this software may be distributed.
//-----------------------------------------------------------------------------
// headers
//-----------------------------------------------------------------------------
#include "astyle.h"
#include <algorithm>
//-----------------------------------------------------------------------------
// astyle namespace
//-----------------------------------------------------------------------------
namespace astyle {
//
const string ASResource::_AS_EXCEPT = string("__except");
const string ASResource::_AS_FINALLY = string("__finally");
const string ASResource::_AS_TRY = string("__try");
const string ASResource::AS_ADD = string("add");
const string ASResource::AS_AUTO = string("auto");
const string ASResource::AS_AUTORELEASEPOOL = string("autoreleasepool");
const string ASResource::AS_CASE = string("case");
const string ASResource::AS_CATCH = string("catch");
const string ASResource::AS_CLASS = string("class");
const string ASResource::AS_CONST = string("const");
const string ASResource::AS_CONST_CAST = string("const_cast");
const string ASResource::AS_DEFAULT = string("default");
const string ASResource::AS_DELEGATE = string("delegate");
const string ASResource::AS_DELETE = string("delete");
const string ASResource::AS_DO = string("do");
const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast");
const string ASResource::AS_ELSE = string("else");
const string ASResource::AS_END = string("end");
const string ASResource::AS_ENUM = string("enum");
const string ASResource::AS_EXTERN = string("extern");
const string ASResource::AS_FINALLY = string("finally");
const string ASResource::AS_FIXED = string("fixed");
const string ASResource::AS_FOR = string("for");
const string ASResource::AS_FOREACH = string("foreach");
const string ASResource::AS_FOREVER = string("forever");
const string ASResource::AS_GET = string("get");
const string ASResource::AS_IF = string("if");
const string ASResource::AS_INTERFACE = string("interface");
const string ASResource::AS_INTERRUPT = string("interrupt");
const string ASResource::AS_LET = string("let");
const string ASResource::AS_LOCK = string("lock");
const string ASResource::AS_MODULE = string("module"); // CORBA IDL module definition
const string ASResource::AS_NAMESPACE = string("namespace");
const string ASResource::AS_NEW = string("new");
const string ASResource::AS_NOEXCEPT = string("noexcept");
const string ASResource::AS_NS_DURING = string("NS_DURING");
const string ASResource::AS_NS_HANDLER = string("NS_HANDLER");
const string ASResource::AS_OPERATOR = string("operator");
const string ASResource::AS_OVERRIDE = string("override");
const string ASResource::AS_PRIVATE = string("private");
const string ASResource::AS_PROTECTED = string("protected");
const string ASResource::AS_PUBLIC = string("public");
const string ASResource::AS_QFOREACH = string("Q_FOREACH");
const string ASResource::AS_QFOREVER = string("Q_FOREVER");
const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast");
const string ASResource::AS_REMOVE = string("remove");
const string ASResource::AS_SEALED = string("sealed");
const string ASResource::AS_SELECTOR = string("selector");
const string ASResource::AS_SET = string("set");
const string ASResource::AS_STATIC = string("static");
const string ASResource::AS_STATIC_CAST = string("static_cast");
const string ASResource::AS_STRUCT = string("struct");
const string ASResource::AS_SWITCH = string("switch");
const string ASResource::AS_SYNCHRONIZED = string("synchronized");
const string ASResource::AS_TEMPLATE = string("template");
const string ASResource::AS_THROW = string("throw");
const string ASResource::AS_THROWS = string("throws");
const string ASResource::AS_TRY = string("try");
const string ASResource::AS_UNCHECKED = string("unchecked");
const string ASResource::AS_UNION = string("union");
const string ASResource::AS_UNSAFE = string("unsafe");
const string ASResource::AS_USING = string("using");
const string ASResource::AS_VOLATILE = string("volatile");
const string ASResource::AS_WHERE = string("where");
const string ASResource::AS_WHILE = string("while");
const string ASResource::AS_ASM = string("asm");
const string ASResource::AS__ASM__ = string("__asm__");
const string ASResource::AS_MS_ASM = string("_asm");
const string ASResource::AS_MS__ASM = string("__asm");
const string ASResource::AS_BAR_DEFINE = string("#define");
const string ASResource::AS_BAR_INCLUDE = string("#include");
const string ASResource::AS_BAR_IF = string("#if");
const string ASResource::AS_BAR_EL = string("#el");
const string ASResource::AS_BAR_ENDIF = string("#endif");
const string ASResource::AS_OPEN_BRACE = string("{");
const string ASResource::AS_CLOSE_BRACE = string("}");
const string ASResource::AS_OPEN_LINE_COMMENT = string("//");
const string ASResource::AS_OPEN_COMMENT = string("/*");
const string ASResource::AS_CLOSE_COMMENT = string("*/");
const string ASResource::AS_ASSIGN = string("=");
const string ASResource::AS_PLUS_ASSIGN = string("+=");
const string ASResource::AS_MINUS_ASSIGN = string("-=");
const string ASResource::AS_MULT_ASSIGN = string("*=");
const string ASResource::AS_DIV_ASSIGN = string("/=");
const string ASResource::AS_MOD_ASSIGN = string("%=");
const string ASResource::AS_OR_ASSIGN = string("|=");
const string ASResource::AS_AND_ASSIGN = string("&=");
const string ASResource::AS_XOR_ASSIGN = string("^=");
const string ASResource::AS_GR_GR_ASSIGN = string(">>=");
const string ASResource::AS_LS_LS_ASSIGN = string("<<=");
const string ASResource::AS_GR_GR_GR_ASSIGN = string(">>>=");
const string ASResource::AS_LS_LS_LS_ASSIGN = string("<<<=");
const string ASResource::AS_GCC_MIN_ASSIGN = string("<?");
const string ASResource::AS_GCC_MAX_ASSIGN = string(">?");
const string ASResource::AS_RETURN = string("return");
const string ASResource::AS_CIN = string("cin");
const string ASResource::AS_COUT = string("cout");
const string ASResource::AS_CERR = string("cerr");
const string ASResource::AS_EQUAL = string("==");
const string ASResource::AS_PLUS_PLUS = string("++");
const string ASResource::AS_MINUS_MINUS = string("--");
const string ASResource::AS_NOT_EQUAL = string("!=");
const string ASResource::AS_GR_EQUAL = string(">=");
const string ASResource::AS_GR_GR = string(">>");
const string ASResource::AS_GR_GR_GR = string(">>>");
const string ASResource::AS_LS_EQUAL = string("<=");
const string ASResource::AS_LS_LS = string("<<");
const string ASResource::AS_LS_LS_LS = string("<<<");
const string ASResource::AS_QUESTION_QUESTION = string("??");
const string ASResource::AS_LAMBDA = string("=>"); // C# lambda expression arrow
const string ASResource::AS_ARROW = string("->");
const string ASResource::AS_AND = string("&&");
const string ASResource::AS_OR = string("||");
const string ASResource::AS_SCOPE_RESOLUTION = string("::");
const string ASResource::AS_PLUS = string("+");
const string ASResource::AS_MINUS = string("-");
const string ASResource::AS_MULT = string("*");
const string ASResource::AS_DIV = string("/");
const string ASResource::AS_MOD = string("%");
const string ASResource::AS_GR = string(">");
const string ASResource::AS_LS = string("<");
const string ASResource::AS_NOT = string("!");
const string ASResource::AS_BIT_OR = string("|");
const string ASResource::AS_BIT_AND = string("&");
const string ASResource::AS_BIT_NOT = string("~");
const string ASResource::AS_BIT_XOR = string("^");
const string ASResource::AS_QUESTION = string("?");
const string ASResource::AS_COLON = string(":");
const string ASResource::AS_COMMA = string(",");
const string ASResource::AS_SEMICOLON = string(";");
/**
* Sort comparison function.
* Compares the length of the value of pointers in the vectors.
* The LONGEST strings will be first in the vector.
*
* @param a and b, the string pointers to be compared.
*/
bool sortOnLength(const string* a, const string* b)
{
return (*a).length() > (*b).length();
}
/**
* Sort comparison function.
* Compares the value of pointers in the vectors.
*
* @param a and b, the string pointers to be compared.
*/
bool sortOnName(const string* a, const string* b)
{
return *a < *b;
}
/**
* Build the vector of assignment operators.
* Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
*
* @param assignmentOperators a reference to the vector to be built.
*/
void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOperators)
{
const size_t elements = 15;
static bool reserved = false;
if (!reserved)
{
assignmentOperators->reserve(elements);
reserved = true;
}
assignmentOperators->emplace_back(&AS_ASSIGN);
assignmentOperators->emplace_back(&AS_PLUS_ASSIGN);
assignmentOperators->emplace_back(&AS_MINUS_ASSIGN);
assignmentOperators->emplace_back(&AS_MULT_ASSIGN);
assignmentOperators->emplace_back(&AS_DIV_ASSIGN);
assignmentOperators->emplace_back(&AS_MOD_ASSIGN);
assignmentOperators->emplace_back(&AS_OR_ASSIGN);
assignmentOperators->emplace_back(&AS_AND_ASSIGN);
assignmentOperators->emplace_back(&AS_XOR_ASSIGN);
// Java
assignmentOperators->emplace_back(&AS_GR_GR_GR_ASSIGN);
assignmentOperators->emplace_back(&AS_GR_GR_ASSIGN);
assignmentOperators->emplace_back(&AS_LS_LS_ASSIGN);
// Unknown
assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN);
assert(assignmentOperators->size() < elements);
sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength);
}
/**
* Build the vector of C++ cast operators.
* Used by ONLY ASFormatter.cpp
*
* @param castOperators a reference to the vector to be built.
*/
void ASResource::buildCastOperators(vector<const string*>* castOperators)
{
const size_t elements = 5;
static bool reserved = false;
if (!reserved)
{
castOperators->reserve(elements);
reserved = true;
}
castOperators->emplace_back(&AS_CONST_CAST);
castOperators->emplace_back(&AS_DYNAMIC_CAST);
castOperators->emplace_back(&AS_REINTERPRET_CAST);
castOperators->emplace_back(&AS_STATIC_CAST);
assert(castOperators->size() < elements);
sort(castOperators->begin(), castOperators->end(), sortOnName);
}
/**
* Build the vector of header words.
* Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
*
* @param headers a reference to the vector to be built.
*/
void ASResource::buildHeaders(vector<const string*>* headers, int fileType, bool beautifier)
{
const size_t elements = 25;
static bool reserved = false;
if (!reserved)
{
headers->reserve(elements);
reserved = true;
}
headers->emplace_back(&AS_IF);
headers->emplace_back(&AS_ELSE);
headers->emplace_back(&AS_FOR);
headers->emplace_back(&AS_WHILE);
headers->emplace_back(&AS_DO);
headers->emplace_back(&AS_SWITCH);
headers->emplace_back(&AS_CASE);
headers->emplace_back(&AS_DEFAULT);
headers->emplace_back(&AS_TRY);
headers->emplace_back(&AS_CATCH);
headers->emplace_back(&AS_QFOREACH); // QT
headers->emplace_back(&AS_QFOREVER); // QT
headers->emplace_back(&AS_FOREACH); // QT & C#
headers->emplace_back(&AS_FOREVER); // Qt & Boost
if (fileType == C_TYPE)
{
headers->emplace_back(&_AS_TRY); // __try
headers->emplace_back(&_AS_FINALLY); // __finally
headers->emplace_back(&_AS_EXCEPT); // __except
}
if (fileType == JAVA_TYPE)
{
headers->emplace_back(&AS_FINALLY);
headers->emplace_back(&AS_SYNCHRONIZED);
}
if (fileType == SHARP_TYPE)
{
headers->emplace_back(&AS_FINALLY);
headers->emplace_back(&AS_LOCK);
headers->emplace_back(&AS_FIXED);
headers->emplace_back(&AS_GET);
headers->emplace_back(&AS_SET);
headers->emplace_back(&AS_ADD);
headers->emplace_back(&AS_REMOVE);
headers->emplace_back(&AS_USING);
}
if (beautifier)
{
if (fileType == C_TYPE)
{
headers->emplace_back(&AS_TEMPLATE);
}
if (fileType == JAVA_TYPE)
{
headers->emplace_back(&AS_STATIC); // for static constructor
}
}
assert(headers->size() < elements);
sort(headers->begin(), headers->end(), sortOnName);
}
/**
* Build the vector of indentable headers.
* Used by ONLY ASBeautifier.cpp
*
* @param indentableHeaders a reference to the vector to be built.
*/
void ASResource::buildIndentableHeaders(vector<const string*>* indentableHeaders)
{
indentableHeaders->emplace_back(&AS_RETURN);
// sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName);
}
/**
* Build the vector of indentable macros pairs.
* Initialized by ASFormatter, used by ONLY ASEnhancer.cpp
*
* @param indentableMacros a reference to the vector to be built.
*/
void ASResource::buildIndentableMacros(vector<const pair<const string, const string>* >* indentableMacros)
{
const size_t elements = 10;
static bool reserved = false;
if (!reserved)
{
indentableMacros->reserve(elements);
reserved = true;
}
// the pairs must be retained in memory because of pair pointers
typedef pair<const string, const string> macro_pair;
static const macro_pair macros[] =
{
// wxWidgets
macro_pair("BEGIN_EVENT_TABLE", "END_EVENT_TABLE"),
macro_pair("wxBEGIN_EVENT_TABLE", "wxEND_EVENT_TABLE"),
// MFC
macro_pair("BEGIN_DISPATCH_MAP", "END_DISPATCH_MAP"),
macro_pair("BEGIN_EVENT_MAP", "END_EVENT_MAP"),
macro_pair("BEGIN_MESSAGE_MAP", "END_MESSAGE_MAP"),
macro_pair("BEGIN_PROPPAGEIDS", "END_PROPPAGEIDS"),
};
size_t entries = sizeof(macros) / sizeof(macros[0]);
for (size_t i = 0; i < entries; i++)
indentableMacros->emplace_back(&macros[i]);
assert(indentableMacros->size() < elements);
}
/**
* Build the vector of non-assignment operators.
* Used by ONLY ASBeautifier.cpp
*
* @param nonAssignmentOperators a reference to the vector to be built.
*/
void ASResource::buildNonAssignmentOperators(vector<const string*>* nonAssignmentOperators)
{
const size_t elements = 15;
static bool reserved = false;
if (!reserved)
{
nonAssignmentOperators->reserve(elements);
reserved = true;
}
nonAssignmentOperators->emplace_back(&AS_EQUAL);
nonAssignmentOperators->emplace_back(&AS_PLUS_PLUS);
nonAssignmentOperators->emplace_back(&AS_MINUS_MINUS);
nonAssignmentOperators->emplace_back(&AS_NOT_EQUAL);
nonAssignmentOperators->emplace_back(&AS_GR_EQUAL);
nonAssignmentOperators->emplace_back(&AS_GR_GR_GR);
nonAssignmentOperators->emplace_back(&AS_GR_GR);
nonAssignmentOperators->emplace_back(&AS_LS_EQUAL);
nonAssignmentOperators->emplace_back(&AS_LS_LS_LS);
nonAssignmentOperators->emplace_back(&AS_LS_LS);
nonAssignmentOperators->emplace_back(&AS_ARROW);
nonAssignmentOperators->emplace_back(&AS_AND);
nonAssignmentOperators->emplace_back(&AS_OR);
nonAssignmentOperators->emplace_back(&AS_LAMBDA);
assert(nonAssignmentOperators->size() < elements);
sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength);
}
/**
* Build the vector of header non-paren headers.
* Used by BOTH ASFormatter.cpp and ASBeautifier.cpp.
* NOTE: Non-paren headers should also be included in the headers vector.
*
* @param nonParenHeaders a reference to the vector to be built.
*/
void ASResource::buildNonParenHeaders(vector<const string*>* nonParenHeaders, int fileType, bool beautifier)
{
const size_t elements = 20;
static bool reserved = false;
if (!reserved)
{
nonParenHeaders->reserve(elements);
reserved = true;
}
nonParenHeaders->emplace_back(&AS_ELSE);
nonParenHeaders->emplace_back(&AS_DO);
nonParenHeaders->emplace_back(&AS_TRY);
nonParenHeaders->emplace_back(&AS_CATCH); // can be paren or non-paren
nonParenHeaders->emplace_back(&AS_CASE); // can be paren or non-paren
nonParenHeaders->emplace_back(&AS_DEFAULT);
nonParenHeaders->emplace_back(&AS_QFOREVER); // QT
nonParenHeaders->emplace_back(&AS_FOREVER); // Boost
if (fileType == C_TYPE)
{
nonParenHeaders->emplace_back(&_AS_TRY); // __try
nonParenHeaders->emplace_back(&_AS_FINALLY); // __finally
}
if (fileType == JAVA_TYPE)
{
nonParenHeaders->emplace_back(&AS_FINALLY);
}
if (fileType == SHARP_TYPE)
{
nonParenHeaders->emplace_back(&AS_FINALLY);
nonParenHeaders->emplace_back(&AS_GET);
nonParenHeaders->emplace_back(&AS_SET);
nonParenHeaders->emplace_back(&AS_ADD);
nonParenHeaders->emplace_back(&AS_REMOVE);
}
if (beautifier)
{
if (fileType == C_TYPE)
{
nonParenHeaders->emplace_back(&AS_TEMPLATE);
}
if (fileType == JAVA_TYPE)
{
nonParenHeaders->emplace_back(&AS_STATIC);
}
}
assert(nonParenHeaders->size() < elements);
sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName);
}
/**
* Build the vector of operators.
* Used by ONLY ASFormatter.cpp
*
* @param operators a reference to the vector to be built.
*/
void ASResource::buildOperators(vector<const string*>* operators, int fileType)
{
const size_t elements = 50;
static bool reserved = false;
if (!reserved)
{
operators->reserve(elements);
reserved = true;
}
operators->emplace_back(&AS_PLUS_ASSIGN);
operators->emplace_back(&AS_MINUS_ASSIGN);
operators->emplace_back(&AS_MULT_ASSIGN);
operators->emplace_back(&AS_DIV_ASSIGN);
operators->emplace_back(&AS_MOD_ASSIGN);
operators->emplace_back(&AS_OR_ASSIGN);
operators->emplace_back(&AS_AND_ASSIGN);
operators->emplace_back(&AS_XOR_ASSIGN);
operators->emplace_back(&AS_EQUAL);
operators->emplace_back(&AS_PLUS_PLUS);
operators->emplace_back(&AS_MINUS_MINUS);
operators->emplace_back(&AS_NOT_EQUAL);
operators->emplace_back(&AS_GR_EQUAL);
operators->emplace_back(&AS_GR_GR_GR_ASSIGN);
operators->emplace_back(&AS_GR_GR_ASSIGN);
operators->emplace_back(&AS_GR_GR_GR);
operators->emplace_back(&AS_GR_GR);
operators->emplace_back(&AS_LS_EQUAL);
operators->emplace_back(&AS_LS_LS_LS_ASSIGN);
operators->emplace_back(&AS_LS_LS_ASSIGN);
operators->emplace_back(&AS_LS_LS_LS);
operators->emplace_back(&AS_LS_LS);
operators->emplace_back(&AS_QUESTION_QUESTION);
operators->emplace_back(&AS_LAMBDA);
operators->emplace_back(&AS_ARROW);
operators->emplace_back(&AS_AND);
operators->emplace_back(&AS_OR);
operators->emplace_back(&AS_SCOPE_RESOLUTION);
operators->emplace_back(&AS_PLUS);
operators->emplace_back(&AS_MINUS);
operators->emplace_back(&AS_MULT);
operators->emplace_back(&AS_DIV);
operators->emplace_back(&AS_MOD);
operators->emplace_back(&AS_QUESTION);
operators->emplace_back(&AS_COLON);
operators->emplace_back(&AS_ASSIGN);
operators->emplace_back(&AS_LS);
operators->emplace_back(&AS_GR);
operators->emplace_back(&AS_NOT);
operators->emplace_back(&AS_BIT_OR);
operators->emplace_back(&AS_BIT_AND);
operators->emplace_back(&AS_BIT_NOT);
operators->emplace_back(&AS_BIT_XOR);
if (fileType == C_TYPE)
{
operators->emplace_back(&AS_GCC_MIN_ASSIGN);
operators->emplace_back(&AS_GCC_MAX_ASSIGN);
}
assert(operators->size() < elements);
sort(operators->begin(), operators->end(), sortOnLength);
}
/**
* Build the vector of pre-block statements.
* Used by ONLY ASBeautifier.cpp
* NOTE: Cannot be both a header and a preBlockStatement.
*
* @param preBlockStatements a reference to the vector to be built.
*/
void ASResource::buildPreBlockStatements(vector<const string*>* preBlockStatements, int fileType)
{
const size_t elements = 10;
static bool reserved = false;
if (!reserved)
{
preBlockStatements->reserve(elements);
reserved = true;
}
preBlockStatements->emplace_back(&AS_CLASS);
if (fileType == C_TYPE)
{
preBlockStatements->emplace_back(&AS_STRUCT);
preBlockStatements->emplace_back(&AS_UNION);
preBlockStatements->emplace_back(&AS_NAMESPACE);
preBlockStatements->emplace_back(&AS_MODULE); // for CORBA IDL
preBlockStatements->emplace_back(&AS_INTERFACE); // for CORBA IDL
}
if (fileType == JAVA_TYPE)
{
preBlockStatements->emplace_back(&AS_INTERFACE);
preBlockStatements->emplace_back(&AS_THROWS);
}
if (fileType == SHARP_TYPE)
{
preBlockStatements->emplace_back(&AS_INTERFACE);
preBlockStatements->emplace_back(&AS_NAMESPACE);
preBlockStatements->emplace_back(&AS_WHERE);
preBlockStatements->emplace_back(&AS_STRUCT);
}
assert(preBlockStatements->size() < elements);
sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName);
}
/**
* Build the vector of pre-command headers.
* Used by BOTH ASFormatter.cpp and ASBeautifier.cpp.
* NOTE: Cannot be both a header and a preCommandHeader.
*
* A preCommandHeader is in a function definition between
* the closing paren and the opening brace.
* e.g. in "void foo() const {}", "const" is a preCommandHeader.
*/
void ASResource::buildPreCommandHeaders(vector<const string*>* preCommandHeaders, int fileType)
{
const size_t elements = 10;
static bool reserved = false;
if (!reserved)
{
preCommandHeaders->reserve(elements);
reserved = true;
}
if (fileType == C_TYPE)
{
preCommandHeaders->emplace_back(&AS_CONST);
preCommandHeaders->emplace_back(&AS_VOLATILE);
preCommandHeaders->emplace_back(&AS_INTERRUPT);
preCommandHeaders->emplace_back(&AS_NOEXCEPT);
preCommandHeaders->emplace_back(&AS_OVERRIDE);
preCommandHeaders->emplace_back(&AS_SEALED); // Visual C only
preCommandHeaders->emplace_back(&AS_AUTORELEASEPOOL); // Obj-C only
}
if (fileType == JAVA_TYPE)
{
preCommandHeaders->emplace_back(&AS_THROWS);
}
if (fileType == SHARP_TYPE)
{
preCommandHeaders->emplace_back(&AS_WHERE);
}
assert(preCommandHeaders->size() < elements);
sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName);
}
/**
* Build the vector of pre-definition headers.
* Used by ONLY ASFormatter.cpp
* NOTE: Do NOT add 'enum' here. It is an array type brace.
* NOTE: Do NOT add 'extern' here. Do not want an extra indent.
*
* @param preDefinitionHeaders a reference to the vector to be built.
*/
void ASResource::buildPreDefinitionHeaders(vector<const string*>* preDefinitionHeaders, int fileType)
{
const size_t elements = 10;
static bool reserved = false;
if (!reserved)
{
preDefinitionHeaders->reserve(elements);
reserved = true;
}
preDefinitionHeaders->emplace_back(&AS_CLASS);
if (fileType == C_TYPE)
{
preDefinitionHeaders->emplace_back(&AS_STRUCT);
preDefinitionHeaders->emplace_back(&AS_UNION);
preDefinitionHeaders->emplace_back(&AS_NAMESPACE);
preDefinitionHeaders->emplace_back(&AS_MODULE); // for CORBA IDL
preDefinitionHeaders->emplace_back(&AS_INTERFACE); // for CORBA IDL
}
if (fileType == JAVA_TYPE)
{
preDefinitionHeaders->emplace_back(&AS_INTERFACE);
}
if (fileType == SHARP_TYPE)
{
preDefinitionHeaders->emplace_back(&AS_STRUCT);
preDefinitionHeaders->emplace_back(&AS_INTERFACE);
preDefinitionHeaders->emplace_back(&AS_NAMESPACE);
}
assert(preDefinitionHeaders->size() < elements);
sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* ASBase Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// check if a specific line position contains a header.
const string* ASBase::findHeader(const string& line, int i,
const vector<const string*>* possibleHeaders) const
{
assert(isCharPotentialHeader(line, i));
// check the word
size_t maxHeaders = possibleHeaders->size();
for (size_t p = 0; p < maxHeaders; p++)
{
const string* header = (*possibleHeaders)[p];
const size_t wordEnd = i + header->length();
if (wordEnd > line.length())
continue;
int result = (line.compare(i, header->length(), *header));
if (result > 0)
continue;
if (result < 0)
break;
// check that this is not part of a longer word
if (wordEnd == line.length())
return header;
if (isLegalNameChar(line[wordEnd]))
continue;
const char peekChar = peekNextChar(line, wordEnd - 1);
// is not a header if part of a definition
if (peekChar == ',' || peekChar == ')')
break;
// the following accessor definitions are NOT headers
// goto default; is NOT a header
// default(int) keyword in C# is NOT a header
else if ((header == &AS_GET
|| header == &AS_SET
|| header == &AS_DEFAULT)
&& (peekChar == ';' || peekChar == '(' || peekChar == '='))
break;
return header;
}
return nullptr;
}
// check if a specific line position contains a keyword.
bool ASBase::findKeyword(const string& line, int i, const string& keyword) const
{
assert(isCharPotentialHeader(line, i));
// check the word
const size_t keywordLength = keyword.length();
const size_t wordEnd = i + keywordLength;
if (wordEnd > line.length())
return false;
if (line.compare(i, keywordLength, keyword) != 0)
return false;
// check that this is not part of a longer word
if (wordEnd == line.length())
return true;
if (isLegalNameChar(line[wordEnd]))
return false;
// is not a keyword if part of a definition
const char peekChar = peekNextChar(line, (int) wordEnd - 1);
if (peekChar == ',' || peekChar == ')')
return false;
return true;
}
// check if a specific line position contains an operator.
const string* ASBase::findOperator(const string& line, int i,
const vector<const string*>* possibleOperators) const
{
assert(isCharPotentialOperator(line[i]));
// find the operator in the vector
// the vector contains the LONGEST operators first
// must loop thru the entire vector
size_t maxOperators = possibleOperators->size();
for (size_t p = 0; p < maxOperators; p++)
{
const size_t wordEnd = i + (*(*possibleOperators)[p]).length();
if (wordEnd > line.length())
continue;
if (line.compare(i, (*(*possibleOperators)[p]).length(), *(*possibleOperators)[p]) == 0)
return (*possibleOperators)[p];
}
return nullptr;
}
// get the current word on a line
// index must point to the beginning of the word
string ASBase::getCurrentWord(const string& line, size_t index) const
{
assert(isCharPotentialHeader(line, index));
size_t lineLength = line.length();
size_t i;
for (i = index; i < lineLength; i++)
{
if (!isLegalNameChar(line[i]))
break;
}
return line.substr(index, i - index);
}
// check if a specific character can be used in a legal variable/method/class name
bool ASBase::isLegalNameChar(char ch) const
{
if (isWhiteSpace(ch))
return false;
if ((unsigned char) ch > 127)
return false;
return (isalnum((unsigned char) ch)
|| ch == '.' || ch == '_'
|| (isJavaStyle() && ch == '$')
|| (isSharpStyle() && ch == '@')); // may be used as a prefix
}
// check if a specific character can be part of a header
bool ASBase::isCharPotentialHeader(const string& line, size_t i) const
{
assert(!isWhiteSpace(line[i]));
char prevCh = ' ';
if (i > 0)
prevCh = line[i - 1];
if (!isLegalNameChar(prevCh) && isLegalNameChar(line[i]))
return true;
return false;
}
// check if a specific character can be part of an operator
bool ASBase::isCharPotentialOperator(char ch) const
{
assert(!isWhiteSpace(ch));
if ((unsigned) ch > 127)
return false;
return (ispunct((unsigned char) ch)
&& ch != '{' && ch != '}'
&& ch != '(' && ch != ')'
&& ch != '[' && ch != ']'
&& ch != ';' && ch != ','
&& ch != '#' && ch != '\\'
&& ch != '\'' && ch != '\"');
}
// check if a specific character is a digit
// NOTE: Visual C isdigit() gives assert error if char > 256
bool ASBase::isDigit(char ch) const
{
return (ch >= '0' && ch <= '9');
}
// check if a specific character is a digit separator
bool ASBase::isDigitSeparator(const string& line, int i) const
{
assert(line[i] == '\'');
// casting to (unsigned char) eliminates negative characters
// will get a "Debug Assertion Failed" if not cast
bool foundDigitSeparator = i > 0
&& isxdigit((unsigned char) line[i - 1])
&& i < (int) line.length() - 1
&& isxdigit((unsigned char) line[i + 1]);
return foundDigitSeparator;
}
// peek at the next unread character.
char ASBase::peekNextChar(const string& line, int i) const
{
char ch = ' ';
size_t peekNum = line.find_first_not_of(" \t", i + 1);
if (peekNum == string::npos)
return ch;
ch = line[peekNum];
return ch;
}
} // end namespace astyle

28
thirdparty/astyle/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,28 @@
SET(ASTYLE_SRCS
astyle_main.cpp
ASBeautifier.cpp
ASEnhancer.cpp
ASFormatter.cpp
ASLocalizer.cpp
ASResource.cpp
)
if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set (CMAKE_CXX_FLAGS "--std=c++11 ${CMAKE_CXX_FLAGS}")
endif ()
else ()
set (CMAKE_CXX_STANDARD 11)
endif ()
# No warnings for astyle build
IF(NOT MSVC)
SET_SOURCE_FILES_PROPERTIES(${ASTYLE_SRCS} PROPERTIES COMPILE_FLAGS -w)
ENDIF(NOT MSVC)
ADD_EXECUTABLE(opjstyle ${ASTYLE_SRCS})
SET_TARGET_PROPERTIES(opjstyle PROPERTIES LINKER_LANGUAGE CXX)
SET_TARGET_PROPERTIES(opjstyle PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/scripts)
IF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++")
ENDIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")

21
thirdparty/astyle/LICENSE.md vendored Executable file
View File

@ -0,0 +1,21 @@
### MIT License
Copyright (c) 2017 by Jim Pattee <jimp03@email.com>.
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.

1056
thirdparty/astyle/astyle.h vendored Executable file

File diff suppressed because it is too large Load Diff

3990
thirdparty/astyle/astyle_main.cpp vendored Executable file

File diff suppressed because it is too large Load Diff

443
thirdparty/astyle/astyle_main.h vendored Executable file
View File

@ -0,0 +1,443 @@
// astyle_main.h
// Copyright (c) 2017 by Jim Pattee <jimp03@email.com>.
// This code is licensed under the MIT License.
// License.md describes the conditions under which this software may be distributed.
#ifndef ASTYLE_MAIN_H
#define ASTYLE_MAIN_H
//----------------------------------------------------------------------------
// headers
//----------------------------------------------------------------------------
#include "astyle.h"
#include <sstream>
#include <ctime>
#if defined(__BORLANDC__) && __BORLANDC__ < 0x0650
// Embarcadero needs this for the following utime.h
// otherwise "struct utimbuf" gets an error on time_t
// 0x0650 for C++Builder XE3
using std::time_t;
#endif
#if defined(_MSC_VER)
#include <sys/utime.h>
#include <sys/stat.h>
#else
#include <utime.h>
#include <sys/stat.h>
#endif // end compiler checks
#ifdef ASTYLE_JNI
#include <jni.h>
#ifndef ASTYLE_LIB // ASTYLE_LIB must be defined for ASTYLE_JNI
#define ASTYLE_LIB
#endif
#endif // ASTYLE_JNI
#ifndef ASTYLE_LIB
// for console build only
#include "ASLocalizer.h"
#define _(a) localizer.settext(a)
#endif // ASTYLE_LIB
//-----------------------------------------------------------------------------
// declarations
//-----------------------------------------------------------------------------
// for G++ implementation of string.compare:
#if defined(__GNUC__) && __GNUC__ < 3
#error - Use GNU C compiler release 3 or higher
#endif
// for getenv and localtime
#if defined(_MSC_VER)
#pragma warning(disable: 4996) // secure version deprecation warnings
#endif
// for namespace problem in version 5.0
#if defined(_MSC_VER) && _MSC_VER < 1200 // check for V6.0
#error - Use Microsoft compiler version 6 or higher
#endif
#ifdef __clang__
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // getenv, localtime
#pragma clang diagnostic ignored "-Wmissing-braces"
#endif
// for mingw BOM, UTF-16, and Unicode functions
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
#if (__MINGW32_MAJOR_VERSION > 3) || \
((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION < 16))
#error - Use MinGW compiler version 4 or higher
#endif
#endif
#ifdef ASTYLE_LIB
// define STDCALL and EXPORT for Windows
// MINGW defines STDCALL in Windows.h (actually windef.h)
// EXPORT has no value if ASTYLE_NO_EXPORT is defined
#ifdef _WIN32
#ifndef STDCALL
#define STDCALL __stdcall
#endif
// define this to prevent compiler warning and error messages
#ifdef ASTYLE_NO_EXPORT
#define EXPORT
#else
#define EXPORT __declspec(dllexport)
#endif
// define STDCALL and EXPORT for non-Windows
// visibility attribute allows "-fvisibility=hidden" compiler option
#else
#define STDCALL
#if __GNUC__ >= 4
#define EXPORT __attribute__ ((visibility ("default")))
#else
#define EXPORT
#endif
#endif // #ifdef _WIN32
// define utf-16 bit text for the platform
typedef unsigned short utf16_t;
// define pointers to callback error handler and memory allocation
typedef void (STDCALL* fpError)(int errorNumber, const char* errorMessage);
typedef char* (STDCALL* fpAlloc)(unsigned long memoryNeeded);
#endif // #ifdef ASTYLE_LIB
//----------------------------------------------------------------------------
// astyle namespace
//----------------------------------------------------------------------------
namespace astyle {
//
//----------------------------------------------------------------------------
// ASStreamIterator class
// typename will be istringstream for GUI and istream otherwise
// ASSourceIterator is an abstract class defined in astyle.h
//----------------------------------------------------------------------------
template<typename T>
class ASStreamIterator : public ASSourceIterator
{
public:
bool checkForEmptyLine;
// function declarations
explicit ASStreamIterator(T* in);
virtual ~ASStreamIterator();
bool getLineEndChange(int lineEndFormat) const;
int getStreamLength() const;
string nextLine(bool emptyLineWasDeleted);
string peekNextLine();
void peekReset();
void saveLastInputLine();
streamoff tellg();
private:
ASStreamIterator(const ASStreamIterator& copy); // copy constructor not to be implemented
ASStreamIterator& operator=(ASStreamIterator&); // assignment operator not to be implemented
T* inStream; // pointer to the input stream
string buffer; // current input line
string prevBuffer; // previous input line
string outputEOL; // next output end of line char
int eolWindows; // number of Windows line endings, CRLF
int eolLinux; // number of Linux line endings, LF
int eolMacOld; // number of old Mac line endings. CR
streamoff streamLength; // length of the input file stream
streamoff peekStart; // starting position for peekNextLine
bool prevLineDeleted; // the previous input line was deleted
public: // inline functions
bool compareToInputBuffer(const string& nextLine_) const
{ return (nextLine_ == prevBuffer); }
const string& getOutputEOL() const { return outputEOL; }
bool hasMoreLines() const { return !inStream->eof(); }
};
//----------------------------------------------------------------------------
// ASEncoding class for utf8/16 conversions
// used by both console and library builds
//----------------------------------------------------------------------------
class ASEncoding
{
private:
typedef unsigned short utf16; // 16 bits
typedef unsigned char utf8; // 8 bits
typedef unsigned char ubyte; // 8 bits
enum { SURROGATE_LEAD_FIRST = 0xD800 };
enum { SURROGATE_LEAD_LAST = 0xDBFF };
enum { SURROGATE_TRAIL_FIRST = 0xDC00 };
enum { SURROGATE_TRAIL_LAST = 0xDFFF };
enum { SURROGATE_FIRST_VALUE = 0x10000 };
enum eState { eStart, eSecondOf4Bytes, ePenultimate, eFinal };
public:
bool getBigEndian() const;
int swap16bit(int value) const;
size_t utf16len(const utf16* utf16In) const;
size_t utf8LengthFromUtf16(const char* utf16In, size_t inLen, bool isBigEndian) const;
size_t utf8ToUtf16(char* utf8In, size_t inLen, bool isBigEndian, char* utf16Out) const;
size_t utf16LengthFromUtf8(const char* utf8In, size_t len) const;
size_t utf16ToUtf8(char* utf16In, size_t inLen, bool isBigEndian,
bool firstBlock, char* utf8Out) const;
};
//----------------------------------------------------------------------------
// ASOptions class for options processing
// used by both console and library builds
//----------------------------------------------------------------------------
class ASConsole;
class ASOptions
{
public:
#ifdef ASTYLE_LIB
ASOptions(ASFormatter& formatterArg);
#else
ASOptions(ASFormatter& formatterArg, ASConsole& consoleArg);
#endif
string getOptionErrors() const;
void importOptions(istream& in, vector<string>& optionsVector);
bool parseOptions(vector<string>& optionsVector, const string& errorInfo);
private:
// variables
ASFormatter& formatter;
stringstream optionErrors; // option error messages
#ifndef ASTYLE_LIB
ASConsole& console; // DO NOT USE for ASTYLE_LIB
#endif
// functions
ASOptions(const ASOptions&); // copy constructor not to be implemented
ASOptions& operator=(ASOptions&); // assignment operator not to be implemented
string getParam(const string& arg, const char* op);
string getParam(const string& arg, const char* op1, const char* op2);
bool isOption(const string& arg, const char* op);
bool isOption(const string& arg, const char* op1, const char* op2);
void isOptionError(const string& arg, const string& errorInfo);
bool isParamOption(const string& arg, const char* option);
bool isParamOption(const string& arg, const char* option1, const char* option2);
void parseOption(const string& arg, const string& errorInfo);
};
#ifndef ASTYLE_LIB
//----------------------------------------------------------------------------
// ASConsole class for console build
//----------------------------------------------------------------------------
class ASConsole
{
private: // variables
ASFormatter& formatter; // reference to the ASFormatter object
ASLocalizer localizer; // ASLocalizer object
ostream* errorStream; // direct error messages to cerr or cout
// command line options
bool isRecursive; // recursive option
bool isDryRun; // dry-run option
bool noBackup; // suffix=none option
bool preserveDate; // preserve-date option
bool isVerbose; // verbose option
bool isQuiet; // quiet option
bool isFormattedOnly; // formatted lines only option
bool ignoreExcludeErrors; // don't abort on unmatched excludes
bool ignoreExcludeErrorsDisplay; // don't display unmatched excludes
bool optionsFileRequired; // options= option
bool useAscii; // ascii option
// other variables
bool bypassBrowserOpen; // don't open the browser on html options
bool hasWildcard; // file name includes a wildcard
size_t mainDirectoryLength; // directory length to be excluded in displays
bool filesAreIdentical; // input and output files are identical
int filesFormatted; // number of files formatted
int filesUnchanged; // number of files unchanged
bool lineEndsMixed; // output has mixed line ends
int linesOut; // number of output lines
ASEncoding utf8_16; // utf8/16 conversion methods
string outputEOL; // current line end
string prevEOL; // previous line end
string optionsFileName; // file path and name of the options file to use
string origSuffix; // suffix= option
string stdPathIn; // path to input from stdin=
string stdPathOut; // path to output from stdout=
string targetDirectory; // path to the directory being processed
string targetFilename; // file name being processed
vector<string> excludeVector; // exclude from wildcard hits
vector<bool> excludeHitsVector; // exclude flags for error reporting
vector<string> fileNameVector; // file paths and names from the command line
vector<string> optionsVector; // options from the command line
vector<string> fileOptionsVector; // options from the options file
vector<string> fileName; // files to be processed including path
public: // functions
explicit ASConsole(ASFormatter& formatterArg);
~ASConsole();
void convertLineEnds(ostringstream& out, int lineEnd);
FileEncoding detectEncoding(const char* data, size_t dataSize) const;
void error() const;
void error(const char* why, const char* what) const;
void formatCinToCout();
vector<string> getArgvOptions(int argc, char** argv) const;
bool fileNameVectorIsEmpty() const;
ostream* getErrorStream() const;
bool getFilesAreIdentical() const;
int getFilesFormatted() const;
bool getIgnoreExcludeErrors() const;
bool getIgnoreExcludeErrorsDisplay() const;
bool getIsDryRun() const;
bool getIsFormattedOnly() const;
bool getIsQuiet() const;
bool getIsRecursive() const;
bool getIsVerbose() const;
bool getLineEndsMixed() const;
bool getNoBackup() const;
bool getPreserveDate() const;
string getLanguageID() const;
string getNumberFormat(int num, size_t lcid = 0) const;
string getNumberFormat(int num, const char* groupingArg, const char* separator) const;
string getOptionsFileName() const;
string getOrigSuffix() const;
string getStdPathIn() const;
string getStdPathOut() const;
void processFiles();
void processOptions(const vector<string>& argvOptions);
void setBypassBrowserOpen(bool state);
void setErrorStream(ostream* errStreamPtr);
void setIgnoreExcludeErrors(bool state);
void setIgnoreExcludeErrorsAndDisplay(bool state);
void setIsDryRun(bool state);
void setIsFormattedOnly(bool state);
void setIsQuiet(bool state);
void setIsRecursive(bool state);
void setIsVerbose(bool state);
void setNoBackup(bool state);
void setOptionsFileName(const string& name);
void setOrigSuffix(const string& suffix);
void setPreserveDate(bool state);
void setStdPathIn(const string& path);
void setStdPathOut(const string& path);
void standardizePath(string& path, bool removeBeginningSeparator = false) const;
bool stringEndsWith(const string& str, const string& suffix) const;
void updateExcludeVector(const string& suffixParam);
vector<string> getExcludeVector() const;
vector<bool> getExcludeHitsVector() const;
vector<string> getFileNameVector() const;
vector<string> getOptionsVector() const;
vector<string> getFileOptionsVector() const;
vector<string> getFileName() const;
private: // functions
ASConsole(const ASConsole&); // copy constructor not to be implemented
ASConsole& operator=(ASConsole&); // assignment operator not to be implemented
void correctMixedLineEnds(ostringstream& out);
void formatFile(const string& fileName_);
string getCurrentDirectory(const string& fileName_) const;
void getFileNames(const string& directory, const string& wildcard);
void getFilePaths(const string& filePath);
string getParam(const string& arg, const char* op);
void initializeOutputEOL(LineEndFormat lineEndFormat);
bool isOption(const string& arg, const char* op);
bool isOption(const string& arg, const char* a, const char* b);
bool isParamOption(const string& arg, const char* option);
bool isPathExclued(const string& subPath);
void launchDefaultBrowser(const char* filePathIn = nullptr) const;
void printHelp() const;
void printMsg(const char* msg, const string& data) const;
void printSeparatingLine() const;
void printVerboseHeader() const;
void printVerboseStats(clock_t startTime) const;
FileEncoding readFile(const string& fileName_, stringstream& in) const;
void removeFile(const char* fileName_, const char* errMsg) const;
void renameFile(const char* oldFileName, const char* newFileName, const char* errMsg) const;
void setOutputEOL(LineEndFormat lineEndFormat, const string& currentEOL);
void sleep(int seconds) const;
int waitForRemove(const char* newFileName) const;
int wildcmp(const char* wild, const char* data) const;
void writeFile(const string& fileName_, FileEncoding encoding, ostringstream& out) const;
#ifdef _WIN32
void displayLastError();
#endif
};
#else // ASTYLE_LIB
//----------------------------------------------------------------------------
// ASLibrary class for library build
//----------------------------------------------------------------------------
class ASLibrary
{
public:
ASLibrary() {}
virtual ~ASLibrary() {}
// virtual functions are mocked in testing
utf16_t* formatUtf16(const utf16_t*, const utf16_t*, fpError, fpAlloc) const;
virtual utf16_t* convertUtf8ToUtf16(const char* utf8In, fpAlloc fpMemoryAlloc) const;
virtual char* convertUtf16ToUtf8(const utf16_t* utf16In) const;
private:
static char* STDCALL tempMemoryAllocation(unsigned long memoryNeeded);
private:
ASEncoding utf8_16; // utf8/16 conversion methods
};
#endif // ASTYLE_LIB
//----------------------------------------------------------------------------
} // end of namespace astyle
//----------------------------------------------------------------------------
// declarations for java native interface (JNI) build
// they are called externally and are NOT part of the namespace
//----------------------------------------------------------------------------
#ifdef ASTYLE_JNI
void STDCALL javaErrorHandler(int errorNumber, const char* errorMessage);
char* STDCALL javaMemoryAlloc(unsigned long memoryNeeded);
// the following function names are constructed from method names in the calling java program
extern "C" EXPORT
jstring STDCALL Java_AStyleInterface_AStyleGetVersion(JNIEnv* env, jclass);
extern "C" EXPORT
jstring STDCALL Java_AStyleInterface_AStyleMain(JNIEnv* env,
jobject obj,
jstring textInJava,
jstring optionsJava);
#endif // ASTYLE_JNI
//----------------------------------------------------------------------------
// declarations for UTF-16 interface
// they are called externally and are NOT part of the namespace
//----------------------------------------------------------------------------
#ifdef ASTYLE_LIB
extern "C" EXPORT
utf16_t* STDCALL AStyleMainUtf16(const utf16_t* pSourceIn,
const utf16_t* pOptions,
fpError fpErrorHandler,
fpAlloc fpMemoryAlloc);
#endif // ASTYLE_LIB
//-----------------------------------------------------------------------------
// declarations for standard DLL interface
// they are called externally and are NOT part of the namespace
//-----------------------------------------------------------------------------
#ifdef ASTYLE_LIB
extern "C" EXPORT char* STDCALL AStyleMain(const char* pSourceIn,
const char* pOptions,
fpError fpErrorHandler,
fpAlloc fpMemoryAlloc);
extern "C" EXPORT const char* STDCALL AStyleGetVersion(void);
#endif // ASTYLE_LIB
//-----------------------------------------------------------------------------
#endif // closes ASTYLE_MAIN_H

BIN
thirdparty/astyle/scripts/opjstyle vendored Executable file

Binary file not shown.

View File

@ -91,6 +91,13 @@ else()
set(BUILD_TESTING "FALSE")
endif(NOT "$ENV{OPJ_CI_SKIP_TESTS}" STREQUAL "1")
if("$ENV{OPJ_CI_CHECK_STYLE}" STREQUAL "1")
set(BUILD_ASTYLE "TRUE")
else()
set(BUILD_ASTYLE "FALSE")
endif("$ENV{OPJ_CI_CHECK_STYLE}" STREQUAL "1")
# Options
set( CACHE_CONTENTS "
@ -100,6 +107,9 @@ CMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}
# Warning level
CMAKE_C_FLAGS:STRING= ${CCFLAGS_ARCH} ${CCFLAGS_WARNING}
# For astyle
CMAKE_CXX_FLAGS:STRING= ${CCFLAGS_ARCH}
# Use to activate the test suite
BUILD_TESTING:BOOL=${BUILD_TESTING}
@ -112,6 +122,8 @@ OPJ_DATA_ROOT:PATH=$ENV{PWD}/data
# jpylyzer is available with on GitHub: https://github.com/openpreserve/jpylyzer
JPYLYZER_EXECUTABLE=$ENV{PWD}/jpylyzer/jpylyzer.${JPYLYZER_EXT}
# Enable astyle
WITH_ASTYLE:BOOL=${BUILD_ASTYLE}
" )
#---------------------

View File

@ -115,3 +115,7 @@ if [ "${OPJ_CI_SKIP_TESTS:-}" != "1" ]; then
fi
fi
fi
if [ "${OPJ_CI_CHECK_STYLE:-}" == "1" ]; then
pip install --user autopep8
fi

View File

@ -30,6 +30,16 @@ if [ "${OPJ_CI_ABI_CHECK:-}" == "1" ]; then
exit 0
fi
if [ "${OPJ_CI_CC:-}" != "" ]; then
export CC=${OPJ_CI_CC}
echo "Using ${CC}"
fi
if [ "${OPJ_CI_CXX:-}" != "" ]; then
export CXX=${OPJ_CI_CXX}
echo "Using ${CXX}"
fi
# Set-up some variables
if [ "${OPJ_CI_BUILD_CONFIGURATION:-}" == "" ]; then
export OPJ_CI_BUILD_CONFIGURATION=Release #default
@ -191,6 +201,15 @@ fi
# ignore ctest exit code & parse this ourselves
set +x
if [ "${OPJ_CI_CHECK_STYLE:-}" == "1" ]; then
export OPJSTYLE=${PWD}/scripts/opjstyle
export PATH=${HOME}/.local/bin:${PATH}
scripts/verify-indentation.sh
fi
# Deployment if needed
#---------------------
if [ "${TRAVIS_TAG:-}" != "" ]; then