Compare commits

...

58 Commits

Author SHA1 Message Date
dd9a3cc627 git: add workflow for auto mirroring git.yzbruh.space/YZBruh/pmt-renovated. 2025-11-24 18:56:04 +03:00
11d75e401e pmt: reformat code, etc. 2025-11-24 18:50:57 +03:00
579b2623a4 Revert "pmt: Set version as release candicate"
This reverts commit 9a1af981d9.
2025-11-02 23:07:35 +03:00
a140320f30 Reapply "README: Fix wrong URLs."
This reverts commit 7405083815.
2025-11-02 23:07:04 +03:00
7405083815 Revert "README: Fix wrong URLs."
This reverts commit eda1b3d50c.
2025-11-02 23:06:03 +03:00
9a1af981d9 pmt: Set version as release candicate 2025-11-02 22:54:27 +03:00
eda1b3d50c README: Fix wrong URLs. 2025-10-28 12:02:31 +03:00
0c48c13852 Cleanup idea files, etc. 2025-10-28 11:42:35 +03:00
7ab20f1c99 .github/workflows/build.yml Güncelle 2025-10-28 11:15:15 +03:00
a45b7332cc build.sh: Stop thread allocation on dual-threaded devices 2025-10-28 11:03:47 +03:00
caff1510f9 .github/workflows/build.yml Güncelle 2025-10-28 10:54:22 +03:00
876674726d revert 4b1c1607ed
revert build.yml: use local server for builds
2025-10-28 10:16:55 +03:00
4b1c1607ed build.yml: use local server for builds 2025-10-28 09:21:34 +03:00
6a25a663e7 revert 1545511859
revert build.yml: Adapt with local git server

Signed-off-by: YZBruh <yagizzengin73@gmail.com>
2025-10-28 09:20:47 +03:00
1545511859 build.yml: Adapt with local git server
Signed-off-by: YZBruh <yagizzengin73@gmail.com>
2025-10-28 08:43:05 +03:00
798cad275c pmt: Improve libhelper, etc. 2025-09-30 21:07:11 +03:00
066080c999 pmt: Add new type (class) to libhelper, etc.
- Add Helper::Capsule.
 - Fix some compilation errors.
2025-09-28 21:45:40 +03:00
397b95466d pmt: reformat code, etc. 2025-09-24 22:14:25 +03:00
0ff94cc4b9 pmt: improve PureTuple class and improve function manager. 2025-09-23 14:13:36 +03:00
b60c5c023f pmt: improve PureTuple class. 2025-09-22 20:16:18 +03:00
17f2fb5660 pmt: cleanup PureTuple class. 2025-09-21 21:19:02 +03:00
6e8931bd68 libhelper: created new type (class) PureTuple (vector-like tuple) 2025-09-21 21:17:23 +03:00
7aca7792ae pmt: add random number generator class (compile-time, with templates) 2025-09-17 00:28:26 +03:00
318739adc8 pmt: add stdin parsing support, etc. 2025-09-15 00:01:52 +03:00
398b119cb4 pmt: improve libhelper, etc. 2025-09-13 11:36:29 +03:00
b99f20c6a1 pmt: fixup manager.sh 2025-09-11 10:59:39 +03:00
37dc3ac94b pmt: reformat code and improve workflow 2025-09-11 10:58:14 +03:00
83c56c795e pmt: update latest release date 2025-09-11 10:13:31 +03:00
de1cb5dd5a pmt: Fixup backup function 2025-09-07 21:55:53 +03:00
9625bf6df0 pmt: Improve libhelper and libpartition_map, etc. 2025-09-07 21:54:35 +03:00
77760bd1d4 pmt: Improve libpartition_map types and some functions.
- Add new operators to Map_t.
 - Add new flags to info function.
 - Move some local pmt function(s) to libhelper.
 - Etc...
2025-09-07 11:56:12 +03:00
1984825dec pmt: add [] operators to Map_t and builder 2025-09-07 10:53:59 +03:00
ab35740fb6 pmt: remove non-signal exit code catching. 2025-09-06 12:12:49 +03:00
08e51c4a15 pmt: start working on 1.3.0
- Add log cleaner function.
 - Introduce function flag structure.
 - Some improvements.
2025-09-06 12:10:46 +03:00
063d62fd85 pmt: fix workflow 2025-09-05 11:38:16 +03:00
2615ddd127 pmt: Last commit for 1.2.0 version
- Major changes for developers.
 - Some changes to flash and sizeof functions.
 - Some minor changes.
2025-09-05 11:31:46 +03:00
51ae72aba1 pmt: add control for -l flag 2025-09-04 21:35:16 +03:00
deab481fd7 pmt: reformat code, etc. 2025-09-04 20:42:50 +03:00
e1dc7132ee pmt: Add documentation to libhelper functions, etc. 2025-09-02 19:20:11 +03:00
360959381b pmt: Improve libraries
- Tests have been improved.
 - Some functions and classes in libhelper have been improved for better results.
2025-09-02 12:41:09 +03:00
0832b57828 pmt: Improve libpartition_map and tests
- Change doFor*** function return types as bool.
 - Add catching of doFor*** function test results.
 - Use std::ios_base_failure for catch std::fstream errors on tests
2025-09-01 01:35:45 +03:00
e7baf4f5bc pmt: Improve pmt & libpartition_map
- Change some operator returnn types.
 - Use std::map instead of std::unordered on magic number maps.
 - Some improvements.
2025-09-01 01:21:06 +03:00
fea9c834fc pmt: reformat code 2025-08-31 15:40:35 +03:00
025ccf3acb pmt: Improve libpartition_map
- Add new operators to Map_t and builder.
 - Some improvements.
2025-08-31 15:36:26 +03:00
d19343d644 pmt: Minor changes.
- Add build instruction.
 - Improve function lambdas.
2025-08-29 13:40:03 +03:00
1a9b4ff5ad pmt: Introduce, fixup
- Fix pstderr file pointer.
 - Improve and add more functions on libpartition_map.
 - Improve functions.
2025-08-28 23:13:52 +03:00
d7bd11165d clean idea config 2025-08-27 22:50:54 +03:00
c2a41b6365 build.sh: Gift two threads to the user... 2025-08-27 22:28:32 +03:00
bfd3324558 pmt: reformat code 2025-08-27 22:24:50 +03:00
41336609fa pmt: switch builder to ninja. And some extra improvements 2025-08-27 22:04:06 +03:00
e0f0b5b484 pmt: Improvements for developers
- Android.bp was written to be included in ROMs/recoveries etc. in Android build system.
 - Macros have been added to simplify feature creation.
 - Some bug fixes (for JSON and pmt).
2025-08-27 15:50:40 +03:00
631c735a9a pmt: reformat code 2025-08-25 13:20:21 +03:00
80bcc0268d pmt: Improve, etc.
- Added custom file descriptors for better print status handling.
 - Added macro to be used for adding functions to make things easier.
 - Duplicate function protection added.
2025-08-25 13:12:46 +03:00
853d2c97b3 Start working for 1.2.0 2025-08-24 16:21:42 +03:00
753d9d8ad2 Cleanup 2025-08-24 16:19:15 +03:00
1d1d6e98ce Reapply "Improve build system, etc..."
This reverts commit 705f529f55.
2025-08-24 16:17:41 +03:00
705f529f55 Revert "Improve build system, etc..."
This reverts commit 249b44a81a.
2025-08-24 16:17:12 +03:00
249b44a81a Improve build system, etc... 2025-08-24 16:16:30 +03:00
49 changed files with 2406 additions and 1351 deletions

View File

@@ -1,6 +1,6 @@
--- ---
Language: Cpp Language: Cpp
AccessModifierOffset: -2 AccessModifierOffset: -1
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignArrayOfStructures: None AlignArrayOfStructures: None
AlignConsecutiveAssignments: AlignConsecutiveAssignments:
@@ -65,7 +65,7 @@ AlignConsecutiveTableGenDefinitionColons:
AlignFunctionDeclarations: false AlignFunctionDeclarations: false
AlignFunctionPointers: false AlignFunctionPointers: false
PadOperators: false PadOperators: false
AlignEscapedNewlines: Right AlignEscapedNewlines: Left
AlignOperands: Align AlignOperands: Align
AlignTrailingComments: AlignTrailingComments:
Kind: Always Kind: Always
@@ -79,17 +79,22 @@ AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLambdasOnASingleLine: All AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: true
AllowShortNamespacesOnASingleLine: false AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false AlwaysBreakBeforeMultilineStrings: true
AttributeMacros: AttributeMacros:
- __capability - __capability
- absl_nonnull
- absl_nullable
- absl_nullability_unknown
BinPackArguments: true BinPackArguments: true
BinPackLongBracedList: true
BinPackParameters: BinPack BinPackParameters: BinPack
BitFieldColonSpacing: Both BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping: BraceWrapping:
AfterCaseLabel: false AfterCaseLabel: false
AfterClass: false AfterClass: false
@@ -118,13 +123,14 @@ BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon BreakInheritanceList: BeforeColon
BreakStringLiterals: true BreakStringLiterals: true
BreakTemplateDeclarations: MultiLine BreakTemplateDeclarations: Yes
ColumnLimit: 80 ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false CompactNamespaces: false
@@ -135,6 +141,7 @@ DerivePointerAlignment: false
DisableFormat: false DisableFormat: false
EmptyLineAfterAccessModifier: Never EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true FixNamespaceComments: true
ForEachMacros: ForEachMacros:
@@ -143,25 +150,29 @@ ForEachMacros:
- BOOST_FOREACH - BOOST_FOREACH
IfMacros: IfMacros:
- KJ_IF_MAYBE - KJ_IF_MAYBE
IncludeBlocks: Preserve IncludeBlocks: Regroup
IncludeCategories: IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Regex: '^<ext/.*\.h>'
Priority: 2 Priority: 2
SortPriority: 0 SortPriority: 0
CaseSensitive: false CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)' - Regex: '^<.*\.h>'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1 Priority: 1
SortPriority: 0 SortPriority: 0
CaseSensitive: false CaseSensitive: false
IncludeIsMainRegex: '(Test)?$' - Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: '' IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false IndentAccessModifiers: false
IndentCaseBlocks: false IndentCaseBlocks: false
IndentCaseLabels: false IndentCaseLabels: true
IndentExportBlock: true IndentExportBlock: true
IndentExternBlock: AfterExternBlock IndentExternBlock: AfterExternBlock
IndentGotoLabels: true IndentGotoLabels: true
@@ -183,7 +194,7 @@ JavaScriptQuotes: Leave
JavaScriptWrapImports: true JavaScriptWrapImports: true
KeepEmptyLines: KeepEmptyLines:
AtEndOfFile: false AtEndOfFile: false
AtStartOfBlock: true AtStartOfBlock: false
AtStartOfFile: true AtStartOfFile: true
KeepFormFeed: false KeepFormFeed: false
LambdaBodyIndentation: Signature LambdaBodyIndentation: Signature
@@ -193,14 +204,15 @@ MacroBlockEnd: ''
MainIncludeChar: Quote MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
NamespaceIndentation: None NamespaceIndentation: None
ObjCBinPackProtocolList: Auto ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2 ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack OneLineFormatOffRegex: ''
PackConstructorInitializers: NextLine
PenaltyBreakAssignment: 2 PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakBeforeMemberAccess: 150 PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300 PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120 PenaltyBreakFirstLessLess: 120
@@ -210,10 +222,40 @@ PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10 PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000 PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0 PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60 PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right PointerAlignment: Left
PPIndentWidth: -1 PPIndentWidth: -1
QualifierAlignment: Leave QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer ReferenceAlignment: Pointer
ReflowComments: Always ReflowComments: Always
RemoveBracesLLVM: false RemoveBracesLLVM: false
@@ -225,11 +267,14 @@ RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1 ShortNamespaceLines: 1
SkipMacroDefinitionBody: false SkipMacroDefinitionBody: false
SortIncludes: CaseSensitive SortIncludes:
Enabled: true
IgnoreCase: false
SortJavaStaticImport: Before SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
@@ -245,6 +290,7 @@ SpaceBeforeParensOptions:
AfterFunctionDefinitionName: false AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false AfterFunctionDeclarationName: false
AfterIfMacros: true AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false AfterOverloadedOperator: false
AfterPlacementOperator: true AfterPlacementOperator: true
AfterRequiresInClause: false AfterRequiresInClause: false
@@ -253,7 +299,7 @@ SpaceBeforeParensOptions:
SpaceBeforeRangeBasedForLoopColon: true SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 1 SpacesBeforeTrailingComments: 2
SpacesInAngles: Never SpacesInAngles: Never
SpacesInContainerLiterals: true SpacesInContainerLiterals: true
SpacesInLineCommentPrefix: SpacesInLineCommentPrefix:
@@ -267,7 +313,7 @@ SpacesInParensOptions:
InEmptyParentheses: false InEmptyParentheses: false
Other: false Other: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
Standard: Latest Standard: Auto
StatementAttributeLikeMacros: StatementAttributeLikeMacros:
- Q_EMIT - Q_EMIT
StatementMacros: StatementMacros:

View File

@@ -23,7 +23,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt upgrade -y sudo apt upgrade -y
sudo apt install make cmake extra-cmake-modules zip -y sudo apt install make ninja-build cmake extra-cmake-modules zip -y
- name: Setup Android NDK - name: Setup Android NDK
id: setup-ndk id: setup-ndk
@@ -35,7 +35,7 @@ jobs:
- name: Build And Prepare For Release - name: Build And Prepare For Release
id: build id: build
run: | run: |
git clone https://github.com/ShawkTeam/pmt-renovated -b main ./pmt && cd pmt git clone https://git.yzbruh.space/${{ github.repository }} -b main ./pmt && cd pmt
export ANDROID_NDK="${{ github.workspace }}/android-ndk-r28c" export ANDROID_NDK="${{ github.workspace }}/android-ndk-r28c"
bash build.sh clean bash build.sh clean
bash build.sh build -DCMAKE_BUILD_TYPE=Release bash build.sh build -DCMAKE_BUILD_TYPE=Release
@@ -49,6 +49,9 @@ jobs:
zip pmt-static-armeabi-v7a.zip pmt_static zip pmt-static-armeabi-v7a.zip pmt_static
echo "BUILD_DATE=$(date +%Y%m%d)" >> $GITHUB_ENV echo "BUILD_DATE=$(date +%Y%m%d)" >> $GITHUB_ENV
echo "BUILD=${{ github.workspace }}/pmt" >> $GITHUB_ENV echo "BUILD=${{ github.workspace }}/pmt" >> $GITHUB_ENV
cd ..
echo -e "Read [Wiki - About Release Types](https://git.yzbruh.space/${{ github.repository }}/wiki/About-Release-Types) for getting more information.\n\n### Changes\n" > release.txt
git log --since="2025-08-21" --pretty=format:" * %ad | [%s](https://git.yzbruh.space/${{ github.repository }}/commit/%H)" --date=short | sed 's/ -.*//' | grep -v cleanup >> release.txt
working-directory: ${{ github.workspace }} working-directory: ${{ github.workspace }}
- name: Upload To GitHub Releases - name: Upload To GitHub Releases
@@ -60,4 +63,4 @@ jobs:
${{ env.BUILD }}/build_armeabi-v7a/*.zip ${{ env.BUILD }}/build_armeabi-v7a/*.zip
name: Partition Manager Tool Release ${{ env.BUILD_DATE }} name: Partition Manager Tool Release ${{ env.BUILD_DATE }}
tag_name: ${{ env.BUILD_DATE }} tag_name: ${{ env.BUILD_DATE }}
body: "Read [Wiki - About Release Types](https://github.com/ShawkTeam/pmt-renovated/wiki/About-Release-Types) for getting more information." body_path: ${{ env.BUILD }}/release.txt

25
.github/workflows/fetch-changes.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Mirror External Repo to GitHub
on:
schedule:
- cron: '0 * * * *'
workflow_dispatch:
jobs:
mirror:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Mirror external repo
run: |
git config --global user.name "github-actions"
git config --global user.email "actions@github.com"
git clone --mirror https://git.yzbruh.space/YZBruh/pmt-renovated.git temp-mirror
cd temp-mirror
git remote add github https://github.com/ShawkTeam/pmt-renovated
git push --mirror github || true

3
.gitignore vendored
View File

@@ -7,8 +7,7 @@ cmake-build-*
include/generated include/generated
# Dont't add build directories # Dont't add build directories
build_arm64-v8a build_*
build_armeabi-v7a
# Don't add generated objects and libs # Don't add generated objects and libs
*.o *.o

1
.idea/.name generated
View File

@@ -1 +0,0 @@
pmt

2
.idea/1.0.0.iml generated
View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

344
.idea/editor.xml generated
View File

@@ -1,344 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BackendCodeEditorSettings">
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstevalIfIsAlwaysConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractVirtualFunctionCallInCtor/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatBadCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatLegacyCode/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatMixedArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooFewArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCoroutineCallResolveError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAArrayIndexOutOfBounds/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAEndlessLoop/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInfiniteRecursion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFATimeOver/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnusedValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesLocal/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesUncapturedLocal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedEntity/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedOverridenMethod/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDereferenceOperatorLimitExceeded/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersPlacement/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceDoStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceForStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceFunctionDeclarationStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceIfStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceNestedNamespacesStyle/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceWhileStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityAssignedButNoRead/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityUsedOnlyInUnevaluatedContext/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalFunctionInFinalClass/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalNonOverridingVirtualFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHiddenFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHidingFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInconsistentNaming/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInvalidLineContinuation/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberInitializersOrder/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppModulePartitionWithSeveralPartitionUnits/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterWideLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineVariableDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderIsNotIncluded/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderNotFound/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantControlFlowJump/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElaboratedTypeSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeyword/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeywordInsideCompoundStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantFwdClassOrEnumSpecifier/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifierADL/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnMemberAllocationFunction/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnThreadLocalLocalVariable/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAlgorithmWithCount/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAuto/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAutoForNumeric/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStructuredBinding/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseTypeTraitAlias/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongIncludesOrder/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongSlashesInIncludeDirective/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IfStdIsConstantEvaluatedCanBeReplaced/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
</component>
</project>

8
.idea/misc.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakePythonSetting">
<option name="pythonIntegrationState" value="YES" />
</component>
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
<component name="WestSettings"><![CDATA[{}]]></component>
</project>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/1.0.0.iml" filepath="$PROJECT_DIR$/.idea/1.0.0.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

110
Android.bp Normal file
View File

@@ -0,0 +1,110 @@
//
// Copyright 2025 Yağız Zengin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Partition manager tool source list
filegroup {
name: "pmt_srcs",
srcs: [
"src/FunctionManager.cpp",
"src/Main.cpp",
"src/PartitionManager.cpp",
"src/functions/BackupFunction.cpp",
"src/functions/EraseFunction.cpp",
"src/functions/FlashFunction.cpp",
"src/functions/InfoFunction.cpp",
"src/functions/MemoryTestFunction.cpp",
"src/functions/PartitionSizeFunction.cpp",
"src/functions/RealPathFunction.cpp",
"src/functions/RebootFunction.cpp",
"src/functions/TypeFunction.cpp",
],
}
// libhelper source list
filegroup {
name: "libhelper_srcs",
srcs: [
"srclib/libhelper/src/Checkers.cpp",
"srclib/libhelper/src/Classes.cpp",
"srclib/libhelper/src/FileUtil.cpp",
"srclib/libhelper/src/Sha256.cpp",
"srclib/libhelper/src/Utilities.cpp",
],
}
// libpartition_map source list
filegroup {
name: "libpartition_map_srcs",
srcs: [
"srclib/libpartition_map/src/Getters.cpp",
"srclib/libpartition_map/src/Magic.cpp",
"srclib/libpartition_map/src/PartitionMap.cpp",
"srclib/libpartition_map/src/Type.cpp",
],
}
// Default configurations of pmt
cc_defaults {
name: "pmt_defaults",
recovery_available: true,
cflags: [
"-Wall",
"-Werror",
"-Wno-deprecated-declarations",
"-Os",
"-fexceptions",
"-DANDROID_BUILD",
],
ldflags: ["-Wl,-s"],
local_include_dirs: [
"include",
"srclib/libhelper/include",
"srclib/libpartition_map/include",
],
export_include_dirs: [
"include",
"srclib/libhelper/include",
"srclib/libpartition_map/include",
],
shared_libs: ["libbase"],
}
// libhelper library target
cc_library_shared {
name: "libhelper",
defaults: ["pmt_defaults"],
srcs: [":libhelper_srcs"],
}
// libpartition_map library target
cc_library_shared {
name: "libpartition_map",
defaults: ["pmt_defaults"],
srcs: [":libpartition_map_srcs"],
shared_libs: ["libhelper"],
static_libs: ["libc++fs"],
}
// pmt executable target
cc_binary {
name: "pmt",
defaults: ["pmt_defaults"],
srcs: [":pmt_srcs"],
shared_libs: [
"libhelper",
"libpartition_map",
],
}

View File

@@ -16,7 +16,7 @@
# Project info # Project info
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(pmt VERSION 1.1.0) project(pmt VERSION 1.3.0)
# Set compiler flags # Set compiler flags
add_compile_options(-Wall -Werror -Wno-deprecated-declarations) add_compile_options(-Wall -Werror -Wno-deprecated-declarations)
@@ -29,7 +29,7 @@ else()
endif() endif()
# Add pmt's CMake module(s) # Add pmt's CMake module(s)
include(cmake/generate_headers.cmake) include(build/cmake/generate_headers.cmake)
# Generate header(s) # Generate header(s)
get_property(FLAGS DIRECTORY PROPERTY COMPILE_OPTIONS) get_property(FLAGS DIRECTORY PROPERTY COMPILE_OPTIONS)

View File

@@ -25,12 +25,13 @@ PMT is designed for developers, technicians, and Android enthusiasts who need fi
## Documentation ## Documentation
For all information about PMT, see the [wiki](https://github.com/ShawkTeam/pmt-renovated/wiki).\ For all information about PMT, see the [wiki](https://git.yzbruh.space/YZBruh/pmt-renovated/wiki).\
Read [Wiki - Using PMT via Termux or ADB](https://github.com/ShawkTeam/pmt-renovated/wiki/Using-PMT-via-Termux-or-ADB) for learn how to use PMT via Termux or ADB.\ Read [Wiki - Using PMT via Termux or ADB](https://git.yzbruh.space/YZBruh/pmt-renovated/wiki/Using-PMT-via-Termux-or-ADB) for learn how to use PMT via Termux or ADB.\
Detailed usage instructions and option references can be found in the [Wiki - Usage](https://github.com/ShawkTeam/pmt-renovated/wiki/Usage). Detailed usage instructions and option references can be found in the [Wiki - Usage](https://git.yzbruh.space/YZBruh/pmt-renovated/wiki/Usage).\
See [Wiki - How To Build](https://git.yzbruh.space/YZBruh/pmt-renovated/wiki/How-To-Build) to learn how to build.
## Bug Reporting ## Bug Reporting
Please submit bugs at [Issues](https://github.com/ShawkTeam/pmt-renovated/issues) page. Please submit bugs at [Issues](https://git.yzbruh.space/YZBruh/pmt-renovated/issues) page.
--- ---

View File

@@ -15,74 +15,68 @@
# limitations under the License. # limitations under the License.
# #
set -e
BUILD_64="build_arm64-v8a"
BUILD_32="build_armeabi-v7a"
THIS="$(basename $0)" THIS="$(basename $0)"
TARGET_ABI_LIST=("arm64-v8a" "armeabi-v7a")
echo() { command echo "[$THIS]: $@"; } echo() { command echo "[$THIS]: $@"; }
checks() checks() {
{
if [ -z "$ANDROID_NDK" ]; then if [ -z "$ANDROID_NDK" ]; then
echo "Please set ANDROID_NDK variable as your NDK path." echo "Please set ANDROID_NDK variable as your NDK path."
exit 1 exit 1
fi fi
if [ ! -f /usr/bin/cmake ] && [ ! -f /bin/cmake ]; then if ! which cmake &>/dev/null; then
echo "Please verify your CMake installation." echo "Please verify your CMake installation."
exit 1 exit 1
fi fi
if ! which ninja &>/dev/null; then
echo "Please verify your Ninja installation."
exit 1
fi
} }
clean() clean() {
{
echo "Cleaning workspace." echo "Cleaning workspace."
rm -rf $BUILD_32 $BUILD_64 \ for a in ${TARGET_ABI_LIST[@]}; do rm -rf build_$a; done
include/generated \ rm -rf include/generated \
srclib/libhelper/tests/dir \ srclib/libhelper/tests/dir \
srclib/libhelper/tests/linkdir \ srclib/libhelper/tests/linkdir \
srclib/libhelper/tests/file.txt srclib/libhelper/tests/file.txt
} }
build() build() {
{ set -e
mkdir -p $BUILD_64 $BUILD_32
command echo -e "BUILD INFO: command echo -e "BUILD INFO:
ARCHS: arm64-v8a armeabi-v7a ARCHS: ${TARGET_ABI_LIST[@]}
ANDROID_PLATFORM: $ANDROID_PLATFORM ANDROID_PLATFORM: $ANDROID_PLATFORM
ANDROID_TOOLCHAIN_FILE: $ANDROID_NDK/build/cmake/android.toolchain.cmake\n" ANDROID_TOOLCHAIN_FILE: $ANDROID_NDK/build/cmake/android.toolchain.cmake\n"
echo "Configuring for arm64-v8a..." for a in ${TARGET_ABI_LIST[@]}; do
cmake -B $BUILD_64 -S . $1 \ echo "Configuring for $a..."
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ mkdir -p build_$a
-DANDROID_ABI=arm64-v8a \ cmake -B build_$a -G Ninja -S . $1 \
-DANDROID_PLATFORM=$ANDROID_PLATFORM \ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_STL=c++_static -DANDROID_ABI=$a \
-DANDROID_PLATFORM=$ANDROID_PLATFORM \
-DANDROID_STL=c++_static
done
echo "Configuring for armeabi-v7a..." CORES=$(($(nproc --all) - 2))
cmake -B $BUILD_32 -S . $1 \ [ $CORES -eq 0 ] && CORES=2
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_PLATFORM=$ANDROID_PLATFORM \
-DANDROID_STL=c++_static
echo "Building arm64-v8a artifacts..." for a in ${TARGET_ABI_LIST[@]}; do
cmake --build $BUILD_64 echo "Building $a artifacts... Using $CORES thread."
echo "arm64-v8a build complete, artifacts: $PWD/$BUILD_64" cmake --build build_$a -j$CORES
echo "$a build complete, artifacts: $PWD/build_$a"
echo "Building armeabi-v7a artifacts..." done
cmake --build $BUILD_32
echo "armeabi-v7a build complete, artifacts: $PWD/$BUILD_32"
} }
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
command echo "Usage: $0 build|rebuild|clean [EXTRA_CMAKE_FLAGS] [ANDROID_PLATFORM=SELECTED_ANDROID_PLATFORM]" command echo -e "Usage: $0 build|rebuild|clean [EXTRA_CMAKE_FLAGS]\n HINT: Export ANDROID_PLATFORM if you set min Android target.\n HINT: Change TARGET_ABI_LIST array in build.sh if you build other archs."
exit 1 exit 1
fi fi
if [ -z $ANDROID_PLATFORM ]; then ANDROID_PLATFORM="android-21"; fi [ -z $ANDROID_PLATFORM ] && ANDROID_PLATFORM="android-21"
checks checks
case $1 in case $1 in

View File

@@ -28,35 +28,124 @@
#define PMTE "pmt" #define PMTE "pmt"
#define PMTF "libpmt-function-manager" #define PMTF "libpmt-function-manager"
// Quick access to variables.
#define VARS (*Variables)
// Quick access to partition map.
#define PART_MAP (*VARS.PartMap)
namespace PartitionManager { namespace PartitionManager {
int Main(int argc, char** argv);
// Print messages if not using quiet mode
__attribute__((format(printf, 1, 2))) void print(const char* format, ...);
__attribute__((format(printf, 1, 2))) void println(const char* format, ...);
// If there is a delimiter in the string, CLI::detail::split returns; if not, an
// empty vector is returned. And checks duplicate arguments.
std::vector<std::string> splitIfHasDelim(const std::string& s, char delim,
bool checkForBadUsage = false);
// Process vectors with input strings. Use for [flag(s)]-[other flag(s)]
// situations
void processCommandLine(std::vector<std::string>& vec1,
std::vector<std::string>& vec2, const std::string& s1,
const std::string& s2, char delim,
bool checkForBadUsage = false);
// Setting ups buffer size
void setupBufferSize(uint64_t& size, const std::string& entry);
std::string getLibVersion();
std::string getAppVersion(); // Not Android app version (an Android app is
// planned!), tells pmt version.
enum basic_function_flags {
NO_SU = 1,
NO_MAP_CHECK = 2,
ADB_SUFFICIENT = 3,
};
// All function classes must inherit from this class. // All function classes must inherit from this class.
class basic_function { class basic_function {
public: public:
CLI::App *cmd = nullptr; CLI::App* cmd = nullptr;
std::vector<int> flags = {};
virtual bool init(CLI::App &_app) = 0; virtual bool init(CLI::App& _app) = 0;
virtual bool run() = 0; virtual bool run() = 0;
[[nodiscard]] virtual bool isUsed() const = 0; [[nodiscard]] virtual bool isUsed() const = 0;
[[nodiscard]] virtual const char *name() const = 0; [[nodiscard]] virtual const char* name() const = 0;
virtual ~basic_function() = default; virtual ~basic_function() = default;
}; };
// A class for function management. // A class for function management.
class basic_function_manager final { template <class _Type>
private: class basic_manager {
std::vector<std::unique_ptr<basic_function>> _functions; private:
std::vector<std::unique_ptr<_Type>> _functions;
public: public:
void registerFunction(std::unique_ptr<basic_function> _func, CLI::App &_app); void registerFunction(std::unique_ptr<_Type> _func, CLI::App& _app) {
LOGN(PMTF, INFO) << "registering: " << _func->name() << std::endl;
for (const auto& f : _functions) {
if (std::string(_func->name()) == std::string(f->name())) {
LOGN(PMTF, INFO) << "Is already registered: " << _func->name()
<< ". Skipping." << std::endl;
return;
}
}
if (!_func->init(_app))
throw Helper::Error("Cannot init: %s", _func->name());
_functions.push_back(std::move(_func));
LOGN(PMTF, INFO) << _functions.back()->name() << " successfully registered."
<< std::endl;
}
[[nodiscard]] bool isUsed(std::string name) const; [[nodiscard]] bool hasFlagOnUsedFunction(int flag) const {
[[nodiscard]] bool handleAll() const; for (const auto& func : _functions) {
if (func->isUsed()) {
std::for_each(func->flags.begin(), func->flags.end(), [&](const int x) {
LOGN(PMTF, INFO) << "Used flag " << x << " on " << func->name()
<< std::endl;
});
return std::find(func->flags.begin(), func->flags.end(), flag) !=
func->flags.end();
}
}
return false;
}
[[nodiscard]] bool isUsed(const std::string& name) const {
if (_functions.empty()) return false;
for (const auto& func : _functions) {
if (func->name() == name) return func->isUsed();
}
return false;
}
[[nodiscard]] bool handleAll() const {
LOGN(PMTF, INFO) << "running caught commands in command-line." << std::endl;
for (const auto& func : _functions) {
if (func->isUsed()) {
LOGN(PMTF, INFO) << func->name()
<< " is calling because used in command-line."
<< std::endl;
return func->run();
}
}
LOGN(PMTF, INFO) << "not found any used function from command-line."
<< std::endl;
println("Target progress is not specified. Specify a progress.");
return false;
}
}; };
class basic_variables final { class basic_variables final {
public: public:
basic_variables(); basic_variables();
std::unique_ptr<PartitionMap::BuildMap> PartMap; std::unique_ptr<PartitionMap::BuildMap> PartMap;
@@ -70,41 +159,13 @@ public:
}; };
using FunctionBase = basic_function; using FunctionBase = basic_function;
using FunctionManager = basic_function_manager; using FunctionManager = basic_manager<FunctionBase>;
using FunctionFlags = basic_function_flags;
using VariableTable = basic_variables; using VariableTable = basic_variables;
using Error = Helper::Error; using Error = Helper::Error;
extern std::unique_ptr<VariableTable> Variables; extern std::unique_ptr<VariableTable> Variables;
extern FILE *pstdout, *pstderr;
} // namespace PartitionManager
int Main(int argc, char **argv); #endif // #ifndef LIBPMT_LIB_HPP
// Print messages if not using quiet mode
__attribute__((format(printf, 1, 2))) void print(const char *format, ...);
__attribute__((format(printf, 1, 2))) void println(const char *format, ...);
// Format it input and return as std::string
__attribute__((format(printf, 1, 2))) std::string format(const char *format,
...);
// If there is a delimiter in the string, CLI::detail::split returns; if not, an
// empty vector is returned. And checks duplicate arguments.
std::vector<std::string> splitIfHasDelim(const std::string &s, char delim,
bool checkForBadUsage = false);
// Process vectors with input strings. Use for [flag(s)]-[other flag(s)]
// situations
void processCommandLine(std::vector<std::string> &vec1,
std::vector<std::string> &vec2, const std::string &s1,
const std::string &s2, char delim,
bool checkForBadUsage = false);
// Setting ups buffer size
void setupBufferSize(uint64_t &size, const std::string &entry);
std::string getLibVersion();
std::string getAppVersion(); // Not Android app version (an Android app is
// planned!), tells pmt version.
} // namespace PartitionManager
#endif // #ifndef LIBPMT_LIB_HPP

View File

@@ -6090,12 +6090,7 @@ inline void to_json(BasicJsonType& j, const T& t)
template<typename BasicJsonType> template<typename BasicJsonType>
inline void to_json(BasicJsonType& j, const std_fs::path& p) inline void to_json(BasicJsonType& j, const std_fs::path& p)
{ {
#ifdef JSON_HAS_CPP_20
const std::u8string s = p.u8string();
j = std::string(s.begin(), s.end());
#else
j = p.u8string(); // returns std::string in C++17 j = p.u8string(); // returns std::string in C++17
#endif
} }
#endif #endif

View File

@@ -19,8 +19,7 @@ RELEASE="20250821"
echo() { command echo "[$THIS]: $@"; } echo() { command echo "[$THIS]: $@"; }
checks() checks() {
{
if ! curl "https://github.com" &>/dev/null; then if ! curl "https://github.com" &>/dev/null; then
echo "No internet connection!" echo "No internet connection!"
exit 1 exit 1
@@ -32,8 +31,7 @@ checks()
[ ! -f $PREFIX/bin/wget ] && pkg install -y wget [ ! -f $PREFIX/bin/wget ] && pkg install -y wget
} }
select_variant() select_variant() {
{
LINK=""; ARCH=""; VARIANT="" LINK=""; ARCH=""; VARIANT=""
if getprop ro.product.cpu.abi | grep "arm64-v8a" &>/dev/null; then ARCH="arm64-v8a" if getprop ro.product.cpu.abi | grep "arm64-v8a" &>/dev/null; then ARCH="arm64-v8a"
@@ -44,8 +42,7 @@ select_variant()
LINK="https://github.com/ShawkTeam/pmt-renovated/releases/download/${RELEASE}/pmt-${VARIANT}${ARCH}.zip" LINK="https://github.com/ShawkTeam/pmt-renovated/releases/download/${RELEASE}/pmt-${VARIANT}${ARCH}.zip"
} }
download() download() {
{
echo "Downloading pmt-${VARIANT}${ARCH}.zip (${RELEASE})" echo "Downloading pmt-${VARIANT}${ARCH}.zip (${RELEASE})"
if ! wget -O $PREFIX/tmp/pmt.zip "${LINK}" &>/dev/null; then if ! wget -O $PREFIX/tmp/pmt.zip "${LINK}" &>/dev/null; then
echo "Download failed! LINK=${LINK}" echo "Download failed! LINK=${LINK}"
@@ -60,8 +57,7 @@ download()
fi fi
} }
setup() setup() {
{
[ -f $PREFIX/tmp/pmt_static ] && mv $PREFIX/tmp/pmt_static $PREFIX/tmp/pmt [ -f $PREFIX/tmp/pmt_static ] && mv $PREFIX/tmp/pmt_static $PREFIX/tmp/pmt
set -e set -e
install -t $PREFIX/bin $PREFIX/tmp/pmt install -t $PREFIX/bin $PREFIX/tmp/pmt
@@ -72,21 +68,18 @@ setup()
echo "Installed successfully. Try running 'pmt' command." echo "Installed successfully. Try running 'pmt' command."
} }
uninstall() uninstall() {
{
rm -f $PREFIX/bin/pmt $PREFIX/lib/libhelper* $PREFIX/lib/libpartition_map* &>/dev/null rm -f $PREFIX/bin/pmt $PREFIX/lib/libhelper* $PREFIX/lib/libpartition_map* &>/dev/null
} }
is_installed() is_installed() {
{
if /system/bin/which pmt &>/dev/null; then if /system/bin/which pmt &>/dev/null; then
echo "PMT is already installed." echo "PMT is already installed."
exit 1 exit 1
fi fi
} }
cleanup() cleanup() {
{
rm -f $PREFIX/tmp/pmt* $PREFIX/tmp/lib* $PREFIX/tmp/*.zip &>/dev/null rm -f $PREFIX/tmp/pmt* $PREFIX/tmp/lib* $PREFIX/tmp/*.zip &>/dev/null
} }
@@ -95,7 +88,7 @@ if [ $# -eq 0 ]; then
exit 1 exit 1
fi fi
if ! basename -a ${PREFIX}/bin/* | grep "termux" &>/dev/null; then if ! echo ${HOME} | grep "com.termux" &>/dev/null; then
echo "This script only for termux!" echo "This script only for termux!"
exit 1 exit 1
fi fi

View File

@@ -19,6 +19,7 @@ set(PMT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/PartitionManager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/PartitionManager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/functions/BackupFunction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/BackupFunction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/functions/CleanLogFunction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/functions/EraseFunction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/EraseFunction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/functions/FlashFunction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/FlashFunction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/functions/InfoFunction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/InfoFunction.cpp
@@ -30,7 +31,8 @@ set(PMT_SOURCES
) )
# Add pmt # Add pmt
add_executable(pmt ${PMT_SOURCES}) add_executable(pmt ${PMT_SOURCES}
functions/CleanLogFunction.cpp)
add_executable(pmt_static ${PMT_SOURCES}) add_executable(pmt_static ${PMT_SOURCES})
# Set linker options # Set linker options

View File

@@ -14,22 +14,24 @@
limitations under the License. limitations under the License.
*/ */
#include <PartitionManager/PartitionManager.hpp>
#include <fcntl.h> #include <fcntl.h>
#include <PartitionManager/PartitionManager.hpp>
#include <algorithm>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
namespace PartitionManager { namespace PartitionManager {
std::vector<std::string> splitIfHasDelim(const std::string &s, const char delim, std::vector<std::string> splitIfHasDelim(const std::string& s, const char delim,
const bool checkForBadUsage) { const bool checkForBadUsage) {
if (s.find(delim) == std::string::npos) return {}; if (s.find(delim) == std::string::npos) return {};
auto vec = CLI::detail::split(s, delim); auto vec = CLI::detail::split(s, delim);
if (checkForBadUsage) { if (checkForBadUsage) {
std::unordered_set<std::string> set; std::unordered_set<std::string> set;
for (const auto &str : vec) { for (const auto& str : vec) {
if (set.find(str) != set.end()) if (set.find(str) != set.end())
throw CLI::ValidationError("Duplicate element in your inputs!"); throw CLI::ValidationError("Duplicate element in your inputs!");
set.insert(str); set.insert(str);
@@ -39,26 +41,27 @@ std::vector<std::string> splitIfHasDelim(const std::string &s, const char delim,
return vec; return vec;
} }
void setupBufferSize(uint64_t &size, const std::string &entry) { void setupBufferSize(uint64_t& size, const std::string& entry) {
if (Variables->PartMap->hasPartition(entry) && if (PART_MAP.hasPartition(entry) && PART_MAP.sizeOf(entry) % size != 0) {
Variables->PartMap->sizeOf(entry) % size != 0) { println(
println("%sWARNING%s: Specified buffer size is invalid for %s! Using " "%sWARNING%s: Specified buffer size is invalid for %s! Using "
"different buffer size for %s.", "different buffer size for %s.",
YELLOW, STYLE_RESET, entry.data(), entry.data()); YELLOW, STYLE_RESET, entry.data(), entry.data());
size = Variables->PartMap->sizeOf(entry) % 4096 == 0 ? 4096 : 1; size = PART_MAP.sizeOf(entry) % 4096 == 0 ? 4096 : 1;
} else if (Helper::fileIsExists(entry)) { } else if (Helper::fileIsExists(entry)) {
if (Helper::fileSize(entry) % size != 0) { if (Helper::fileSize(entry) % size != 0) {
println("%sWARNING%s: Specified buffer size is invalid for %s! using " println(
"different buffer size for %s.", "%sWARNING%s: Specified buffer size is invalid for %s! using "
YELLOW, STYLE_RESET, entry.data(), entry.data()); "different buffer size for %s.",
YELLOW, STYLE_RESET, entry.data(), entry.data());
size = Helper::fileSize(entry) % 4096 == 0 ? 4096 : 1; size = Helper::fileSize(entry) % 4096 == 0 ? 4096 : 1;
} }
} }
} }
void processCommandLine(std::vector<std::string> &vec1, void processCommandLine(std::vector<std::string>& vec1,
std::vector<std::string> &vec2, const std::string &s1, std::vector<std::string>& vec2, const std::string& s1,
const std::string &s2, const char delim, const std::string& s2, const char delim,
const bool checkForBadUsage) { const bool checkForBadUsage) {
vec1 = splitIfHasDelim(s1, delim, checkForBadUsage); vec1 = splitIfHasDelim(s1, delim, checkForBadUsage);
vec2 = splitIfHasDelim(s2, delim, checkForBadUsage); vec2 = splitIfHasDelim(s2, delim, checkForBadUsage);
@@ -66,40 +69,4 @@ void processCommandLine(std::vector<std::string> &vec1,
if (vec1.empty() && !s1.empty()) vec1.push_back(s1); if (vec1.empty() && !s1.empty()) vec1.push_back(s1);
if (vec2.empty() && !s2.empty()) vec2.push_back(s2); if (vec2.empty() && !s2.empty()) vec2.push_back(s2);
} }
} // namespace PartitionManager
void basic_function_manager::registerFunction(
std::unique_ptr<basic_function> _func, CLI::App &_app) {
LOGN(PMTF, INFO) << "registering function: " << _func->name() << std::endl;
if (!_func->init(_app))
throw Error("Cannot init function: %s\n", _func->name());
_functions.push_back(std::move(_func));
LOGN(PMTF, INFO) << _functions.back()->name() << " successfully registered."
<< std::endl;
}
bool basic_function_manager::isUsed(const std::string name) const {
if (_functions.empty()) return false;
for (const auto &func : _functions) {
if (func->name() == name) return func->isUsed();
}
return false;
}
bool basic_function_manager::handleAll() const {
LOGN(PMTF, INFO) << "running caught function commands in command-line."
<< std::endl;
for (const auto &func : _functions) {
if (func->isUsed()) {
LOGN(PMTF, INFO) << func->name()
<< " is calling because used in command-line."
<< std::endl;
return func->run();
}
}
LOGN(PMTF, INFO) << "not found any used function from command-line."
<< std::endl;
println("Target progress is not specified. Specify a progress.");
return false;
}
} // namespace PartitionManager

View File

@@ -16,8 +16,7 @@
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
int main(int argc, char **argv) { int main(int argc, char** argv) {
// Call integrated main function in library // Call integrated main function in library
Helper::LoggingProperties::setProgramName(PMTE);
return PartitionManager::Main(argc, argv); return PartitionManager::Main(argc, argv);
} }

View File

@@ -14,44 +14,97 @@
limitations under the License. limitations under the License.
*/ */
#include "functions/functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <unistd.h> #include <csignal>
#include <cstdarg> #include <cstdarg>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <csignal>
#include "functions/functions.hpp"
#ifndef ANDROID_BUILD
#include <generated/buildInfo.hpp> #include <generated/buildInfo.hpp>
#endif
#include <unistd.h>
#include <string> #include <string>
namespace PartitionManager { namespace PartitionManager {
__attribute__((constructor)) /**
void init() { * Register functions. Uses ready 'FuncManager' variable.
*
* Usage: REGISTER_FUNCTION(FUNCTION_CLASS);
*/
#define REGISTER_FUNCTION(cls) \
FuncManager.registerFunction(std::make_unique<cls>(), AppMain)
basic_variables::basic_variables()
: logFile(Helper::LoggingProperties::FILE),
onLogical(false),
quietProcess(false),
verboseMode(false),
viewVersion(false),
forceProcess(false) {
try {
PartMap = std::make_unique<PartitionMap::BuildMap>();
} catch (std::exception&) {
}
}
__attribute__((constructor)) void init() {
Helper::LoggingProperties::setProgramName(PMTE);
Helper::LoggingProperties::setLogFile("/sdcard/Documents/last_pmt_logs.log"); Helper::LoggingProperties::setLogFile("/sdcard/Documents/last_pmt_logs.log");
} }
static void sigHandler(const int sig) { static void sigHandler(const int sig) {
// Even if only SIGINT is to be captured for now, this is still a more appropriate code
if (sig == SIGINT) println("\n%sInterrupted.%s", YELLOW, STYLE_RESET); if (sig == SIGINT) println("\n%sInterrupted.%s", YELLOW, STYLE_RESET);
if (sig == SIGABRT) println("\n%sAborted.%s", RED, STYLE_RESET);
exit(sig); exit(sig);
} }
auto Variables = std::make_unique<VariableTable>(); static int write(void* cookie, const char* buf, const int size) {
auto* real = static_cast<FILE*>(cookie);
basic_variables::basic_variables() if (!VARS.quietProcess) {
: logFile(Helper::LoggingProperties::FILE), onLogical(false), const int ret = fwrite(buf, 1, static_cast<size_t>(size), real);
quietProcess(false), verboseMode(false), viewVersion(false), fflush(real);
forceProcess(false) { return ret;
try { } else
PartMap = std::make_unique<PartitionMap::BuildMap>(); return size;
} catch (std::exception &) {
}
} }
int Main(int argc, char **argv) { static FILE* make_fp(FILE* real) {
return funopen(real, nullptr, write, nullptr, nullptr);
}
auto Variables = std::make_unique<VariableTable>();
FILE* pstdout = make_fp(stdout);
FILE* pstderr = make_fp(stderr);
static Helper::garbageCollector collector;
int Main(int argc, char** argv) {
try { try {
// try-catch start // try-catch start
Helper::LoggingProperties::setProgramName(argv[0]);
collector.closeAfterProgress(pstdout);
collector.closeAfterProgress(pstderr);
signal(SIGINT, sigHandler);
signal(SIGABRT, sigHandler);
if (!isatty(fileno(stdin))) {
char buf[128];
while (fgets(buf, sizeof(buf), stdin) != nullptr) {
buf[strcspn(buf, "\n")] = 0;
const char* token = strtok(buf, " \t");
while (token != nullptr) {
argv[argc] = strdup(token);
argc++;
token = strtok(nullptr, " \t");
}
}
}
if (argc < 2) { if (argc < 2) {
println( println(
"Usage: %s [OPTIONS] [SUBCOMMAND]\nUse --help for more information.", "Usage: %s [OPTIONS] [SUBCOMMAND]\nUse --help for more information.",
@@ -59,119 +112,122 @@ int Main(int argc, char **argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
signal(SIGINT, sigHandler);
CLI::App AppMain{"Partition Manager Tool"}; CLI::App AppMain{"Partition Manager Tool"};
FunctionManager FuncManager; FunctionManager FuncManager;
AppMain.fallthrough(true); AppMain.fallthrough(true);
AppMain.set_help_all_flag("--help-all", "Print full help message and exit"); AppMain.set_help_all_flag("--help-all", "Print full help message and exit");
AppMain.footer("Partition Manager Tool is written by YZBruh\n" AppMain.footer(
"This project licensed under " "Partition Manager Tool is written by YZBruh\n"
"Apache 2.0 license\nReport " "This project licensed under "
"bugs to https://github.com/ShawkTeam/pmt-renovated/issues"); "Apache 2.0 license\nReport "
"bugs to https://github.com/ShawkTeam/pmt-renovated/issues");
AppMain AppMain
.add_option("-S,--search-path", Variables->searchPath, .add_option("-S,--search-path", VARS.searchPath,
"Set partition search path") "Set partition search path")
->check([&](const std::string &val) { ->check([&](const std::string& val) {
if (val.find("/block") == std::string::npos) if (val.find("/block") == std::string::npos)
return std::string( return std::string(
"Partition search path is unexpected! Couldn't find " "Partition search path is unexpected! Couldn't find "
"'block' in input path!"); "'block' in input path!");
return std::string(); return std::string();
}); });
AppMain.add_option("-L,--log-file", Variables->logFile, "Set log file"); AppMain.add_option("-L,--log-file", VARS.logFile, "Set log file");
AppMain.add_flag("-f,--force", Variables->forceProcess, AppMain.add_flag("-f,--force", VARS.forceProcess,
"Force process to be processed"); "Force process to be processed");
AppMain.add_flag("-l,--logical", Variables->onLogical, AppMain.add_flag("-l,--logical", VARS.onLogical,
"Specify that the target partition is dynamic"); "Specify that the target partition is dynamic");
AppMain.add_flag("-q,--quiet", Variables->quietProcess, "Quiet process"); AppMain.add_flag("-q,--quiet", VARS.quietProcess, "Quiet process");
AppMain.add_flag("-V,--verbose", Variables->verboseMode, AppMain.add_flag("-V,--verbose", VARS.verboseMode,
"Detailed information is written on the screen while the " "Detailed information is written on the screen while the "
"transaction is " "transaction is "
"being carried out"); "being carried out");
AppMain.add_flag("-v,--version", Variables->viewVersion, AppMain.add_flag("-v,--version", VARS.viewVersion,
"Print version and exit"); "Print version and exit");
FuncManager.registerFunction(std::make_unique<backupFunction>(), AppMain); REGISTER_FUNCTION(backupFunction);
FuncManager.registerFunction(std::make_unique<flashFunction>(), AppMain); REGISTER_FUNCTION(cleanLogFunction);
FuncManager.registerFunction(std::make_unique<eraseFunction>(), AppMain); REGISTER_FUNCTION(flashFunction);
FuncManager.registerFunction(std::make_unique<partitionSizeFunction>(), REGISTER_FUNCTION(eraseFunction);
AppMain); REGISTER_FUNCTION(partitionSizeFunction);
FuncManager.registerFunction(std::make_unique<infoFunction>(), AppMain); REGISTER_FUNCTION(infoFunction);
FuncManager.registerFunction(std::make_unique<realPathFunction>(), AppMain); REGISTER_FUNCTION(realPathFunction);
FuncManager.registerFunction(std::make_unique<typeFunction>(), AppMain); REGISTER_FUNCTION(typeFunction);
FuncManager.registerFunction(std::make_unique<rebootFunction>(), AppMain); REGISTER_FUNCTION(rebootFunction);
FuncManager.registerFunction(std::make_unique<memoryTestFunction>(), REGISTER_FUNCTION(memoryTestFunction);
AppMain);
CLI11_PARSE(AppMain, argc, argv); CLI11_PARSE(AppMain, argc, argv);
if (Variables->verboseMode) Helper::LoggingProperties::setPrinting(YES); if (VARS.verboseMode) Helper::LoggingProperties::setPrinting<YES>();
if (Variables->viewVersion) { if (VARS.viewVersion) {
println("%s", getAppVersion().data()); println("%s", getAppVersion().data());
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if (!Variables->searchPath.empty())
(*Variables->PartMap)(Variables->searchPath);
if (!Variables->PartMap && Variables->searchPath.empty()) if (FuncManager.hasFlagOnUsedFunction(NO_MAP_CHECK)) {
throw Error("No default search entries were found. Specify a search " if (!VARS.searchPath.empty())
"directory with -S " WARNING(
"(--search-path)"); "-S (--search-path) flag is ignored. Because, don't needed "
"partition map by your used function.\n");
if (!Helper::hasSuperUser()) { if (VARS.onLogical)
if (!((FuncManager.isUsed("rebootFunction") && WARNING(
Helper::hasAdbPermissions()) || "-l (--logical) flag ignored. Because, partition type don't "
FuncManager.isUsed("memoryTestFunction"))) "needed by your used function.\n");
} else {
if (!VARS.searchPath.empty()) (PART_MAP)(VARS.searchPath);
if (!VARS.PartMap && VARS.searchPath.empty())
throw Error( throw Error(
"Partition Manager Tool is requires super-user privileges!\n"); "No default search entries were found. Specify a search "
"directory with -S "
"(--search-path)");
if (VARS.onLogical) {
if (!PART_MAP.hasLogicalPartitions())
throw Error(
"This device doesn't contains logical partitions. But you "
"used -l (--logical) flag.");
}
}
if (!Helper::hasSuperUser() && !FuncManager.hasFlagOnUsedFunction(NO_SU)) {
if (!(FuncManager.hasFlagOnUsedFunction(ADB_SUFFICIENT) &&
Helper::hasAdbPermissions())) {
throw Error("This function is requires super-user privileges!");
}
} }
return FuncManager.handleAll() == true ? EXIT_SUCCESS : EXIT_FAILURE; return FuncManager.handleAll() == true ? EXIT_SUCCESS : EXIT_FAILURE;
} catch (Helper::Error &error) { } catch (Helper::Error& error) {
// catch Helper::Error // catch Helper::Error
if (!Variables->quietProcess) fprintf(pstderr, "%s%sERROR(S) OCCURRED:%s\n%s\n", RED, BOLD, STYLE_RESET,
fprintf(stderr, "%s%sERROR(S) OCCURRED:%s\n%s", RED, BOLD, STYLE_RESET, error.what());
error.what());
return EXIT_FAILURE; return EXIT_FAILURE;
} catch (CLI::Error &error) { } catch (CLI::Error& error) {
// catch CLI::Error // catch CLI::Error
fprintf(stderr, "%s: %s%sFLAG PARSE ERROR:%s %s\n", argv[0], RED, BOLD, fprintf(stderr, "%s: %s%sFLAG PARSE ERROR:%s %s\n", argv[0], RED, BOLD,
STYLE_RESET, error.what()); STYLE_RESET, error.what());
return EXIT_FAILURE; return EXIT_FAILURE;
} // try-catch block end } // try-catch block end
} }
void print(const char *format, ...) { void print(const char* format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
if (!Variables->quietProcess) vfprintf(stdout, format, args); vfprintf(pstdout, format, args);
va_end(args); va_end(args);
} }
void println(const char *format, ...) { void println(const char* format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
if (!Variables->quietProcess) { vfprintf(pstdout, format, args);
vfprintf(stdout, format, args); print("\n");
print("\n");
}
va_end(args); va_end(args);
} }
std::string format(const char *format, ...) {
va_list args;
va_start(args, format);
char str[1024];
vsnprintf(str, sizeof(str), format, args);
va_end(args);
return str;
}
std::string getLibVersion() { MKVERSION(PMT); } std::string getLibVersion() { MKVERSION(PMT); }
std::string getAppVersion() { MKVERSION(PMTE); } std::string getAppVersion() { MKVERSION(PMTE); }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -14,44 +14,47 @@
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp" #include <fcntl.h>
#include <private/android_filesystem_config.h>
#include <unistd.h>
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <cerrno> #include <cerrno>
#include <chrono> #include <chrono>
#include <cstdlib> #include <cstdlib>
#include <fcntl.h>
#include <future> #include <future>
#include <private/android_filesystem_config.h>
#include <unistd.h> #include "functions.hpp"
#define BFUN "backupFunction" #define BFUN "backupFunction"
#define FUNCTION_CLASS backupFunction
namespace PartitionManager { namespace PartitionManager {
pair backupFunction::runAsync(const std::string &partitionName, RUN_ASYNC(const std::string& partitionName, const std::string& outputName,
const std::string &outputName, const uint64_t bufferSize) {
const uint64_t bufferSize) { if (!PART_MAP.hasPartition(partitionName))
if (!Variables->PartMap->hasPartition(partitionName)) return {Helper::format("Couldn't find partition: %s", partitionName.data()),
return {format("Couldn't find partition: %s", partitionName.data()), false}; false};
LOGN(BFUN, INFO) << "back upping " << partitionName << " as " << outputName LOGN(BFUN, INFO) << "Back upping " << partitionName << " as " << outputName
<< std::endl; << std::endl;
if (Variables->onLogical && !Variables->PartMap->isLogical(partitionName)) { if (VARS.onLogical && !PART_MAP.isLogical(partitionName)) {
if (Variables->forceProcess) if (VARS.forceProcess)
LOGN(BFUN, WARNING) LOGN(BFUN, WARNING)
<< "Partition " << partitionName << "Partition " << partitionName
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
<< std::endl; << std::endl;
else else
return { return {Helper::format(
format("Used --logical (-l) flag but is not logical partition: %s", "Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
if (Helper::fileIsExists(outputName) && !Variables->forceProcess) if (Helper::fileIsExists(outputName) && !VARS.forceProcess)
return {format("%s is exists. Remove it, or use --force (-f) flag.", return {Helper::format("%s is exists. Remove it, or use --force (-f) flag.",
outputName.data()), outputName.data()),
false}; false};
LOGN(BFUN, INFO) << "Using buffer size (for back upping " << partitionName LOGN(BFUN, INFO) << "Using buffer size (for back upping " << partitionName
@@ -61,22 +64,22 @@ pair backupFunction::runAsync(const std::string &partitionName,
Helper::garbageCollector collector; Helper::garbageCollector collector;
const int pfd = Helper::openAndAddToCloseList( const int pfd = Helper::openAndAddToCloseList(
Variables->PartMap->getRealPathOf(partitionName), collector, O_RDONLY); PART_MAP.getRealPathOf(partitionName), collector, O_RDONLY);
if (pfd < 0) if (pfd < 0)
return {format("Can't open partition: %s: %s", partitionName.data(), return {Helper::format("Can't open partition: %s: %s", partitionName.data(),
strerror(errno)), strerror(errno)),
false}; false};
const int ffd = Helper::openAndAddToCloseList( const int ffd = Helper::openAndAddToCloseList(
outputName, collector, O_WRONLY | O_CREAT | O_TRUNC, 0644); outputName, collector, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (ffd < 0) if (ffd < 0)
return {format("Can't create/open output file %s: %s", outputName.data(), return {Helper::format("Can't create/open output file %s: %s",
strerror(errno)), outputName.data(), strerror(errno)),
false}; false};
LOGN(BFUN, INFO) << "Writing partition " << partitionName LOGN(BFUN, INFO) << "Writing partition " << partitionName
<< " to file: " << outputName << std::endl; << " to file: " << outputName << std::endl;
auto *buffer = new (std::nothrow) char[bufferSize]; auto* buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize); memset(buffer, 0x00, bufferSize);
@@ -84,8 +87,8 @@ pair backupFunction::runAsync(const std::string &partitionName,
while ((bytesRead = read(pfd, buffer, bufferSize)) > 0) { while ((bytesRead = read(pfd, buffer, bufferSize)) > 0) {
if (const ssize_t bytesWritten = write(ffd, buffer, bytesRead); if (const ssize_t bytesWritten = write(ffd, buffer, bytesRead);
bytesWritten != bytesRead) bytesWritten != bytesRead)
return {format("Can't write partition to output file %s: %s", return {Helper::format("Can't write partition to output file %s: %s",
outputName.data(), strerror(errno)), outputName.data(), strerror(errno)),
false}; false};
} }
@@ -100,12 +103,12 @@ pair backupFunction::runAsync(const std::string &partitionName,
<< ". Access problems maybe occur in non-root mode" << ". Access problems maybe occur in non-root mode"
<< std::endl; << std::endl;
return {format("%s partition successfully back upped to %s", return {Helper::format("%s partition successfully back upped to %s",
partitionName.data(), outputName.data()), partitionName.data(), outputName.data()),
true}; true};
} }
bool backupFunction::init(CLI::App &_app) { INIT {
LOGN(BFUN, INFO) << "Initializing variables of backup function." << std::endl; LOGN(BFUN, INFO) << "Initializing variables of backup function." << std::endl;
cmd = _app.add_subcommand("backup", "Backup partition(s) to file(s)"); cmd = _app.add_subcommand("backup", "Backup partition(s) to file(s)");
cmd->add_option("partition(s)", rawPartitions, "Partition name(s)") cmd->add_option("partition(s)", rawPartitions, "Partition name(s)")
@@ -123,7 +126,7 @@ bool backupFunction::init(CLI::App &_app) {
return true; return true;
} }
bool backupFunction::run() { RUN {
processCommandLine(partitions, outputNames, rawPartitions, rawOutputNames, processCommandLine(partitions, outputNames, rawPartitions, rawOutputNames,
',', true); ',', true);
if (!outputNames.empty() && partitions.size() != outputNames.size()) if (!outputNames.empty() && partitions.size() != outputNames.size())
@@ -147,12 +150,13 @@ bool backupFunction::run() {
std::string end; std::string end;
bool endResult = true; bool endResult = true;
for (auto &future : futures) { for (auto& future : futures) {
auto [fst, snd] = future.get(); auto [fst, snd] = future.get();
if (!snd) { if (!snd) {
end += fst + '\n'; end += fst + '\n';
endResult = false; endResult = false;
} else println("%s", fst.c_str()); } else
println("%s", fst.c_str());
} }
if (!endResult) throw Error("%s", end.c_str()); if (!endResult) throw Error("%s", end.c_str());
@@ -161,7 +165,7 @@ bool backupFunction::run() {
return endResult; return endResult;
} }
bool backupFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *backupFunction::name() const { return BFUN; } NAME { return BFUN; }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -0,0 +1,43 @@
/*
Copyright 2025 Yağız Zengin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <PartitionManager/PartitionManager.hpp>
#include "functions.hpp"
#define CFUN "cleanLogFunction"
#define FUNCTION_CLASS cleanLogFunction
namespace PartitionManager {
INIT {
LOGN(CFUN, INFO) << "Initializing variables of clean log function."
<< std::endl;
flags = {FunctionFlags::NO_MAP_CHECK, FunctionFlags::NO_SU};
cmd = _app.add_subcommand("clean-logs", "Clean PMT logs.");
return true;
}
RUN {
LOGN(CFUN, INFO) << "Removing log file: " << VARS.logFile << std::endl;
Helper::LoggingProperties::setLoggingState<YES>(); // eraseEntry writes log!
return Helper::eraseEntry(VARS.logFile);
}
IS_USED_COMMON_BODY
NAME { return CFUN; }
} // namespace PartitionManager

View File

@@ -14,33 +14,35 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp>
#include <cerrno>
#include <cstdlib>
#include <fcntl.h> #include <fcntl.h>
#include <future>
#include <unistd.h> #include <unistd.h>
#include <PartitionManager/PartitionManager.hpp>
#include <cerrno>
#include <future>
#include "functions.hpp"
#define EFUN "eraseFunction" #define EFUN "eraseFunction"
#define FUNCTION_CLASS eraseFunction
namespace PartitionManager { namespace PartitionManager {
pair eraseFunction::runAsync(const std::string &partitionName, RUN_ASYNC(const std::string& partitionName, const uint64_t bufferSize) {
const uint64_t bufferSize) { if (!PART_MAP.hasPartition(partitionName))
if (!Variables->PartMap->hasPartition(partitionName)) return {Helper::format("Couldn't find partition: %s", partitionName.data()),
return {format("Couldn't find partition: %s", partitionName.data()), false}; false};
if (Variables->onLogical && !Variables->PartMap->isLogical(partitionName)) { if (VARS.onLogical && !PART_MAP.isLogical(partitionName)) {
if (Variables->forceProcess) if (VARS.forceProcess)
LOGN(EFUN, WARNING) LOGN(EFUN, WARNING)
<< "Partition " << partitionName << "Partition " << partitionName
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
<< std::endl; << std::endl;
else else
return { return {Helper::format(
format("Used --logical (-l) flag but is not logical partition: %s", "Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
LOGN(EFUN, INFO) << "Using buffer size: " << bufferSize; LOGN(EFUN, INFO) << "Using buffer size: " << bufferSize;
@@ -49,26 +51,28 @@ pair eraseFunction::runAsync(const std::string &partitionName,
Helper::garbageCollector collector; Helper::garbageCollector collector;
const int pfd = Helper::openAndAddToCloseList( const int pfd = Helper::openAndAddToCloseList(
Variables->PartMap->getRealPathOf(partitionName), collector, O_WRONLY); PART_MAP.getRealPathOf(partitionName), collector, O_WRONLY);
if (pfd < 0) if (pfd < 0)
return {format("Can't open partition: %s: %s", partitionName.data(), return {Helper::format("Can't open partition: %s: %s", partitionName.data(),
strerror(errno)), strerror(errno)),
false}; false};
if (!Variables->forceProcess) if (!VARS.forceProcess) {
Helper::confirmPropt( if (!Helper::confirmPropt(
"Are you sure you want to continue? This could render your device " "Are you sure you want to continue? This could render your device "
"unusable! Do not continue if you " "unusable! Do not continue if you "
"do not know what you are doing!"); "do not know what you are doing!"))
throw Error("Operation canceled.");
}
LOGN(EFUN, INFO) << "Writing zero bytes to partition: " << partitionName LOGN(EFUN, INFO) << "Writing zero bytes to partition: " << partitionName
<< std::endl; << std::endl;
auto *buffer = new (std::nothrow) char[bufferSize]; auto* buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize); memset(buffer, 0x00, bufferSize);
ssize_t bytesWritten = 0; ssize_t bytesWritten = 0;
const uint64_t partitionSize = Variables->PartMap->sizeOf(partitionName); const uint64_t partitionSize = PART_MAP.sizeOf(partitionName);
while (bytesWritten < partitionSize) { while (bytesWritten < partitionSize) {
size_t toWrite = sizeof(buffer); size_t toWrite = sizeof(buffer);
@@ -76,18 +80,19 @@ pair eraseFunction::runAsync(const std::string &partitionName,
toWrite = partitionSize - bytesWritten; toWrite = partitionSize - bytesWritten;
if (const ssize_t result = write(pfd, buffer, toWrite); result == -1) if (const ssize_t result = write(pfd, buffer, toWrite); result == -1)
return {format("Can't write zero bytes to partition: %s: %s", return {Helper::format("Can't write zero bytes to partition: %s: %s",
partitionName.data(), strerror(errno)), partitionName.data(), strerror(errno)),
false}; false};
else bytesWritten += result; else
bytesWritten += result;
} }
return {format("Successfully wrote zero bytes to the %s partition\n", return {Helper::format("Successfully wrote zero bytes to the %s partition",
partitionName.data()), partitionName.data()),
true}; true};
} }
bool eraseFunction::init(CLI::App &_app) { INIT {
LOGN(EFUN, INFO) << "Initializing variables of erase function." << std::endl; LOGN(EFUN, INFO) << "Initializing variables of erase function." << std::endl;
cmd = _app.add_subcommand("erase", "Writes zero bytes to partition(s)"); cmd = _app.add_subcommand("erase", "Writes zero bytes to partition(s)");
cmd->add_option("partition(s)", partitions, "Partition name(s)") cmd->add_option("partition(s)", partitions, "Partition name(s)")
@@ -100,9 +105,9 @@ bool eraseFunction::init(CLI::App &_app) {
return true; return true;
} }
bool eraseFunction::run() { RUN {
std::vector<std::future<pair>> futures; std::vector<std::future<pair>> futures;
for (const auto &partitionName : partitions) { for (const auto& partitionName : partitions) {
uint64_t buf = bufferSize; uint64_t buf = bufferSize;
setupBufferSize(buf, partitionName); setupBufferSize(buf, partitionName);
futures.push_back( futures.push_back(
@@ -113,12 +118,13 @@ bool eraseFunction::run() {
std::string end; std::string end;
bool endResult = true; bool endResult = true;
for (auto &future : futures) { for (auto& future : futures) {
auto [fst, snd] = future.get(); auto [fst, snd] = future.get();
if (!snd) { if (!snd) {
end += fst + '\n'; end += fst + '\n';
endResult = false; endResult = false;
} else println("%s", fst.c_str()); } else
println("%s", fst.c_str());
} }
if (!endResult) throw Error("%s", end.c_str()); if (!endResult) throw Error("%s", end.c_str());
@@ -127,7 +133,7 @@ bool eraseFunction::run() {
return endResult; return endResult;
} }
bool eraseFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *eraseFunction::name() const { return EFUN; } NAME { return EFUN; }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -14,43 +14,47 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp" #include <fcntl.h>
#include <unistd.h>
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <cerrno> #include <cerrno>
#include <cstdlib> #include <cstdlib>
#include <fcntl.h>
#include <future> #include <future>
#include <unistd.h>
#include "functions.hpp"
#define FFUN "flashFunction" #define FFUN "flashFunction"
#define FUNCTION_CLASS flashFunction
namespace PartitionManager { namespace PartitionManager {
pair flashFunction::runAsync(const std::string &partitionName, RUN_ASYNC(const std::string& partitionName, const std::string& imageName,
const std::string &imageName, const uint64_t bufferSize, const bool deleteAfterProgress) {
const uint64_t bufferSize) {
if (!Helper::fileIsExists(imageName)) if (!Helper::fileIsExists(imageName))
return {format("Couldn't find image file: %s", imageName.data()), false}; return {Helper::format("Couldn't find image file: %s", imageName.data()),
if (!Variables->PartMap->hasPartition(partitionName)) false};
return {format("Couldn't find partition: %s", partitionName.data()), false}; if (!PART_MAP.hasPartition(partitionName))
if (Helper::fileSize(imageName) > Variables->PartMap->sizeOf(partitionName)) return {Helper::format("Couldn't find partition: %s", partitionName.data()),
return {format("%s is larger than %s partition size!", imageName.data(), false};
partitionName.data()), if (Helper::fileSize(imageName) > PART_MAP.sizeOf(partitionName))
return {Helper::format("%s is larger than %s partition size!",
imageName.data(), partitionName.data()),
false}; false};
LOGN(FFUN, INFO) << "flashing " << imageName << " to " << partitionName LOGN(FFUN, INFO) << "flashing " << imageName << " to " << partitionName
<< std::endl; << std::endl;
if (Variables->onLogical && !Variables->PartMap->isLogical(partitionName)) { if (VARS.onLogical && !PART_MAP.isLogical(partitionName)) {
if (Variables->forceProcess) if (VARS.forceProcess)
LOGN(FFUN, WARNING) LOGN(FFUN, WARNING)
<< "Partition " << partitionName << "Partition " << partitionName
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
<< std::endl; << std::endl;
else else
return { return {Helper::format(
format("Used --logical (-l) flag but is not logical partition: %s", "Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
LOGN(FFUN, INFO) << "Using buffer size: " << bufferSize << std::endl; LOGN(FFUN, INFO) << "Using buffer size: " << bufferSize << std::endl;
@@ -60,21 +64,20 @@ pair flashFunction::runAsync(const std::string &partitionName,
const int ffd = Helper::openAndAddToCloseList(imageName, collector, O_RDONLY); const int ffd = Helper::openAndAddToCloseList(imageName, collector, O_RDONLY);
if (ffd < 0) if (ffd < 0)
return {format("Can't open image file %s: %s", imageName.data(), return {Helper::format("Can't open image file %s: %s", imageName.data(),
strerror(errno)), strerror(errno)),
false}; false};
const int pfd = Helper::openAndAddToCloseList( const int pfd = Helper::openAndAddToCloseList(
Variables->PartMap->getRealPathOf(partitionName), collector, PART_MAP.getRealPathOf(partitionName), collector, O_RDWR | O_TRUNC);
O_RDWR | O_TRUNC);
if (pfd < 0) if (pfd < 0)
return {format("Can't open partition: %s: %s", partitionName.data(), return {Helper::format("Can't open partition: %s: %s", partitionName.data(),
strerror(errno)), strerror(errno)),
false}; false};
LOGN(FFUN, INFO) << "Writing image " << imageName LOGN(FFUN, INFO) << "Writing image " << imageName
<< " to partition: " << partitionName << std::endl; << " to partition: " << partitionName << std::endl;
auto *buffer = new (std::nothrow) char[bufferSize]; auto* buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize); memset(buffer, 0x00, bufferSize);
@@ -82,17 +85,24 @@ pair flashFunction::runAsync(const std::string &partitionName,
while ((bytesRead = read(ffd, buffer, bufferSize)) > 0) { while ((bytesRead = read(ffd, buffer, bufferSize)) > 0) {
if (const ssize_t bytesWritten = write(pfd, buffer, bytesRead); if (const ssize_t bytesWritten = write(pfd, buffer, bytesRead);
bytesWritten != bytesRead) bytesWritten != bytesRead)
return {format("Can't write partition to output file %s: %s", return {Helper::format("Can't write partition to output file %s: %s",
imageName.data(), strerror(errno)), imageName.data(), strerror(errno)),
false}; false};
} }
return {format("%s is successfully wrote to %s partition", imageName.data(), if (deleteAfterProgress) {
partitionName.data()), LOGN(FFUN, INFO) << "Deleting flash file: " << imageName << std::endl;
if (!Helper::eraseEntry(imageName) && !VARS.quietProcess)
WARNING(
std::string("Cannot erase flash file: " + imageName + "\n").data());
}
return {Helper::format("%s is successfully wrote to %s partition",
imageName.data(), partitionName.data()),
true}; true};
} }
bool flashFunction::init(CLI::App &_app) { INIT {
LOGN(FFUN, INFO) << "Initializing variables of flash function." << std::endl; LOGN(FFUN, INFO) << "Initializing variables of flash function." << std::endl;
cmd = _app.add_subcommand("flash", "Flash image(s) to partition(s)"); cmd = _app.add_subcommand("flash", "Flash image(s) to partition(s)");
cmd->add_option("partition(s)", rawPartitions, "Partition name(s)") cmd->add_option("partition(s)", rawPartitions, "Partition name(s)")
@@ -106,11 +116,14 @@ bool flashFunction::init(CLI::App &_app) {
->default_val("4KB"); ->default_val("4KB");
cmd->add_option("-I,--image-directory", imageDirectory, cmd->add_option("-I,--image-directory", imageDirectory,
"Directory to find image(s) and flash to partition(s)"); "Directory to find image(s) and flash to partition(s)");
cmd->add_flag("-d,--delete", deleteAfterProgress,
"Delete flash file(s) after progress.")
->default_val(false);
return true; return true;
} }
bool flashFunction::run() { RUN {
processCommandLine(partitions, imageNames, rawPartitions, rawImageNames, ',', processCommandLine(partitions, imageNames, rawPartitions, rawImageNames, ',',
true); true);
if (partitions.size() != imageNames.size()) if (partitions.size() != imageNames.size())
@@ -127,19 +140,21 @@ bool flashFunction::run() {
setupBufferSize(buf, imageNames[i]); setupBufferSize(buf, imageNames[i]);
futures.push_back(std::async(std::launch::async, runAsync, partitions[i], futures.push_back(std::async(std::launch::async, runAsync, partitions[i],
imageNames[i], bufferSize)); imageNames[i], bufferSize,
deleteAfterProgress));
LOGN(FFUN, INFO) << "Created thread for flashing image to " << partitions[i] LOGN(FFUN, INFO) << "Created thread for flashing image to " << partitions[i]
<< std::endl; << std::endl;
} }
std::string end; std::string end;
bool endResult = true; bool endResult = true;
for (auto &future : futures) { for (auto& future : futures) {
auto [fst, snd] = future.get(); auto [fst, snd] = future.get();
if (!snd) { if (!snd) {
end += fst + '\n'; end += fst + '\n';
endResult = false; endResult = false;
} else println("%s", fst.c_str()); } else
println("%s", fst.c_str());
} }
if (!endResult) throw Error("%s", end.c_str()); if (!endResult) throw Error("%s", end.c_str());
@@ -148,7 +163,7 @@ bool flashFunction::run() {
return endResult; return endResult;
} }
bool flashFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *flashFunction::name() const { return FFUN; } NAME { return FFUN; }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -14,23 +14,30 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp" #include <fcntl.h>
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <cerrno> #include <cerrno>
#include <cstdlib> #include <cstdlib>
#include <fcntl.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "functions.hpp"
#define IFUN "infoFunction" #define IFUN "infoFunction"
#define FUNCTION_CLASS infoFunction
namespace PartitionManager { namespace PartitionManager {
bool infoFunction::init(CLI::App &_app) {
INIT {
LOGN(IFUN, INFO) << "Initializing variables of info printer function." LOGN(IFUN, INFO) << "Initializing variables of info printer function."
<< std::endl; << std::endl;
cmd = _app.add_subcommand("info", "Tell info(s) of input partition list") cmd = _app.add_subcommand("info", "Tell info(s) of input partition list")
->footer("Use get-all or getvar-all as partition name for getting " ->footer(
"info's of all " "Use get-all or getvar-all as partition name for getting "
"partitions."); "info's of all partitions.\nUse get-logicals as partition "
"name for getting info's of logical partitions.\n"
"Use get-physical as partition name for getting info's of "
"physical partitions.");
cmd->add_option("partition(s)", partitions, "Partition name(s).") cmd->add_option("partition(s)", partitions, "Partition name(s).")
->required() ->required()
->delimiter(','); ->delimiter(',');
@@ -38,6 +45,13 @@ bool infoFunction::init(CLI::App &_app) {
"Print info(s) as JSON body. The body of each partition will " "Print info(s) as JSON body. The body of each partition will "
"be written separately") "be written separately")
->default_val(false); ->default_val(false);
cmd->add_flag("--as-byte", asByte, "View sizes as byte.")->default_val(true);
cmd->add_flag("--as-kilobyte", asKiloBytes, "View sizes as kilobyte.")
->default_val(false);
cmd->add_flag("--as-megabyte", asMega, "View sizes as megabyte.")
->default_val(false);
cmd->add_flag("--as-gigabyte", asGiga, "View sizes as gigabyte.")
->default_val(false);
cmd->add_option("--json-partition-name", jNamePartition, cmd->add_option("--json-partition-name", jNamePartition,
"Specify partition name element for JSON body") "Specify partition name element for JSON body")
->default_val("name"); ->default_val("name");
@@ -53,26 +67,17 @@ bool infoFunction::init(CLI::App &_app) {
return true; return true;
} }
bool infoFunction::run() { RUN {
if (partitions.back() == "get-all" || partitions.back() == "getvar-all") {
partitions.clear();
const auto parts = Variables->PartMap->getPartitionList();
if (!parts)
throw Error("Cannot get list of all partitions! See logs for more "
"information (%s)",
Helper::LoggingProperties::FILE.data());
for (const auto &name : *parts)
partitions.push_back(name);
}
std::vector<PartitionMap::Partition_t> jParts; std::vector<PartitionMap::Partition_t> jParts;
for (const auto &partition : partitions) { sizeCastTypes multiple;
if (!Variables->PartMap->hasPartition(partition)) if (asByte) multiple = B;
throw Error("Couldn't find partition: %s", partition.data()); if (asKiloBytes) multiple = KB;
if (asMega) multiple = MB;
if (asGiga) multiple = GB;
if (Variables->onLogical && !Variables->PartMap->isLogical(partition)) { auto func = [this, &jParts, &multiple] COMMON_LAMBDA_PARAMS -> bool {
if (Variables->forceProcess) if (VARS.onLogical && !props.isLogical) {
if (VARS.forceProcess)
LOGN(IFUN, WARNING) LOGN(IFUN, WARNING)
<< "Partition " << partition << "Partition " << partition
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
@@ -83,23 +88,32 @@ bool infoFunction::run() {
} }
if (jsonFormat) if (jsonFormat)
jParts.push_back({partition, jParts.push_back(
{Variables->PartMap->sizeOf(partition), {partition,
Variables->PartMap->isLogical(partition)}}); {static_cast<uint64_t>(Helper::convertTo(props.size, multiple)),
props.isLogical}});
else else
#ifdef __LP64__ println("partition=%s size=%d isLogical=%s", partition.data(),
println("partition=%s size=%lu isLogical=%s", Helper::convertTo(props.size, multiple),
#else props.isLogical ? "true" : "false");
println("partition=%s size=%llu isLogical=%s",
#endif return true;
partition.data(), Variables->PartMap->sizeOf(partition), };
Variables->PartMap->isLogical(partition) ? "true" : "false");
} if (partitions.back() == "get-all" || partitions.back() == "getvar-all")
PART_MAP.doForAllPartitions(func);
else if (partitions.back() == "get-logicals")
PART_MAP.doForLogicalPartitions(func);
else if (partitions.back() == "get-physicals")
PART_MAP.doForPhysicalPartitions(func);
else
PART_MAP.doForPartitionList(partitions, func);
if (jsonFormat) { if (jsonFormat) {
nlohmann::json j; nlohmann::json j;
j["multipleType"] = Helper::multipleToString(multiple);
j["partitions"] = nlohmann::json::array(); j["partitions"] = nlohmann::json::array();
for (const auto &[name, props] : jParts) { for (const auto& [name, props] : jParts) {
j["partitions"].push_back({{jNamePartition, name}, j["partitions"].push_back({{jNamePartition, name},
{jNameSize, props.size}, {jNameSize, props.size},
{jNameLogical, props.isLogical}}); {jNameLogical, props.isLogical}});
@@ -111,7 +125,7 @@ bool infoFunction::run() {
return true; return true;
} }
bool infoFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *infoFunction::name() const { return IFUN; }; NAME { return IFUN; };
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -14,26 +14,30 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp" #include <fcntl.h>
#include <unistd.h>
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <chrono> #include <chrono>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <fcntl.h>
#include <random> #include <random>
#include <unistd.h>
#include "functions.hpp"
#define MTFUN "memoryTestFunction" #define MTFUN "memoryTestFunction"
#define FUNCTION_CLASS memoryTestFunction
namespace PartitionManager { namespace PartitionManager {
bool memoryTestFunction::init(CLI::App &_app) { INIT {
LOGN(MTFUN, INFO) << "Initializing variables of memory test function." LOGN(MTFUN, INFO) << "Initializing variables of memory test function."
<< std::endl; << std::endl;
flags = {FunctionFlags::NO_MAP_CHECK, FunctionFlags::ADB_SUFFICIENT};
cmd = _app.add_subcommand("memtest", "Test your write/read speed of device."); cmd = _app.add_subcommand("memtest", "Test your write/read speed of device.");
cmd->add_option("testDirectory", testPath, "Path to test directory") cmd->add_option("testDirectory", testPath, "Path to test directory")
->default_val("/data/local/tmp") ->default_val("/data/local/tmp")
->check([&](const std::string &val) { ->check([&](const std::string& val) {
if (val.find("/sdcard") != std::string::npos || if (val.find("/sdcard") != std::string::npos ||
val.find("/storage") != std::string::npos) val.find("/storage") != std::string::npos)
return std::string( return std::string(
@@ -56,33 +60,35 @@ bool memoryTestFunction::init(CLI::App &_app) {
return true; return true;
} }
bool memoryTestFunction::run() { RUN {
if (testFileSize > GB(2) && !VARS.forceProcess)
throw Error(
"File size is more than 2GB! Sizes over 2GB may not give accurate "
"results in the write test. Use -f (--force) for skip this error.");
LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl; LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl;
Helper::garbageCollector collector; Helper::garbageCollector collector;
const std::string test = Helper::pathJoin(testPath, "test.bin"); const std::string test = Helper::pathJoin(testPath, "test.bin");
LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl; LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl;
auto *buffer = new (std::nothrow) char[bufferSize]; auto* buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
std::mt19937 rng(std::random_device{}());
std::uniform_int_distribution dist(0, 255);
for (size_t i = 0; i < bufferSize; i++) for (size_t i = 0; i < bufferSize; i++)
buffer[i] = static_cast<char>(dist(rng)); buffer[i] = static_cast<char>(Helper::Random<1024>::getNumber());
collector.delFileAfterProgress(test); collector.delFileAfterProgress(test);
const int wfd = Helper::openAndAddToCloseList( const int wfd = Helper::openAndAddToCloseList(
test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644); test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
if (wfd < 0) if (wfd < 0) throw Error("Can't open/create test file: %s", strerror(errno));
throw Error("Can't open/create test file: %s\n", strerror(errno));
LOGN(MTFUN, INFO) << "Sequential write test started!" << std::endl; LOGN(MTFUN, INFO) << "Sequential write test started!" << std::endl;
const auto startWrite = std::chrono::high_resolution_clock::now(); const auto startWrite = std::chrono::high_resolution_clock::now();
ssize_t bytesWritten = 0; ssize_t bytesWritten = 0;
while (bytesWritten < testFileSize) { while (bytesWritten < testFileSize) {
const ssize_t ret = write(wfd, buffer, bufferSize); const ssize_t ret = write(wfd, buffer, bufferSize);
if (ret < 0) throw Error("Can't write to test file: %s\n", strerror(errno)); if (ret < 0) throw Error("Can't write to test file: %s", strerror(errno));
bytesWritten += ret; bytesWritten += ret;
} }
@@ -91,18 +97,17 @@ bool memoryTestFunction::run() {
const double writeTime = const double writeTime =
std::chrono::duration<double>(endWrite - startWrite).count(); std::chrono::duration<double>(endWrite - startWrite).count();
println("Sequential write speed: %3.f MB/s", println("Sequential write speed: %3.f MB/s",
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / (static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / writeTime);
writeTime);
LOGN(MTFUN, INFO) << "Sequential write test done!" << std::endl; LOGN(MTFUN, INFO) << "Sequential write test done!" << std::endl;
if (!doNotReadTest) { if (!doNotReadTest) {
auto *rawBuffer = new char[bufferSize + 4096]; auto* rawBuffer = new char[bufferSize + 4096];
collector.delAfterProgress(rawBuffer); collector.delAfterProgress(rawBuffer);
auto *bufferRead = reinterpret_cast<char *>( auto* bufferRead = reinterpret_cast<char*>(
(reinterpret_cast<uintptr_t>(rawBuffer) + 4096 - 1) & ~(4096 - 1)); (reinterpret_cast<uintptr_t>(rawBuffer) + 4096 - 1) & ~(4096 - 1));
const int rfd = const int rfd =
Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_DIRECT); Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_DIRECT);
if (rfd < 0) throw Error("Can't open test file: %s\n", strerror(errno)); if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno));
LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl; LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl;
const auto startRead = std::chrono::high_resolution_clock::now(); const auto startRead = std::chrono::high_resolution_clock::now();
@@ -123,8 +128,7 @@ bool memoryTestFunction::run() {
return true; return true;
} }
bool memoryTestFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *memoryTestFunction::name() const { return MTFUN; } NAME { return MTFUN; }
} // namespace PartitionManager
} // namespace PartitionManager

View File

@@ -14,24 +14,25 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#define SFUN "partitionSizeFunction" #include "functions.hpp"
std::string convertTo(const uint64_t size, const std::string &multiple) { #define SFUN "partitionSizeFunction"
if (multiple == "KB") return std::to_string(TO_KB(size)); #define FUNCTION_CLASS partitionSizeFunction
if (multiple == "MB") return std::to_string(TO_MB(size));
if (multiple == "GB") return std::to_string(TO_GB(size));
return std::to_string(size);
}
namespace PartitionManager { namespace PartitionManager {
bool partitionSizeFunction::init(CLI::App &_app) { INIT {
LOGN(SFUN, INFO) LOGN(SFUN, INFO)
<< "Initializing variables of partition size getter function." << "Initializing variables of partition size getter function."
<< std::endl; << std::endl;
cmd = _app.add_subcommand("sizeof", "Tell size(s) of input partition list"); cmd = _app.add_subcommand("sizeof", "Tell size(s) of input partition list")
->footer(
"Use get-all or getvar-all as partition name for getting "
"sizes of all partitions.\nUse get-logicals as partition "
"name for getting sizes of logical partitions.\n"
"Use get-physical as partition name for getting sizes of "
"physical partitions.");
cmd->add_option("partition(s)", partitions, "Partition name(s).") cmd->add_option("partition(s)", partitions, "Partition name(s).")
->required() ->required()
->delimiter(','); ->delimiter(',');
@@ -43,7 +44,7 @@ bool partitionSizeFunction::init(CLI::App &_app) {
->default_val(false); ->default_val(false);
cmd->add_flag("--as-megabyte", asMega, cmd->add_flag("--as-megabyte", asMega,
"Tell input size of partition list as megabyte.") "Tell input size of partition list as megabyte.")
->default_val(false); ->default_val(true);
cmd->add_flag("--as-gigabyte", asGiga, cmd->add_flag("--as-gigabyte", asGiga,
"Tell input size of partition list as gigabyte.") "Tell input size of partition list as gigabyte.")
->default_val(false); ->default_val(false);
@@ -54,13 +55,16 @@ bool partitionSizeFunction::init(CLI::App &_app) {
return true; return true;
} }
bool partitionSizeFunction::run() { RUN {
for (const auto &partition : partitions) { sizeCastTypes multiple = {};
if (!Variables->PartMap->hasPartition(partition)) if (asByte) multiple = B;
throw Error("Couldn't find partition: %s", partition.data()); if (asKiloBytes) multiple = KB;
if (asMega) multiple = MB;
if (asGiga) multiple = GB;
if (Variables->onLogical && !Variables->PartMap->isLogical(partition)) { auto func = [this, &multiple] COMMON_LAMBDA_PARAMS -> bool {
if (Variables->forceProcess) if (VARS.onLogical && !props.isLogical) {
if (VARS.forceProcess)
LOGN(SFUN, WARNING) LOGN(SFUN, WARNING)
<< "Partition " << partition << "Partition " << partition
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
@@ -70,26 +74,29 @@ bool partitionSizeFunction::run() {
partition.data()); partition.data());
} }
std::string multiple = "MB";
if (asByte) multiple = "B";
if (asKiloBytes) multiple = "KB";
if (asMega) multiple = "MB";
if (asGiga) multiple = "GB";
if (onlySize) if (onlySize)
println( println("%d", Helper::convertTo(props.size, multiple));
"%s",
convertTo(Variables->PartMap->sizeOf(partition), multiple).data());
else else
println("%s: %s%s", partition.data(), println("%s: %d%s", partition.data(),
convertTo(Variables->PartMap->sizeOf(partition), multiple).data(), Helper::convertTo(props.size, multiple),
multiple.data()); Helper::multipleToString(multiple).data());
}
return true;
};
if (partitions.back() == "get-all" || partitions.back() == "getvar-all")
PART_MAP.doForAllPartitions(func);
else if (partitions.back() == "get-logicals")
PART_MAP.doForLogicalPartitions(func);
else if (partitions.back() == "get-physicals")
PART_MAP.doForPhysicalPartitions(func);
else
PART_MAP.doForPartitionList(partitions, func);
return true; return true;
} }
bool partitionSizeFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *partitionSizeFunction::name() const { return SFUN; } NAME { return SFUN; }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -14,30 +14,33 @@
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include "functions.hpp"
#define RPFUN "realPathFunction" #define RPFUN "realPathFunction"
#define FUNCTION_CLASS realPathFunction
namespace PartitionManager { namespace PartitionManager {
bool realPathFunction::init(CLI::App &_app) { INIT {
LOGN(RPFUN, INFO) << "Initializing variables of real path function." LOGN(RPFUN, INFO) << "Initializing variables of real path function."
<< std::endl; << std::endl;
cmd = _app.add_subcommand("real-path", "Tell real paths of partition(s)"); cmd = _app.add_subcommand("real-path", "Tell real paths of partition(s)");
cmd->add_option("partition(s)", partitions, "Partition name(s)") cmd->add_option("partition(s)", partitions, "Partition name(s)")
->required() ->required()
->delimiter(','); ->delimiter(',');
cmd->add_flag("--real-link-path", realLinkPath, "Print real link path(s)")->default_val(false); cmd->add_flag("--real-link-path", realLinkPath, "Print real link path(s)")
->default_val(false);
return true; return true;
} }
bool realPathFunction::run() { RUN {
for (const auto &partition : partitions) { for (const auto& partition : partitions) {
if (!Variables->PartMap->hasPartition(partition)) if (!PART_MAP.hasPartition(partition))
throw Error("Couldn't find partition: %s", partition.data()); throw Error("Couldn't find partition: %s", partition.data());
if (Variables->onLogical && !Variables->PartMap->isLogical(partition)) { if (VARS.onLogical && !PART_MAP.isLogical(partition)) {
if (Variables->forceProcess) if (VARS.forceProcess)
LOGN(RPFUN, WARNING) LOGN(RPFUN, WARNING)
<< "Partition " << partition << "Partition " << partition
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
@@ -48,15 +51,15 @@ bool realPathFunction::run() {
} }
if (realLinkPath) if (realLinkPath)
println("%s", Variables->PartMap->getRealLinkPathOf(partition).data()); println("%s", PART_MAP.getRealLinkPathOf(partition).data());
else else
println("%s", Variables->PartMap->getRealPathOf(partition).data()); println("%s", PART_MAP.getRealPathOf(partition).data());
} }
return true; return true;
} }
bool realPathFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *realPathFunction::name() const { return RPFUN; } NAME { return RPFUN; }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -14,32 +14,37 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include "functions.hpp"
#define RFUN "rebootFunction" #define RFUN "rebootFunction"
#define FUNCTION_CLASS rebootFunction
namespace PartitionManager { namespace PartitionManager {
bool rebootFunction::init(CLI::App &_app) { INIT {
LOGN(RFUN, INFO) << "Initializing variables of reboot function." << std::endl; LOGN(RFUN, INFO) << "Initializing variables of reboot function." << std::endl;
flags = {FunctionFlags::NO_MAP_CHECK, FunctionFlags::ADB_SUFFICIENT};
cmd = _app.add_subcommand("reboot", "Reboots device"); cmd = _app.add_subcommand("reboot", "Reboots device");
cmd->add_option("rebootTarget", rebootTarget, cmd->add_option("rebootTarget", rebootTarget,
"Reboot target (default: normal)"); "Reboot target (default: normal)");
return true; return true;
} }
bool rebootFunction::run() { RUN {
LOGN(RFUN, INFO) << "Rebooting device!!! (custom reboot target: " LOGN(RFUN, INFO) << "Rebooting device!!! (custom reboot target: "
<< (rebootTarget.empty() ? "none" : rebootTarget) << (rebootTarget.empty() ? "none" : rebootTarget)
<< std::endl; << std::endl;
if (Helper::reboot(rebootTarget)) println("Reboot command was sent"); if (Helper::androidReboot(rebootTarget))
else throw Error("Cannot reboot device"); println("Reboot command was sent");
else
throw Error("Cannot reboot device");
return true; return true;
} }
bool rebootFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *rebootFunction::name() const { return RFUN; } NAME { return RFUN; }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -14,13 +14,16 @@
limitations under the License. limitations under the License.
*/ */
#include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <map>
#include "functions.hpp"
#define TFUN "typeFunction" #define TFUN "typeFunction"
#define FUNCTION_CLASS typeFunction
namespace PartitionManager { namespace PartitionManager {
bool typeFunction::init(CLI::App &_app) { INIT {
LOGN(TFUN, INFO) << "Initializing variables of type function." << std::endl; LOGN(TFUN, INFO) << "Initializing variables of type function." << std::endl;
cmd = _app.add_subcommand("type", "Get type of the partition(s) or image(s)"); cmd = _app.add_subcommand("type", "Get type of the partition(s) or image(s)");
cmd->add_option("content(s)", contents, "Content(s)") cmd->add_option("content(s)", contents, "Content(s)")
@@ -39,27 +42,26 @@ bool typeFunction::init(CLI::App &_app) {
return true; return true;
} }
bool typeFunction::run() { RUN {
std::unordered_map<uint64_t, std::string> magics; std::map<uint64_t, std::string> magics;
if (onlyCheckAndroidMagics) if (onlyCheckAndroidMagics)
magics.merge(PartitionMap::Extras::AndroidMagicMap); magics.merge(PartitionMap::Extras::AndroidMagicMap);
else if (onlyCheckFileSystemMagics) else if (onlyCheckFileSystemMagics)
magics.merge(PartitionMap::Extras::FileSystemMagicMap); magics.merge(PartitionMap::Extras::FileSystemMagicMap);
else magics.merge(PartitionMap::Extras::MagicMap); else
magics.merge(PartitionMap::Extras::MagicMap);
for (const auto &content : contents) { for (const auto& content : contents) {
if (!Variables->PartMap->hasPartition(content) && if (!PART_MAP.hasPartition(content) && !Helper::fileIsExists(content))
!Helper::fileIsExists(content)) throw Error("Couldn't find partition or image file: %s", content.data());
throw Error("Couldn't find partition or image file: %s\n",
content.data());
bool found = false; bool found = false;
for (const auto &[magic, name] : magics) { for (const auto& [magic, name] : magics) {
if (PartitionMap::Extras::hasMagic( if (PartitionMap::Extras::hasMagic(
magic, static_cast<ssize_t>(bufferSize), magic, static_cast<ssize_t>(bufferSize),
Helper::fileIsExists(content) Helper::fileIsExists(content)
? content ? content
: Variables->PartMap->getRealPathOf(content))) { : PART_MAP.getRealPathOf(content))) {
println("%s contains %s magic (%s)", content.data(), name.data(), println("%s contains %s magic (%s)", content.data(), name.data(),
PartitionMap::Extras::formatMagic(magic).data()); PartitionMap::Extras::formatMagic(magic).data());
found = true; found = true;
@@ -68,15 +70,15 @@ bool typeFunction::run() {
} }
if (!found) if (!found)
throw Error("Couldn't determine type of %s%s\n", content.data(), throw Error("Couldn't determine type of %s%s", content.data(),
content == "userdata" ? " (encrypted file system?)" : ""); content == "userdata" ? " (encrypted file system?)" : "");
} }
return true; return true;
} }
bool typeFunction::isUsed() const { return cmd->parsed(); } IS_USED_COMMON_BODY
const char *typeFunction::name() const { return TFUN; } NAME { return TFUN; }
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -21,160 +21,133 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#define INIT bool FUNCTION_CLASS::init(CLI::App& _app)
#define RUN bool FUNCTION_CLASS::run()
#define RUN_ASYNC pair FUNCTION_CLASS::runAsync
#define IS_USED bool FUNCTION_CLASS::isUsed() const
#define IS_USED_COMMON_BODY \
bool FUNCTION_CLASS::isUsed() const { return cmd->parsed(); }
#define NAME const char* FUNCTION_CLASS::name() const
/**
* Please define FUNCTION_CLASS before using these macros!!! (INIT etc.)
*/
#define COMMON_FUNCTION_BODY() \
CLI::App* cmd = nullptr; \
bool init(CLI::App& _app) override; \
bool run() override; \
[[nodiscard]] bool isUsed() const override; \
[[nodiscard]] const char* name() const override
namespace PartitionManager { namespace PartitionManager {
using pair = std::pair<std::string, bool>; using pair = std::pair<std::string, bool>;
// Back-up function // Back-up function
class backupFunction final : public FunctionBase { class backupFunction final : public FunctionBase {
private: private:
std::vector<std::string> partitions, outputNames; std::vector<std::string> partitions, outputNames;
std::string rawPartitions, rawOutputNames, outputDirectory; std::string rawPartitions, rawOutputNames, outputDirectory;
uint64_t bufferSize = 0; uint64_t bufferSize = 0;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
static pair runAsync(const std::string& partitionName,
bool init(CLI::App &_app) override; const std::string& outputName, uint64_t bufferSize);
bool run() override;
static pair runAsync(const std::string &partitionName,
const std::string &outputName, uint64_t bufferSize);
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
// Image flasher function // Image flasher function
class flashFunction final : public FunctionBase { class flashFunction final : public FunctionBase {
private: private:
std::vector<std::string> partitions, imageNames; std::vector<std::string> partitions, imageNames;
std::string rawPartitions, rawImageNames, imageDirectory; std::string rawPartitions, rawImageNames, imageDirectory;
uint64_t bufferSize = 0; uint64_t bufferSize = 0;
bool deleteAfterProgress = false;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
static pair runAsync(const std::string& partitionName,
bool init(CLI::App &_app) override; const std::string& imageName, uint64_t bufferSize,
bool run() override; bool deleteAfterProgress);
static pair runAsync(const std::string &partitionName,
const std::string &imageName, uint64_t bufferSize);
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
// Eraser function (writes zero bytes to partition) // Eraser function (writes zero bytes to partition)
class eraseFunction final : public FunctionBase { class eraseFunction final : public FunctionBase {
private: private:
std::vector<std::string> partitions; std::vector<std::string> partitions;
uint64_t bufferSize = 0; uint64_t bufferSize = 0;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
static pair runAsync(const std::string& partitionName, uint64_t bufferSize);
bool init(CLI::App &_app) override;
bool run() override;
static pair runAsync(const std::string &partitionName, uint64_t bufferSize);
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
// Partition size getter function // Partition size getter function
class partitionSizeFunction final : public FunctionBase { class partitionSizeFunction final : public FunctionBase {
private: private:
std::vector<std::string> partitions; std::vector<std::string> partitions;
bool onlySize = false, asByte = false, asKiloBytes = false, asMega = false, bool onlySize = false, asByte = false, asKiloBytes = false, asMega = false,
asGiga = false; asGiga = false;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
bool init(CLI::App &_app) override;
bool run() override;
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
// Partition info getter function // Partition info getter function
class infoFunction final : public FunctionBase { class infoFunction final : public FunctionBase {
private: private:
std::vector<std::string> partitions; std::vector<std::string> partitions;
std::string jNamePartition, jNameSize, jNameLogical; std::string jNamePartition, jNameSize, jNameLogical;
int jIndentSize = 2; int jIndentSize = 2;
bool jsonFormat = false; bool jsonFormat = false, asByte = true, asKiloBytes = false, asMega = false,
asGiga = false;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
bool init(CLI::App &_app) override;
bool run() override;
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
class realPathFunction final : public FunctionBase { class realPathFunction final : public FunctionBase {
private: private:
std::vector<std::string> partitions; std::vector<std::string> partitions;
bool realLinkPath = false; bool realLinkPath = false;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
bool init(CLI::App &_app) override;
bool run() override;
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
class typeFunction final : public FunctionBase { class typeFunction final : public FunctionBase {
private: private:
std::vector<std::string> contents; std::vector<std::string> contents;
bool onlyCheckAndroidMagics = false, onlyCheckFileSystemMagics = false; bool onlyCheckAndroidMagics = false, onlyCheckFileSystemMagics = false;
uint64_t bufferSize = 0; uint64_t bufferSize = 0;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
bool init(CLI::App &_app) override;
bool run() override;
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
class rebootFunction final : public FunctionBase { class rebootFunction final : public FunctionBase {
private: private:
std::string rebootTarget; std::string rebootTarget;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
bool init(CLI::App &_app) override;
bool run() override;
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
class memoryTestFunction final : public FunctionBase { class memoryTestFunction final : public FunctionBase {
private: private:
uint64_t bufferSize = MB(4), /* bufferSizeRandom = KB(4),*/ testFileSize = 0; uint64_t bufferSize = MB(4), /* bufferSizeRandom = KB(4),*/ testFileSize = 0;
std::string testPath; std::string testPath;
bool doNotReadTest = false; bool doNotReadTest = false;
public: public:
CLI::App *cmd = nullptr; COMMON_FUNCTION_BODY();
bool init(CLI::App &_app) override;
bool run() override;
[[nodiscard]] bool isUsed() const override;
[[nodiscard]] const char *name() const override;
}; };
} // namespace PartitionManager class cleanLogFunction final : public FunctionBase {
public:
COMMON_FUNCTION_BODY();
};
#endif // #ifndef FUNCTIONS_HPP } // namespace PartitionManager
#endif // #ifndef FUNCTIONS_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -14,13 +14,14 @@
limitations under the License. limitations under the License.
*/ */
#include <cstdio>
#include <cstdlib>
#include <libhelper/lib.hpp>
#include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <libhelper/lib.hpp>
namespace Helper { namespace Helper {
bool hasSuperUser() { return (getuid() == AID_ROOT); } bool hasSuperUser() { return (getuid() == AID_ROOT); }
bool hasAdbPermissions() { return (getuid() == AID_SHELL); } bool hasAdbPermissions() { return (getuid() == AID_SHELL); }
@@ -68,4 +69,4 @@ bool areLinked(const std::string_view entry1, const std::string_view entry2) {
return (st1 == st2); return (st1 == st2);
} }
} // namespace Helper } // namespace Helper

View File

@@ -14,20 +14,23 @@
limitations under the License. limitations under the License.
*/ */
#include <dirent.h>
#include <fcntl.h>
#include <libgen.h>
#include <unistd.h>
#include <cerrno> #include <cerrno>
#include <cstdarg> #include <cstdarg>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <exception> #include <exception>
#include <fcntl.h> #include <functional>
#include <libgen.h>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <sstream> #include <sstream>
#include <unistd.h>
namespace Helper { namespace Helper {
Error::Error(const char *format, ...) { Error::Error(const char* format, ...) {
char buf[1024]; char buf[1024];
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@@ -37,20 +40,24 @@ Error::Error(const char *format, ...) {
LOGN(HELPER, ERROR) << _message << std::endl; LOGN(HELPER, ERROR) << _message << std::endl;
} }
const char *Error::what() const noexcept { return _message.data(); } const char* Error::what() const noexcept { return _message.data(); }
Logger::Logger(const LogLevels level, const char *func, const char *file, Logger::Logger(const LogLevels level, const char* func, const char* file,
const char *name, const char *sfile, const int line) const char* name, const char* source_file, const int line)
: _level(level), _funcname(func), _logFile(file), _program_name(name), : _level(level),
_file(sfile), _line(line) {} _function_name(func),
_logFile(file),
_program_name(name),
_file(source_file),
_line(line) {}
Logger::~Logger() { Logger::~Logger() {
if (LoggingProperties::DISABLE) return; if (LoggingProperties::DISABLE) return;
char str[1024]; char str[1024];
snprintf(str, sizeof(str), "<%c> [ <prog %s> <on %s:%d> %s %s] %s(): %s", snprintf(str, sizeof(str), "<%c> [ <prog %s> <on %s:%d> %s %s] %s(): %s",
static_cast<char>(_level), _program_name, static_cast<char>(_level), _program_name,
basename(const_cast<char *>(_file)), _line, currentDate().data(), basename(const_cast<char*>(_file)), _line, currentDate().data(),
currentTime().data(), _funcname, _oss.str().data()); currentTime().data(), _function_name, _oss.str().data());
if (!isExists(_logFile)) { if (!isExists(_logFile)) {
if (const int fd = if (const int fd =
@@ -58,15 +65,23 @@ Logger::~Logger() {
fd != -1) fd != -1)
close(fd); close(fd);
else { else {
#ifdef ANDROID_BUILD
LoggingProperties::setLogFile("/tmp/last_pmt_logs.log")
#else
LoggingProperties::setLogFile("last_logs.log"); LoggingProperties::setLogFile("last_logs.log");
LOGN(HELPER, INFO) << "Cannot create log file: " << _logFile << ": " #endif
<< strerror(errno) LOGN(HELPER, INFO)
<< " New logging file: last_logs.log (this file)." << "Cannot create log file: " << _logFile << ": " << strerror(errno)
<< std::endl; #ifdef ANDROID_BUILD
<< " New logging file: /tmp/last_pmt_logs.log (this file)."
#else
<< " New logging file: last_logs.log (this file)."
#endif
<< std::endl;
} }
} }
if (FILE *fp = fopen(_logFile, "a"); fp != nullptr) { if (FILE* fp = fopen(_logFile, "a"); fp != nullptr) {
fprintf(fp, "%s", str); fprintf(fp, "%s", str);
fclose(fp); fclose(fp);
} else { } else {
@@ -81,35 +96,25 @@ Logger::~Logger() {
if (LoggingProperties::PRINT) printf("%s", str); if (LoggingProperties::PRINT) printf("%s", str);
} }
Logger &Logger::operator<<(std::ostream &(*msg)(std::ostream &)) { Logger& Logger::operator<<(std::ostream& (*msg)(std::ostream&)) {
_oss << msg; _oss << msg;
return *this; return *this;
} }
garbageCollector::~garbageCollector() { garbageCollector::~garbageCollector() {
for (const auto &ptr : _ptrs_c) for (auto& ptr_func : _cleaners) ptr_func();
delete[] ptr; for (const auto& fd : _fds) close(fd);
for (const auto &ptr : _ptrs_u) for (const auto& fp : _fps) fclose(fp);
delete[] ptr; for (const auto& dp : _dps) closedir(dp);
for (const auto &fd : _fds) for (const auto& file : _files) eraseEntry(file);
close(fd);
for (const auto &fp : _fps)
fclose(fp);
for (const auto &file : _files)
eraseEntry(file);
} }
void garbageCollector::delAfterProgress(char *&_ptr) { void garbageCollector::delFileAfterProgress(const std::string& _path) {
_ptrs_c.push_back(_ptr); _files.push_back(_path);
}
void garbageCollector::delAfterProgress(uint8_t *&_ptr) {
_ptrs_u.push_back(_ptr);
}
void garbageCollector::delFileAfterProgress(const std::string &path) {
_files.push_back(path);
} }
void garbageCollector::closeAfterProgress(const int _fd) { void garbageCollector::closeAfterProgress(const int _fd) {
_fds.push_back(_fd); _fds.push_back(_fd);
} }
void garbageCollector::closeAfterProgress(FILE *&_fp) { _fps.push_back(_fp); } void garbageCollector::closeAfterProgress(FILE* _fp) { _fps.push_back(_fp); }
} // namespace Helper void garbageCollector::closeAfterProgress(DIR* _dp) { _dps.push_back(_dp); }
} // namespace Helper

View File

@@ -14,16 +14,17 @@
limitations under the License. limitations under the License.
*/ */
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cerrno> #include <cerrno>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <dirent.h>
#include <fcntl.h>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <string> #include <string>
#include <sys/stat.h>
#include <unistd.h>
namespace Helper { namespace Helper {
bool writeFile(const std::string_view file, const std::string_view text) { bool writeFile(const std::string_view file, const std::string_view text) {
@@ -31,7 +32,7 @@ bool writeFile(const std::string_view file, const std::string_view text) {
<< std::endl; << std::endl;
garbageCollector collector; garbageCollector collector;
FILE *fp = openAndAddToCloseList(file, collector, "a"); FILE* fp = openAndAddToCloseList(file, collector, "a");
if (fp == nullptr) return false; if (fp == nullptr) return false;
fprintf(fp, "%s", text.data()); fprintf(fp, "%s", text.data());
@@ -43,13 +44,12 @@ std::optional<std::string> readFile(const std::string_view file) {
LOGN(HELPER, INFO) << "read " << file << " requested." << std::endl; LOGN(HELPER, INFO) << "read " << file << " requested." << std::endl;
garbageCollector collector; garbageCollector collector;
FILE *fp = openAndAddToCloseList(file, collector, "r"); FILE* fp = openAndAddToCloseList(file, collector, "r");
if (fp == nullptr) return std::nullopt; if (fp == nullptr) return std::nullopt;
char buffer[1024]; char buffer[1024];
std::string str; std::string str;
while (fgets(buffer, sizeof(buffer), fp)) while (fgets(buffer, sizeof(buffer), fp)) str += buffer;
str += buffer;
LOGN(HELPER, INFO) << "read " << file << " successfully, read text: \"" << str LOGN(HELPER, INFO) << "read " << file << " successfully, read text: \"" << str
<< "\"" << std::endl; << "\"" << std::endl;
@@ -95,7 +95,7 @@ bool makeRecursiveDirectory(const std::string_view paths) {
snprintf(tmp, sizeof(tmp), "%s", paths.data()); snprintf(tmp, sizeof(tmp), "%s", paths.data());
if (const size_t len = strlen(tmp); tmp[len - 1] == '/') tmp[len - 1] = '\0'; if (const size_t len = strlen(tmp); tmp[len - 1] == '/') tmp[len - 1] = '\0';
for (char *p = tmp + 1; *p; p++) { for (char* p = tmp + 1; *p; p++) {
if (*p == '/') { if (*p == '/') {
*p = '\0'; *p = '\0';
if (access(tmp, F_OK) != 0) { if (access(tmp, F_OK) != 0) {
@@ -150,9 +150,10 @@ bool eraseEntry(const std::string_view entry) {
bool eraseDirectoryRecursive(const std::string_view directory) { bool eraseDirectoryRecursive(const std::string_view directory) {
LOGN(HELPER, INFO) << "erase recursive requested: " << directory << std::endl; LOGN(HELPER, INFO) << "erase recursive requested: " << directory << std::endl;
struct stat buf{}; struct stat buf{};
dirent *entry; dirent* entry;
garbageCollector collector;
DIR *dir = opendir(directory.data()); DIR* dir = openAndAddToCloseList(directory.data(), collector);
if (dir == nullptr) return false; if (dir == nullptr) return false;
while ((entry = readdir(dir)) != nullptr) { while ((entry = readdir(dir)) != nullptr) {
@@ -164,25 +165,17 @@ bool eraseDirectoryRecursive(const std::string_view directory) {
snprintf(fullpath, sizeof(fullpath), "%s/%s", directory.data(), snprintf(fullpath, sizeof(fullpath), "%s/%s", directory.data(),
entry->d_name); entry->d_name);
if (lstat(fullpath, &buf) == -1) { if (lstat(fullpath, &buf) == -1) return false;
closedir(dir);
return false;
}
if (S_ISDIR(buf.st_mode)) { if (S_ISDIR(buf.st_mode)) {
if (!eraseDirectoryRecursive(fullpath)) { if (!eraseDirectoryRecursive(fullpath)) return false;
closedir(dir); } else if (S_ISREG(buf.st_mode)) {
return false; if (!eraseEntry(fullpath)) return false;
}
} else { } else {
if (unlink(fullpath) == -1) { if (unlink(fullpath) == -1) return false;
closedir(dir);
return false;
}
} }
} }
closedir(dir);
if (rmdir(directory.data()) == -1) return false; if (rmdir(directory.data()) == -1) return false;
LOGN(HELPER, INFO) << "\"" << directory << "\" successfully erased." LOGN(HELPER, INFO) << "\"" << directory << "\" successfully erased."
@@ -203,10 +196,10 @@ std::string readSymlink(const std::string_view entry) {
return target; return target;
} }
size_t fileSize(const std::string_view file) { int64_t fileSize(const std::string_view file) {
LOGN(HELPER, INFO) << "get file size request: " << file << std::endl; LOGN(HELPER, INFO) << "get file size request: " << file << std::endl;
struct stat st{}; struct stat st{};
if (stat(file.data(), &st) != 0) return false; if (stat(file.data(), &st) != 0) return -1;
return static_cast<size_t>(st.st_size); return st.st_size;
} }
} // namespace Helper } // namespace Helper

View File

@@ -14,13 +14,14 @@
limitations under the License. limitations under the License.
*/ */
#include <picosha2.h>
#include <sys/stat.h>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <optional> #include <optional>
#include <picosha2.h>
#include <string> #include <string>
#include <sys/stat.h>
#include <vector> #include <vector>
namespace Helper { namespace Helper {
@@ -54,4 +55,4 @@ bool sha256Compare(const std::string_view file1, const std::string_view file2) {
<< "(): input files is contains same sha256 signature." << std::endl; << "(): input files is contains same sha256 signature." << std::endl;
return (*f1 == *f2); return (*f1 == *f2);
} }
} // namespace Helper } // namespace Helper

View File

@@ -14,50 +14,64 @@
limitations under the License. limitations under the License.
*/ */
#include <cutils/android_reboot.h>
#include <fcntl.h>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <ctime> #include <ctime>
#include <cutils/android_reboot.h> #ifndef ANDROID_BUILD
#include <fcntl.h> #include <sys/_system_properties.h>
#include <generated/buildInfo.hpp> #include <generated/buildInfo.hpp>
#include <iostream> #else
#include <sys/system_properties.h>
#endif
#include <cutils/android_reboot.h>
#include <libgen.h> #include <libgen.h>
#include <libhelper/lib.hpp>
#include <memory>
#include <string>
#include <string_view>
#include <sys/_system_properties.h> #include <sys/_system_properties.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <cstdarg>
#include <iostream>
#include <libhelper/lib.hpp>
#include <memory>
#include <string>
#include <string_view>
#ifdef __ANDROID__
// From system/core/libcutils/android_reboot.cpp android16-s2-release // From system/core/libcutils/android_reboot.cpp android16-s2-release
int android_reboot(const unsigned cmd, int /*flags*/, const char *arg) { int android_reboot(const unsigned cmd, int /*flags*/, const char* arg) {
int ret; int ret;
const char *restart_cmd = nullptr; const char* restart_cmd = nullptr;
char *prop_value; char* prop_value;
switch (cmd) { switch (cmd) {
case ANDROID_RB_RESTART: // deprecated case ANDROID_RB_RESTART: // deprecated
case ANDROID_RB_RESTART2: case ANDROID_RB_RESTART2:
restart_cmd = "reboot"; restart_cmd = "reboot";
break; break;
case ANDROID_RB_POWEROFF: case ANDROID_RB_POWEROFF:
restart_cmd = "shutdown"; restart_cmd = "shutdown";
break; break;
case ANDROID_RB_THERMOFF: case ANDROID_RB_THERMOFF:
restart_cmd = "shutdown,thermal"; restart_cmd = "shutdown,thermal";
break; break;
} }
if (!restart_cmd) return -1; if (!restart_cmd) return -1;
if (arg && arg[0]) ret = asprintf(&prop_value, "%s,%s", restart_cmd, arg); if (arg && arg[0])
else ret = asprintf(&prop_value, "%s", restart_cmd); ret = asprintf(&prop_value, "%s,%s", restart_cmd, arg);
else
ret = asprintf(&prop_value, "%s", restart_cmd);
if (ret < 0) return -1; if (ret < 0) return -1;
ret = __system_property_set(ANDROID_RB_PROPERTY, prop_value); ret = __system_property_set(ANDROID_RB_PROPERTY, prop_value);
free(prop_value); free(prop_value);
return ret; return ret;
} }
#endif
namespace Helper { namespace Helper {
namespace LoggingProperties { namespace LoggingProperties {
@@ -77,17 +91,7 @@ void set(std::string_view file, std::string_view name) {
void setProgramName(const std::string_view name) { NAME = name; } void setProgramName(const std::string_view name) { NAME = name; }
void setLogFile(const std::string_view file) { FILE = file; } void setLogFile(const std::string_view file) { FILE = file; }
} // namespace LoggingProperties
void setPrinting(const int state) {
if (state == 1 || state == 0) PRINT = state;
else PRINT = NO;
}
void setLoggingState(const int state) {
if (state == 1 || state == 0) DISABLE = state;
else DISABLE = NO;
}
} // namespace LoggingProperties
bool runCommand(const std::string_view cmd) { bool runCommand(const std::string_view cmd) {
LOGN(HELPER, INFO) << "run command request: " << cmd << std::endl; LOGN(HELPER, INFO) << "run command request: " << cmd << std::endl;
@@ -117,28 +121,28 @@ std::string currentWorkingDirectory() {
std::string currentDate() { std::string currentDate() {
const time_t t = time(nullptr); const time_t t = time(nullptr);
if (const tm *date = localtime(&t)) if (const tm* date = localtime(&t))
return std::string(std::to_string(date->tm_mday) + "/" + return std::string(std::to_string(date->tm_mday) + "/" +
std::to_string(date->tm_mon + 1) + "/" + std::to_string(date->tm_mon + 1) + "/" +
std::to_string(date->tm_year + 1900)); std::to_string(date->tm_year + 1900));
return "--/--/----"; return {};
} }
std::string currentTime() { std::string currentTime() {
const time_t t = time(nullptr); const time_t t = time(nullptr);
if (const tm *date = localtime(&t)) if (const tm* date = localtime(&t))
return std::string(std::to_string(date->tm_hour) + ":" + return std::string(std::to_string(date->tm_hour) + ":" +
std::to_string(date->tm_min) + ":" + std::to_string(date->tm_min) + ":" +
std::to_string(date->tm_sec)); std::to_string(date->tm_sec));
return "--:--:--"; return {};
} }
std::string runCommandWithOutput(const std::string_view cmd) { std::pair<std::string, int> runCommandWithOutput(const std::string_view cmd) {
LOGN(HELPER, INFO) << "run command and catch out request: " << cmd LOGN(HELPER, INFO) << "run command and catch out request: " << cmd
<< std::endl; << std::endl;
FILE *pipe = popen(cmd.data(), "r"); FILE* pipe = popen(cmd.data(), "r");
if (!pipe) return {}; if (!pipe) return {};
std::unique_ptr<FILE, decltype(&pclose)> pipe_holder(pipe, pclose); std::unique_ptr<FILE, decltype(&pclose)> pipe_holder(pipe, pclose);
@@ -149,7 +153,9 @@ std::string runCommandWithOutput(const std::string_view cmd) {
while (fgets(buffer, sizeof(buffer), pipe_holder.get()) != nullptr) while (fgets(buffer, sizeof(buffer), pipe_holder.get()) != nullptr)
output += buffer; output += buffer;
return output; FILE* raw = pipe_holder.release();
const int status = pclose(raw);
return {output, (WIFEXITED(status) ? WEXITSTATUS(status) : -1)};
} }
std::string pathJoin(std::string base, std::string relative) { std::string pathJoin(std::string base, std::string relative) {
@@ -160,12 +166,12 @@ std::string pathJoin(std::string base, std::string relative) {
} }
std::string pathBasename(const std::string_view entry) { std::string pathBasename(const std::string_view entry) {
char *base = basename(const_cast<char *>(entry.data())); char* base = basename(const_cast<char*>(entry.data()));
return (base == nullptr) ? std::string() : std::string(base); return (base == nullptr) ? std::string() : std::string(base);
} }
std::string pathDirname(const std::string_view entry) { std::string pathDirname(const std::string_view entry) {
char *base = dirname(const_cast<char *>(entry.data())); char* base = dirname(const_cast<char*>(entry.data()));
return (base == nullptr) ? std::string() : std::string(base); return (base == nullptr) ? std::string() : std::string(base);
} }
@@ -182,8 +188,8 @@ bool changeOwner(const std::string_view file, const uid_t uid,
return chown(file.data(), uid, gid) == 0; return chown(file.data(), uid, gid) == 0;
} }
int openAndAddToCloseList(const std::string_view &path, int openAndAddToCloseList(const std::string_view& path,
garbageCollector &collector, const int flags, garbageCollector& collector, const int flags,
const mode_t mode) { const mode_t mode) {
const int fd = const int fd =
mode == 0 ? open(path.data(), flags) : open(path.data(), flags, mode); mode == 0 ? open(path.data(), flags) : open(path.data(), flags, mode);
@@ -191,20 +197,28 @@ int openAndAddToCloseList(const std::string_view &path,
return fd; return fd;
} }
FILE *openAndAddToCloseList(const std::string_view &path, FILE* openAndAddToCloseList(const std::string_view& path,
garbageCollector &collector, const char *mode) { garbageCollector& collector, const char* mode) {
FILE *fp = fopen(path.data(), mode); FILE* fp = fopen(path.data(), mode);
collector.closeAfterProgress(fp); collector.closeAfterProgress(fp);
return fp; return fp;
} }
DIR* openAndAddToCloseList(const std::string_view& path,
garbageCollector& collector) {
DIR* dp = opendir(path.data());
collector.closeAfterProgress(dp);
return dp;
}
#ifdef __ANDROID__
std::string getProperty(const std::string_view prop) { std::string getProperty(const std::string_view prop) {
char val[PROP_VALUE_MAX]; char val[PROP_VALUE_MAX];
const int x = __system_property_get(prop.data(), val); const int x = __system_property_get(prop.data(), val);
return x > 0 ? val : "ERROR"; return x > 0 ? val : "ERROR";
} }
bool reboot(const std::string_view arg) { bool androidReboot(const std::string_view arg) {
LOGN(HELPER, INFO) << "reboot request sent!!!" << std::endl; LOGN(HELPER, INFO) << "reboot request sent!!!" << std::endl;
unsigned cmd = ANDROID_RB_RESTART2; unsigned cmd = ANDROID_RB_RESTART2;
@@ -215,12 +229,37 @@ bool reboot(const std::string_view arg) {
return android_reboot(cmd, 0, arg.empty() ? nullptr : arg.data()) != -1; return android_reboot(cmd, 0, arg.empty() ? nullptr : arg.data()) != -1;
} }
#endif
uint64_t getRandomOffset(const uint64_t size, const uint64_t bufferSize) { uint64_t getRandomOffset(const uint64_t size, const uint64_t bufferSize) {
if (size <= bufferSize) return 0; if (size <= bufferSize) return 0;
const uint64_t maxOffset = size - bufferSize; const uint64_t maxOffset = size - bufferSize;
srand(time(nullptr));
return rand() % maxOffset; return rand() % maxOffset;
} }
int convertTo(const uint64_t size, const sizeCastTypes type) {
if (type == KB) return TO_KB(size);
if (type == MB) return TO_MB(size);
if (type == GB) return TO_GB(size);
return static_cast<int>(size);
}
std::string multipleToString(const sizeCastTypes type) {
if (type == KB) return "KB";
if (type == MB) return "MB";
if (type == GB) return "GB";
return "B";
}
std::string format(const char* format, ...) {
va_list args;
va_start(args, format);
char str[1024];
vsnprintf(str, sizeof(str), format, args);
va_end(args);
return str;
}
std::string getLibVersion() { MKVERSION("libhelper"); } std::string getLibVersion() { MKVERSION("libhelper"); }
} // namespace Helper } // namespace Helper

View File

@@ -19,16 +19,16 @@
#include <iostream> #include <iostream>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
char *TEST_DIR = nullptr; char* TEST_DIR = nullptr;
std::string test_path(const char *file) { std::string test_path(const char* file) {
std::string end = std::string(TEST_DIR) + "/" + file; std::string end = std::string(TEST_DIR) + "/" + file;
return end; return end;
} }
int main(int argc, char **argv) { int main(int argc, char** argv) {
if (argc < 2) return 2; if (argc < 2) return 2;
else TEST_DIR = argv[1]; TEST_DIR = argv[1];
try { try {
std::cout << "Has super user?; " << std::boolalpha << Helper::hasSuperUser() std::cout << "Has super user?; " << std::boolalpha << Helper::hasSuperUser()
@@ -50,12 +50,14 @@ int main(int argc, char **argv) {
<< std::endl; << std::endl;
if (!Helper::writeFile("file.txt", "hello world")) if (!Helper::writeFile("file.txt", "hello world"))
throw Helper::Error("Cannor write \"hello world\" in 'file.txt'"); throw Helper::Error("Cannot write \"hello world\" in 'file.txt'");
else std::cout << "file.txt writed." << std::endl; else
std::cout << "file.txt writed." << std::endl;
auto content = Helper::readFile("file.txt"); if (const auto content = Helper::readFile("file.txt"); !content)
if (!content) throw Helper::Error("Cannot read 'file.txt'"); throw Helper::Error("Cannot read 'file.txt'");
else std::cout << "'file.txt': " << *content << std::endl; else
std::cout << "'file.txt': " << *content << std::endl;
std::cout << "Making directory 'dir2': " << std::boolalpha std::cout << "Making directory 'dir2': " << std::boolalpha
<< Helper::makeDirectory(test_path("dir2")) << std::endl; << Helper::makeDirectory(test_path("dir2")) << std::endl;
@@ -78,9 +80,10 @@ int main(int argc, char **argv) {
std::cout << "Read link of 'file2lnk.txt': " std::cout << "Read link of 'file2lnk.txt': "
<< Helper::readSymlink(test_path("file2lnk.txt")) << std::endl; << Helper::readSymlink(test_path("file2lnk.txt")) << std::endl;
auto sha256 = Helper::sha256Of(test_path("file2.txt")); if (const auto sha256 = Helper::sha256Of(test_path("file2.txt")); !sha256)
if (!sha256) throw Helper::Error("Cannot get sha256 of 'file2.txt'"); throw Helper::Error("Cannot get sha256 of 'file2.txt'");
else std::cout << "SHA256 of 'file2.txt': " << *sha256 << std::endl; else
std::cout << "SHA256 of 'file2.txt': " << *sha256 << std::endl;
std::cout << "'file2.txt' and 'file2lnk.txt' same? (SHA256): " std::cout << "'file2.txt' and 'file2lnk.txt' same? (SHA256): "
<< std::boolalpha << std::boolalpha
@@ -95,7 +98,7 @@ int main(int argc, char **argv) {
<< Helper::runCommand("ls") << std::endl; << Helper::runCommand("ls") << std::endl;
std::cout << "Spawn confirm propt..." << std::endl; std::cout << "Spawn confirm propt..." << std::endl;
bool p = Helper::confirmPropt("Please answer"); const bool p = Helper::confirmPropt("Please answer");
std::cout << "Result of confirm propt: " << std::boolalpha << p std::cout << "Result of confirm propt: " << std::boolalpha << p
<< std::endl; << std::endl;
@@ -104,7 +107,7 @@ int main(int argc, char **argv) {
std::cout << "Current date: " << Helper::currentDate() << std::endl; std::cout << "Current date: " << Helper::currentDate() << std::endl;
std::cout << "Current time: " << Helper::currentTime() << std::endl; std::cout << "Current time: " << Helper::currentTime() << std::endl;
std::cout << "Output of 'ls' command: " std::cout << "Output of 'ls' command: "
<< Helper::runCommandWithOutput("ls") << std::endl; << Helper::runCommandWithOutput("ls").first << std::endl;
std::cout << "Basename of " << test_path("file2.txt") << ": " std::cout << "Basename of " << test_path("file2.txt") << ": "
<< Helper::pathBasename(test_path("file2.txt")) << std::endl; << Helper::pathBasename(test_path("file2.txt")) << std::endl;
std::cout << "Dirname of " << test_path("file2.txt") << ": " std::cout << "Dirname of " << test_path("file2.txt") << ": "
@@ -119,13 +122,29 @@ int main(int argc, char **argv) {
std::cout << "pathJoin() test 4: " << Helper::pathJoin("mydir", "/dir2") std::cout << "pathJoin() test 4: " << Helper::pathJoin("mydir", "/dir2")
<< std::endl; << std::endl;
Helper::PureTuple<int, std::string, bool> values = {
{1, "hi", true}, {2, "im", true}, {3, "helper", false}};
values.insert(std::make_tuple(0, "hi", false));
values.insert(2, "im", true);
values.insert({3, "helper", true});
values.pop({3, "helper", true});
values.pop_back();
std::cout << "pure tuple test: " << std::boolalpha
<< static_cast<bool>(values.at(0)) << std::endl;
for (const auto& [x, y, z] : values) {
std::cout << std::boolalpha << "(" << x << ", " << y << ", " << z << ")"
<< std::endl;
}
std::cout << Helper::getLibVersion() << std::endl; std::cout << Helper::getLibVersion() << std::endl;
LOG(INFO) << "Info message" << std::endl; LOG(INFO) << "Info message" << std::endl;
LOG(WARNING) << "Warning message" << std::endl; LOG(WARNING) << "Warning message" << std::endl;
LOG(ERROR) << "Error message" << std::endl; LOG(ERROR) << "Error message" << std::endl;
LOG(ABORT) << "Abort message" << std::endl; LOG(ABORT) << "Abort message" << std::endl;
} catch (Helper::Error &err) { } catch (std::exception& err) {
std::cout << err.what() << std::endl; std::cout << err.what() << std::endl;
return 1; return 1;
} }

View File

@@ -17,16 +17,17 @@
#ifndef LIBPARTITION_MAP_LIB_HPP #ifndef LIBPARTITION_MAP_LIB_HPP
#define LIBPARTITION_MAP_LIB_HPP #define LIBPARTITION_MAP_LIB_HPP
#include <cstdint> // for uint64_t #include <cstdint> // for uint64_t
#include <exception> #include <exception>
#include <functional>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <list> #include <list>
#include <map>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <unordered_map> #include <utility> // for std::pair
#include <utility> // for std::pair
namespace PartitionMap { namespace PartitionMap {
struct _entry { struct _entry {
@@ -38,77 +39,86 @@ struct _entry {
} props; } props;
}; };
struct _returnable_entry {
uint64_t size;
bool isLogical;
};
using BasicInf = _returnable_entry;
using Info = _entry;
/** /**
* The main type of the library. The Builder class is designed * The main type of the library. The Builder class is designed
* to be easily manipulated and modified only on this class. * to be easily manipulated and modified only on this class.
*/ */
class basic_partition_map { class basic_partition_map {
private: private:
void _resize_map(); void _resize_map();
[[nodiscard]] int _index_of(std::string_view name) const; [[nodiscard]] int _index_of(std::string_view name) const;
public: public:
_entry *_data; _entry* _data;
size_t _count{}, _capacity{}; size_t _count{}, _capacity{};
struct _returnable_entry { basic_partition_map(const std::string& name, uint64_t size, bool logical);
uint64_t size; basic_partition_map(const basic_partition_map& other);
bool isLogical; basic_partition_map(basic_partition_map&& other) noexcept;
};
using BasicInf = _returnable_entry;
basic_partition_map(const std::string &name, uint64_t size, bool logical);
basic_partition_map(const basic_partition_map &other);
basic_partition_map(); basic_partition_map();
~basic_partition_map(); ~basic_partition_map();
bool insert(const std::string &name, uint64_t size, bool logical); bool insert(const std::string& name, uint64_t size, bool logical);
void merge(const basic_partition_map &map); void merge(const basic_partition_map& map);
void clear(); void clear();
[[nodiscard]] uint64_t get_size(std::string_view name) const; [[nodiscard]] uint64_t get_size(std::string_view name) const;
[[nodiscard]] bool is_logical(std::string_view name) const; [[nodiscard]] bool is_logical(std::string_view name) const;
[[nodiscard]] _returnable_entry get_all(std::string_view name) const; [[nodiscard]] _returnable_entry get_all(std::string_view name) const;
[[nodiscard]] bool find(std::string_view name) const; [[nodiscard]] bool find(std::string_view name) const;
[[nodiscard]] std::string find_(const std::string &name) const; [[nodiscard]] std::string find_(const std::string& name) const;
[[nodiscard]] size_t size() const; [[nodiscard]] size_t size() const;
[[nodiscard]] bool empty() const; [[nodiscard]] bool empty() const;
basic_partition_map &operator=(const basic_partition_map &map); basic_partition_map& operator=(const basic_partition_map& map);
bool operator==(const basic_partition_map &other) const; bool operator==(const basic_partition_map& other) const;
bool operator!=(const basic_partition_map &other) const; bool operator!=(const basic_partition_map& other) const;
bool operator!() const;
explicit operator bool() const;
Info operator[](int index) const;
BasicInf operator[](const std::string_view& name) const;
explicit operator std::vector<Info>() const;
explicit operator int() const;
class iterator { class iterator {
public: public:
_entry *ptr; _entry* ptr;
explicit iterator(_entry *p); explicit iterator(_entry* p);
auto operator*() const auto operator*() const -> std::pair<std::string&, decltype(_entry::props)&>;
-> std::pair<std::string &, decltype(_entry::props) &>; _entry* operator->() const;
_entry *operator->() const; iterator& operator++();
iterator &operator++();
iterator operator++(int); iterator operator++(int);
bool operator!=(const iterator &other) const; bool operator!=(const iterator& other) const;
bool operator==(const iterator &other) const; bool operator==(const iterator& other) const;
}; };
class constant_iterator { class constant_iterator {
public: public:
const _entry *ptr; const _entry* ptr;
explicit constant_iterator(const _entry *p); explicit constant_iterator(const _entry* p);
auto operator*() const auto operator*() const
-> std::pair<const std::string &, const decltype(_entry::props) &>; -> std::pair<const std::string&, const decltype(_entry::props)&>;
const _entry *operator->() const; const _entry* operator->() const;
constant_iterator &operator++(); constant_iterator& operator++();
constant_iterator operator++(int); constant_iterator operator++(int);
bool operator!=(const constant_iterator &other) const; bool operator!=(const constant_iterator& other) const;
bool operator==(const constant_iterator &other) const; bool operator==(const constant_iterator& other) const;
}; };
/* for-each support */ /* for-each support */
@@ -122,20 +132,20 @@ using Partition_t = _entry;
using Map_t = basic_partition_map; using Map_t = basic_partition_map;
class basic_partition_map_builder final { class basic_partition_map_builder final {
private: private:
Map_t _current_map; Map_t _current_map;
std::string _workdir; std::string _workdir;
bool _any_generating_error, _map_builded; bool _any_generating_error, _map_builded;
Map_t _build_map(std::string_view path, bool logical = false); Map_t _build_map(std::string_view path, bool logical = false);
void _insert_logicals(Map_t &&logicals); void _insert_logicals(Map_t&& logicals);
void _map_build_check() const; void _map_build_check() const;
[[nodiscard]] static bool _is_real_block_dir(std::string_view path); [[nodiscard]] static bool _is_real_block_dir(std::string_view path);
[[nodiscard]] uint64_t _get_size(const std::string &path); [[nodiscard]] uint64_t _get_size(const std::string& path);
public: public:
/** /**
* By default, it searches the directories in the * By default, it searches the directories in the
* defaultEntryList in PartitionMap.cpp in order and * defaultEntryList in PartitionMap.cpp in order and
@@ -148,9 +158,13 @@ public:
*/ */
explicit basic_partition_map_builder(std::string_view path); explicit basic_partition_map_builder(std::string_view path);
/**
* Move constructor
*/
basic_partition_map_builder(basic_partition_map_builder&& other) noexcept;
/** /**
* Returns the current list content in Map_t type. * Returns the current list content in Map_t type.
* If no list is created, returns std::nullopt.
*/ */
[[nodiscard]] Map_t getAll() const; [[nodiscard]] Map_t getAll() const;
@@ -159,8 +173,8 @@ public:
* Map_temp_t type. If the partition is not in the * Map_temp_t type. If the partition is not in the
* currently created list, returns std::nullopt. * currently created list, returns std::nullopt.
*/ */
[[nodiscard]] std::optional<std::pair<uint64_t, bool>> [[nodiscard]] std::optional<std::pair<uint64_t, bool>> get(
get(std::string_view name) const; std::string_view name) const;
/** /**
* If there is a logical partition(s) in the created * If there is a logical partition(s) in the created
@@ -168,16 +182,16 @@ public:
* data of type std::string). If there is no logical * data of type std::string). If there is no logical
* partition in the created list, it returns std::nullopt. * partition in the created list, it returns std::nullopt.
*/ */
[[nodiscard]] std::optional<std::list<std::string>> [[nodiscard]] std::optional<std::list<std::string>> getLogicalPartitionList()
getLogicalPartitionList() const; const;
/** /**
* The physical partitions in the created list are * The physical partitions in the created list are
* returned as std::list type. If there is no content * returned as std::list type. If there is no content
* due to any problem, returns std::nullopt. * due to any problem, returns std::nullopt.
*/ */
[[nodiscard]] std::optional<std::list<std::string>> [[nodiscard]] std::optional<std::list<std::string>> getPhysicalPartitionList()
getPhysicalPartitionList() const; const;
/** /**
* The partitions in the created list are returned as std::list * The partitions in the created list are returned as std::list
@@ -212,6 +226,11 @@ public:
*/ */
[[nodiscard]] bool hasPartition(std::string_view name) const; [[nodiscard]] bool hasPartition(std::string_view name) const;
/**
* Returns true if the device has dynamic partitions, false otherwise.
*/
[[nodiscard]] bool hasLogicalPartitions() const;
/** /**
* Returns the bool type status of whether the * Returns the bool type status of whether the
* entered partition name is marked as logical in the * entered partition name is marked as logical in the
@@ -221,11 +240,51 @@ public:
*/ */
[[nodiscard]] bool isLogical(std::string_view name) const; [[nodiscard]] bool isLogical(std::string_view name) const;
/**
* Copy partition list to vec, current vec contents are cleaned
*/
bool copyPartitionsToVector(std::vector<std::string>& vec) const;
/**
* Copy logical partition list to vec, current vec contents are cleaned
*/
bool copyLogicalPartitionsToVector(std::vector<std::string>& vec) const;
/**
* Copy physical partition list to vec, current vec contents are cleaned
*/
bool copyPhysicalPartitionsToVector(std::vector<std::string>& vec) const;
/** /**
* The created list and the current search index name are cleared. * The created list and the current search index name are cleared.
*/ */
void clear(); void clear();
/**
* Do input function (lambda) for all partitions.
*/
bool doForAllPartitions(
const std::function<bool(std::string, BasicInf)>& func) const;
/**
* Do input function (lambda) for physical partitions.
*/
bool doForPhysicalPartitions(
const std::function<bool(std::string, BasicInf)>& func) const;
/**
* Do input function (lambda) for logical partitions.
*/
bool doForLogicalPartitions(
const std::function<bool(std::string, BasicInf)>& func) const;
/**
* Do input function (lambda) for input partition list.
*/
bool doForPartitionList(
const std::vector<std::string>& partitions,
const std::function<bool(std::string, BasicInf)>& func) const;
/** /**
* The entered path is defined as the new search * The entered path is defined as the new search
* directory and the search is performed in the entered * directory and the search is performed in the entered
@@ -257,14 +316,14 @@ public:
* the same (checked only according to the partition * the same (checked only according to the partition
* names), true is returned, otherwise false is returned * names), true is returned, otherwise false is returned
*/ */
friend bool operator==(const basic_partition_map_builder &lhs, friend bool operator==(const basic_partition_map_builder& lhs,
const basic_partition_map_builder &rhs); const basic_partition_map_builder& rhs);
/** /**
* The opposite logic of the == operator. * The opposite logic of the == operator.
*/ */
friend bool operator!=(const basic_partition_map_builder &lhs, friend bool operator!=(const basic_partition_map_builder& lhs,
const basic_partition_map_builder &rhs); const basic_partition_map_builder& rhs);
/** /**
* You can check whether the object was created * You can check whether the object was created
@@ -287,8 +346,37 @@ public:
/** /**
* Get Map_t object reference * Get Map_t object reference
*/ */
Map_t &operator*(); Map_t& operator*();
const Map_t &operator*() const;
/**
* Get constant Map_t object reference
*/
const Map_t& operator*() const;
/**
* Get Info structure with given index
*/
Info operator[](int index) const;
/**
* Get BasicInfo structure with given index
*/
BasicInf operator[](const std::string_view& name) const;
/**
* Get map contents as vector (PartitionManager::Info type).
*/
[[nodiscard]] explicit operator std::vector<Info>() const;
/**
* Get total partition count in map (int type).
*/
[[nodiscard]] explicit operator int() const;
/**
* Get current working directory.
*/
[[nodiscard]] explicit operator std::string() const;
}; };
using Error = Helper::Error; using Error = Helper::Error;
@@ -313,7 +401,7 @@ constexpr uint64_t FAT16_FS = 0x3631544146;
constexpr uint64_t FAT32_FS = 0x3233544146; constexpr uint64_t FAT32_FS = 0x3233544146;
constexpr uint64_t NTFS_FS = 0x5346544E; constexpr uint64_t NTFS_FS = 0x5346544E;
constexpr uint64_t MSDOS_FS = 0x4d44; constexpr uint64_t MSDOS_FS = 0x4d44;
} // namespace FileSystemMagic } // namespace FileSystemMagic
namespace AndroidMagic { namespace AndroidMagic {
constexpr uint64_t BOOT_IMAGE = 0x2144494F52444E41; constexpr uint64_t BOOT_IMAGE = 0x2144494F52444E41;
@@ -324,20 +412,23 @@ constexpr uint64_t VBMETA_IMAGE = 0x425641;
constexpr uint64_t SUPER_IMAGE = 0x7265797573; constexpr uint64_t SUPER_IMAGE = 0x7265797573;
constexpr uint64_t SPARSE_IMAGE = 0x3AFF26ED; constexpr uint64_t SPARSE_IMAGE = 0x3AFF26ED;
constexpr uint64_t ELF = constexpr uint64_t ELF =
0x464C457F; // It makes more sense than between file systems 0x464C457F; // It makes more sense than between file systems
constexpr uint64_t RAW = 0x00000000; constexpr uint64_t RAW = 0x00000000;
} // namespace AndroidMagic } // namespace AndroidMagic
extern std::unordered_map<uint64_t, std::string> FileSystemMagicMap; extern std::map<uint64_t, std::string> FileSystemMagicMap;
extern std::unordered_map<uint64_t, std::string> AndroidMagicMap; extern std::map<uint64_t, std::string> AndroidMagicMap;
extern std::unordered_map<uint64_t, std::string> MagicMap; extern std::map<uint64_t, std::string> MagicMap;
size_t getMagicLength(uint64_t magic); size_t getMagicLength(uint64_t magic);
bool hasMagic(uint64_t magic, ssize_t buf, const std::string &path); bool hasMagic(uint64_t magic, ssize_t buf, const std::string& path);
std::string formatMagic(uint64_t magic); std::string formatMagic(uint64_t magic);
} // namespace Extras } // namespace Extras
} // namespace PartitionMap } // namespace PartitionMap
#define MAP "libpartition_map" #define MAP "libpartition_map"
#endif // #ifndef LIBPARTITION_MAP_LIB_HPP #define COMMON_LAMBDA_PARAMS \
(const std::string& partition, const PartitionMap::BasicInf props)
#endif // #ifndef LIBPARTITION_MAP_LIB_HPP

View File

@@ -25,8 +25,8 @@ Map_t basic_partition_map_builder::getAll() const {
return _current_map; return _current_map;
} }
std::optional<std::pair<uint64_t, bool>> std::optional<std::pair<uint64_t, bool>> basic_partition_map_builder::get(
basic_partition_map_builder::get(const std::string_view name) const { const std::string_view name) const {
_map_build_check(); _map_build_check();
if (!_current_map.find(name)) return std::nullopt; if (!_current_map.find(name)) return std::nullopt;
@@ -39,7 +39,7 @@ basic_partition_map_builder::getLogicalPartitionList() const {
_map_build_check(); _map_build_check();
std::list<std::string> logicals; std::list<std::string> logicals;
for (const auto &[name, props] : _current_map) for (const auto& [name, props] : _current_map)
if (props.isLogical) logicals.push_back(name); if (props.isLogical) logicals.push_back(name);
if (logicals.empty()) return std::nullopt; if (logicals.empty()) return std::nullopt;
@@ -51,7 +51,7 @@ basic_partition_map_builder::getPhysicalPartitionList() const {
_map_build_check(); _map_build_check();
std::list<std::string> physicals; std::list<std::string> physicals;
for (const auto &[name, props] : _current_map) for (const auto& [name, props] : _current_map)
if (!props.isLogical) physicals.push_back(name); if (!props.isLogical) physicals.push_back(name);
if (physicals.empty()) return std::nullopt; if (physicals.empty()) return std::nullopt;
@@ -63,8 +63,7 @@ basic_partition_map_builder::getPartitionList() const {
_map_build_check(); _map_build_check();
std::list<std::string> partitions; std::list<std::string> partitions;
for (const auto &[name, props] : _current_map) for (const auto& [name, props] : _current_map) partitions.push_back(name);
partitions.push_back(name);
if (partitions.empty()) return std::nullopt; if (partitions.empty()) return std::nullopt;
return partitions; return partitions;
@@ -78,8 +77,8 @@ std::string basic_partition_map_builder::getRealLinkPathOf(
return std::string(_workdir + "/" + name.data()); return std::string(_workdir + "/" + name.data());
} }
std::string std::string basic_partition_map_builder::getRealPathOf(
basic_partition_map_builder::getRealPathOf(const std::string_view name) const { const std::string_view name) const {
_map_build_check(); _map_build_check();
const std::string full = (isLogical(name)) const std::string full = (isLogical(name))
@@ -93,4 +92,4 @@ basic_partition_map_builder::getRealPathOf(const std::string_view name) const {
std::string basic_partition_map_builder::getCurrentWorkDir() const { std::string basic_partition_map_builder::getCurrentWorkDir() const {
return _workdir; return _workdir;
} }
} // namespace PartitionMap } // namespace PartitionMap

View File

@@ -15,17 +15,18 @@
*/ */
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <libpartition_map/lib.hpp> #include <libpartition_map/lib.hpp>
#include <map>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <unistd.h>
#include <unordered_map>
#include "PartitionManager/PartitionManager.hpp" #include "PartitionManager/PartitionManager.hpp"
namespace PartitionMap::Extras { namespace PartitionMap::Extras {
std::unordered_map<uint64_t, std::string> FileSystemMagicMap = { std::map<uint64_t, std::string> FileSystemMagicMap = {
{FileSystemMagic::EXTFS_FS, "EXT2/3/4"}, {FileSystemMagic::EXTFS_FS, "EXT2/3/4"},
{FileSystemMagic::F2FS_FS, "F2FS"}, {FileSystemMagic::F2FS_FS, "F2FS"},
{FileSystemMagic::EROFS_FS, "EROFS"}, {FileSystemMagic::EROFS_FS, "EROFS"},
@@ -36,7 +37,7 @@ std::unordered_map<uint64_t, std::string> FileSystemMagicMap = {
{FileSystemMagic::NTFS_FS, "NTFS"}, {FileSystemMagic::NTFS_FS, "NTFS"},
{FileSystemMagic::MSDOS_FS, "MSDOS"}}; {FileSystemMagic::MSDOS_FS, "MSDOS"}};
std::unordered_map<uint64_t, std::string> AndroidMagicMap = { std::map<uint64_t, std::string> AndroidMagicMap = {
{AndroidMagic::BOOT_IMAGE, "Android Boot Image"}, {AndroidMagic::BOOT_IMAGE, "Android Boot Image"},
{AndroidMagic::VBOOT_IMAGE, "Android Vendor Boot Image"}, {AndroidMagic::VBOOT_IMAGE, "Android Vendor Boot Image"},
{AndroidMagic::LK_IMAGE, "Android LK (Bootloader)"}, {AndroidMagic::LK_IMAGE, "Android LK (Bootloader)"},
@@ -47,7 +48,7 @@ std::unordered_map<uint64_t, std::string> AndroidMagicMap = {
{AndroidMagic::ELF, "ELF"}, {AndroidMagic::ELF, "ELF"},
{AndroidMagic::RAW, "Raw Data"}}; {AndroidMagic::RAW, "Raw Data"}};
std::unordered_map<uint64_t, std::string> MagicMap = { std::map<uint64_t, std::string> MagicMap = {
{AndroidMagic::BOOT_IMAGE, "Android Boot Image"}, {AndroidMagic::BOOT_IMAGE, "Android Boot Image"},
{AndroidMagic::VBOOT_IMAGE, "Android Vendor Boot Image"}, {AndroidMagic::VBOOT_IMAGE, "Android Vendor Boot Image"},
{AndroidMagic::LK_IMAGE, "Android LK (Bootloader)"}, {AndroidMagic::LK_IMAGE, "Android LK (Bootloader)"},
@@ -76,7 +77,7 @@ size_t getMagicLength(const uint64_t magic) {
} }
bool hasMagic(const uint64_t magic, const ssize_t buf, bool hasMagic(const uint64_t magic, const ssize_t buf,
const std::string &path) { const std::string& path) {
LOGN(MAP, INFO) << "Checking magic of " << path << " with using " << buf LOGN(MAP, INFO) << "Checking magic of " << path << " with using " << buf
<< " byte buffer size (has magic 0x" << std::hex << magic << " byte buffer size (has magic 0x" << std::hex << magic
<< "?)" << std::endl; << "?)" << std::endl;
@@ -89,7 +90,7 @@ bool hasMagic(const uint64_t magic, const ssize_t buf,
return false; return false;
} }
auto *buffer = new (std::nothrow) uint8_t[buf]; auto* buffer = new (std::nothrow) uint8_t[buf];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
const ssize_t bytesRead = read(fd, buffer, buf); const ssize_t bytesRead = read(fd, buffer, buf);
@@ -120,4 +121,4 @@ std::string formatMagic(const uint64_t magic) {
<< magic; << magic;
return ss.str(); return ss.str();
} }
} // namespace PartitionMap::Extras } // namespace PartitionMap::Extras

View File

@@ -14,22 +14,26 @@
limitations under the License. limitations under the License.
*/ */
#include <fcntl.h>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
#include <fcntl.h>
#include <filesystem> #include <filesystem>
#ifndef ANDROID_BUILD
#include <generated/buildInfo.hpp> #include <generated/buildInfo.hpp>
#include <iostream> #endif
#include <libpartition_map/lib.hpp>
#include <linux/fs.h> #include <linux/fs.h>
#include <memory>
#include <string>
#include <string_view>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <iostream>
#include <libpartition_map/lib.hpp>
#include <memory>
#include <string>
#include <string_view>
#include <vector> #include <vector>
static constexpr std::array<std::string_view, 3> defaultEntryList = { static constexpr std::array<std::string_view, 3> defaultEntryList = {
@@ -48,20 +52,26 @@ bool basic_partition_map_builder::_is_real_block_dir(
Map_t basic_partition_map_builder::_build_map(std::string_view path, Map_t basic_partition_map_builder::_build_map(std::string_view path,
const bool logical) { const bool logical) {
if (!Helper::directoryIsExists(path) && logical) {
LOGN(MAP, WARNING) << "This device not contains logical partitions."
<< std::endl;
return {};
}
Map_t map; Map_t map;
std::vector<std::filesystem::directory_entry> entries{ std::vector<std::filesystem::directory_entry> entries{
std::filesystem::directory_iterator(path), std::filesystem::directory_iterator(path),
std::filesystem::directory_iterator()}; std::filesystem::directory_iterator()};
std::sort(entries.begin(), entries.end(), [](const auto &a, const auto &b) { std::sort(entries.begin(), entries.end(), [](const auto& a, const auto& b) {
return a.path().filename() < b.path().filename(); return a.path().filename() < b.path().filename();
}); });
LOGN_IF(MAP, WARNING, entries.empty()) LOGN_IF(MAP, WARNING, entries.empty())
<< "" << path << path
<< "is exists but generated vector is empty " << " is exists but generated vector is empty "
"(std::vector<std::filesystem::directory_entry>)." "(std::vector<std::filesystem::directory_entry>)."
<< std::endl; << std::endl;
for (const auto &entry : entries) { for (const auto& entry : entries) {
if (entry.path().filename() != "by-uuid" && if (entry.path().filename() != "by-uuid" &&
std::string(entry.path()).find("com.") == std::string::npos) std::string(entry.path()).find("com.") == std::string::npos)
map.insert(entry.path().filename().string(), _get_size(entry.path()), map.insert(entry.path().filename().string(), _get_size(entry.path()),
@@ -74,18 +84,21 @@ Map_t basic_partition_map_builder::_build_map(std::string_view path,
return map; return map;
} }
void basic_partition_map_builder::_insert_logicals(Map_t &&logicals) { void basic_partition_map_builder::_insert_logicals(Map_t&& logicals) {
LOGN(MAP, INFO) LOGN(MAP, INFO)
<< "merging created logical partition list to this object's variable." << "merging created logical partition list to this object's variable."
<< std::endl; << std::endl;
_current_map.merge(logicals); _current_map.merge(logicals);
LOGN(MAP, INFO) << "Cleaning created logical partition because not need more."
<< std::endl;
logicals.clear();
} }
void basic_partition_map_builder::_map_build_check() const { void basic_partition_map_builder::_map_build_check() const {
if (!_map_builded) throw Error("Please build partition map before!"); if (!_map_builded) throw Error("Please build partition map before!");
} }
uint64_t basic_partition_map_builder::_get_size(const std::string &path) { uint64_t basic_partition_map_builder::_get_size(const std::string& path) {
const std::string real = std::filesystem::read_symlink(path); const std::string real = std::filesystem::read_symlink(path);
Helper::garbageCollector collector; Helper::garbageCollector collector;
@@ -109,7 +122,7 @@ uint64_t basic_partition_map_builder::_get_size(const std::string &path) {
basic_partition_map_builder::basic_partition_map_builder() { basic_partition_map_builder::basic_partition_map_builder() {
LOGN(MAP, INFO) << "default constructor called. Starting build." << std::endl; LOGN(MAP, INFO) << "default constructor called. Starting build." << std::endl;
for (const auto &path : defaultEntryList) { for (const auto& path : defaultEntryList) {
if (std::filesystem::exists(path)) { if (std::filesystem::exists(path)) {
_current_map = _build_map(path); _current_map = _build_map(path);
if (_current_map.empty()) { if (_current_map.empty()) {
@@ -125,8 +138,7 @@ basic_partition_map_builder::basic_partition_map_builder() {
LOGN(MAP, ERROR) << "Cannot build map by any default search entry." LOGN(MAP, ERROR) << "Cannot build map by any default search entry."
<< std::endl; << std::endl;
LOGN(MAP, INFO) << "default constructor successfully ended work." LOGN(MAP, INFO) << "default constructor ended work." << std::endl;
<< std::endl;
_insert_logicals(_build_map("/dev/block/mapper", true)); _insert_logicals(_build_map("/dev/block/mapper", true));
_map_builded = true; _map_builded = true;
} }
@@ -139,8 +151,10 @@ basic_partition_map_builder::basic_partition_map_builder(
if (std::filesystem::exists(path)) { if (std::filesystem::exists(path)) {
if (!_is_real_block_dir(path)) return; if (!_is_real_block_dir(path)) return;
_current_map = _build_map(path); _current_map = _build_map(path);
if (_current_map.empty()) _any_generating_error = true; if (_current_map.empty())
else _workdir = path; _any_generating_error = true;
else
_workdir = path;
} else } else
throw Error("Cannot find directory: %s. Cannot build partition map!", throw Error("Cannot find directory: %s. Cannot build partition map!",
path.data()); path.data());
@@ -151,12 +165,29 @@ basic_partition_map_builder::basic_partition_map_builder(
_map_builded = true; _map_builded = true;
} }
basic_partition_map_builder::basic_partition_map_builder(
basic_partition_map_builder&& other) noexcept {
_current_map = Map_t(std::move(other._current_map));
_workdir = std::move(other._workdir);
_any_generating_error = other._any_generating_error;
_map_builded = other._map_builded;
other.clear();
}
bool basic_partition_map_builder::hasPartition( bool basic_partition_map_builder::hasPartition(
const std::string_view name) const { const std::string_view name) const {
_map_build_check(); _map_build_check();
return _current_map.find(name); return _current_map.find(name);
} }
bool basic_partition_map_builder::hasLogicalPartitions() const {
_map_build_check();
for (const auto& [name, props] : _current_map)
if (props.isLogical) return true;
return false;
}
bool basic_partition_map_builder::isLogical(const std::string_view name) const { bool basic_partition_map_builder::isLogical(const std::string_view name) const {
_map_build_check(); _map_build_check();
return _current_map.is_logical(name); return _current_map.is_logical(name);
@@ -178,12 +209,13 @@ bool basic_partition_map_builder::readDirectory(const std::string_view path) {
if (_current_map.empty()) { if (_current_map.empty()) {
_any_generating_error = true; _any_generating_error = true;
return false; return false;
} else _workdir = path; } else
_workdir = path;
} else } else
throw Error("Cannot find directory: %s. Cannot build partition map!", throw Error("Cannot find directory: %s. Cannot build partition map!",
path.data()); path.data());
LOGN(MAP, INFO) << "read " << path << " successfull." << std::endl; LOGN(MAP, INFO) << "read " << path << " successfully." << std::endl;
_insert_logicals(_build_map("/dev/block/mapper", true)); _insert_logicals(_build_map("/dev/block/mapper", true));
_map_builded = true; _map_builded = true;
return true; return true;
@@ -193,7 +225,7 @@ bool basic_partition_map_builder::readDefaultDirectories() {
_map_builded = false; _map_builded = false;
LOGN(MAP, INFO) << "read default directories request." << std::endl; LOGN(MAP, INFO) << "read default directories request." << std::endl;
for (const auto &path : defaultEntryList) { for (const auto& path : defaultEntryList) {
if (std::filesystem::exists(path)) { if (std::filesystem::exists(path)) {
_current_map = _build_map(path); _current_map = _build_map(path);
if (_current_map.empty()) { if (_current_map.empty()) {
@@ -210,30 +242,162 @@ bool basic_partition_map_builder::readDefaultDirectories() {
LOGN(MAP, ERROR) << "Cannot build map by any default search entry." LOGN(MAP, ERROR) << "Cannot build map by any default search entry."
<< std::endl; << std::endl;
LOGN(MAP, INFO) << "read default directories successfull." << std::endl; LOGN(MAP, INFO) << "read default directories successfully." << std::endl;
_insert_logicals(_build_map("/dev/block/mapper", true)); _insert_logicals(_build_map("/dev/block/mapper", true));
_map_builded = true; _map_builded = true;
return true; return true;
} }
bool basic_partition_map_builder::copyPartitionsToVector(
std::vector<std::string>& vec) const {
if (_current_map.empty()) {
LOGN(MAP, ERROR) << "Current map is empty.";
return false;
}
vec.clear();
for (const auto& [name, props] : _current_map) vec.push_back(name);
return true;
}
bool basic_partition_map_builder::copyLogicalPartitionsToVector(
std::vector<std::string>& vec) const {
if (_current_map.empty()) {
LOGN(MAP, ERROR) << "Current map is empty.";
return false;
}
std::vector<std::string> vec2;
for (const auto& [name, props] : _current_map)
if (props.isLogical) vec2.push_back(name);
if (vec2.empty()) {
LOGN(MAP, ERROR) << "Cannot find logical partitions in current map.";
return false;
} else
vec = vec2;
return true;
}
bool basic_partition_map_builder::copyPhysicalPartitionsToVector(
std::vector<std::string>& vec) const {
if (_current_map.empty()) {
LOGN(MAP, ERROR) << "Current map is empty.";
return false;
}
std::vector<std::string> vec2;
for (const auto& [name, props] : _current_map)
if (!props.isLogical) vec2.push_back(name);
if (vec2.empty()) {
LOGN(MAP, ERROR) << "Cannot find physical partitions in current map.";
return false;
} else
vec = vec2;
return true;
}
bool basic_partition_map_builder::empty() const { bool basic_partition_map_builder::empty() const {
_map_build_check(); _map_build_check();
return _current_map.empty(); return _current_map.empty();
} }
uint64_t bool basic_partition_map_builder::doForAllPartitions(
basic_partition_map_builder::sizeOf(const std::string_view name) const { const std::function<bool(std::string, BasicInf)>& func) const {
_map_build_check();
bool err = false;
LOGN(MAP, INFO) << "Doing input function for all partitions." << std::endl;
for (const auto& [name, props] : _current_map) {
if (func(name, {props.size, props.isLogical}))
LOGN(MAP, INFO) << "Done progress for " << name << " partition."
<< std::endl;
else {
err = true;
LOGN(MAP, ERROR) << "Failed progress for " << name << " partition."
<< std::endl;
}
}
return err;
}
bool basic_partition_map_builder::doForPhysicalPartitions(
const std::function<bool(std::string, BasicInf)>& func) const {
_map_build_check();
bool err = false;
LOGN(MAP, INFO) << "Doing input function for physical partitions."
<< std::endl;
for (const auto& [name, props] : _current_map) {
if (props.isLogical) continue;
if (func(name, {props.size, props.isLogical}))
LOGN(MAP, INFO) << "Done progress for " << name << " partition."
<< std::endl;
else {
err = true;
LOGN(MAP, ERROR) << "Failed progress for " << name << " partition."
<< std::endl;
}
}
return err;
}
bool basic_partition_map_builder::doForLogicalPartitions(
const std::function<bool(std::string, BasicInf)>& func) const {
_map_build_check();
bool err = false;
LOGN(MAP, INFO) << "Doing input function for logical partitions."
<< std::endl;
for (const auto& [name, props] : _current_map) {
if (!props.isLogical) continue;
if (func(name, {props.size, props.isLogical}))
LOGN(MAP, INFO) << "Done progress for " << name << " partition."
<< std::endl;
else {
err = true;
LOGN(MAP, ERROR) << "Failed progress for " << name << " partition."
<< std::endl;
}
}
return err;
}
bool basic_partition_map_builder::doForPartitionList(
const std::vector<std::string>& partitions,
const std::function<bool(std::string, BasicInf)>& func) const {
_map_build_check();
bool err = false;
LOGN(MAP, INFO) << "Doing input function for input partition list."
<< std::endl;
for (const auto& partition : partitions) {
if (!hasPartition(partition))
throw Error("Couldn't find partition: %s", partition.data());
if (!func(partition, _current_map[partition])) {
err = true;
LOGN(MAP, ERROR) << "Failed progress for " << partition << " partition."
<< std::endl;
}
}
return err;
}
uint64_t basic_partition_map_builder::sizeOf(
const std::string_view name) const {
_map_build_check(); _map_build_check();
return _current_map.get_size(name); return _current_map.get_size(name);
} }
bool operator==(const basic_partition_map_builder &lhs, bool operator==(const basic_partition_map_builder& lhs,
const basic_partition_map_builder &rhs) { const basic_partition_map_builder& rhs) {
return lhs._current_map == rhs._current_map; return lhs._current_map == rhs._current_map;
} }
bool operator!=(const basic_partition_map_builder &lhs, bool operator!=(const basic_partition_map_builder& lhs,
const basic_partition_map_builder &rhs) { const basic_partition_map_builder& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
@@ -251,11 +415,30 @@ bool basic_partition_map_builder::operator()(const std::string_view path) {
return readDirectory(path); return readDirectory(path);
} }
Map_t &basic_partition_map_builder::operator*() { return _current_map; } Map_t& basic_partition_map_builder::operator*() { return _current_map; }
const Map_t &basic_partition_map_builder::operator*() const { const Map_t& basic_partition_map_builder::operator*() const {
return _current_map; return _current_map;
} }
Info basic_partition_map_builder::operator[](const int index) const {
return _current_map[index];
}
BasicInf basic_partition_map_builder::operator[](
const std::string_view& name) const {
return _current_map[name];
}
basic_partition_map_builder::operator std::vector<Info>() const {
return static_cast<std::vector<Info>>(_current_map);
}
basic_partition_map_builder::operator int() const {
return static_cast<int>(_current_map);
}
basic_partition_map_builder::operator std::string() const { return _workdir; }
std::string getLibVersion() { MKVERSION("libpartition_map"); } std::string getLibVersion() { MKVERSION("libpartition_map"); }
} // namespace PartitionMap } // namespace PartitionMap

View File

@@ -20,16 +20,16 @@
#include <utility> #include <utility>
namespace PartitionMap { namespace PartitionMap {
basic_partition_map::iterator::iterator(_entry *p) : ptr(p) {} basic_partition_map::iterator::iterator(_entry* p) : ptr(p) {}
auto basic_partition_map::iterator::operator*() const auto basic_partition_map::iterator::operator*() const
-> std::pair<std::string &, decltype(_entry::props) &> { -> std::pair<std::string&, decltype(_entry::props)&> {
return {ptr->name, ptr->props}; return {ptr->name, ptr->props};
} }
_entry *basic_partition_map::iterator::operator->() const { return ptr; } _entry* basic_partition_map::iterator::operator->() const { return ptr; }
basic_partition_map::iterator &basic_partition_map::iterator::operator++() { basic_partition_map::iterator& basic_partition_map::iterator::operator++() {
++ptr; ++ptr;
return *this; return *this;
} }
@@ -40,27 +40,27 @@ basic_partition_map::iterator basic_partition_map::iterator::operator++(int) {
return tmp; return tmp;
} }
bool basic_partition_map::iterator::operator==(const iterator &other) const { bool basic_partition_map::iterator::operator==(const iterator& other) const {
return ptr == other.ptr; return ptr == other.ptr;
} }
bool basic_partition_map::iterator::operator!=(const iterator &other) const { bool basic_partition_map::iterator::operator!=(const iterator& other) const {
return ptr != other.ptr; return ptr != other.ptr;
} }
basic_partition_map::constant_iterator::constant_iterator(const _entry *p) basic_partition_map::constant_iterator::constant_iterator(const _entry* p)
: ptr(p) {} : ptr(p) {}
auto basic_partition_map::constant_iterator::operator*() const auto basic_partition_map::constant_iterator::operator*() const
-> std::pair<const std::string &, const decltype(_entry::props) &> { -> std::pair<const std::string&, const decltype(_entry::props)&> {
return {ptr->name, ptr->props}; return {ptr->name, ptr->props};
} }
const _entry *basic_partition_map::constant_iterator::operator->() const { const _entry* basic_partition_map::constant_iterator::operator->() const {
return ptr; return ptr;
} }
basic_partition_map::constant_iterator & basic_partition_map::constant_iterator&
basic_partition_map::constant_iterator::operator++() { basic_partition_map::constant_iterator::operator++() {
++ptr; ++ptr;
return *this; return *this;
@@ -74,21 +74,20 @@ basic_partition_map::constant_iterator::operator++(int) {
} }
bool basic_partition_map::constant_iterator::operator==( bool basic_partition_map::constant_iterator::operator==(
const constant_iterator &other) const { const constant_iterator& other) const {
return ptr == other.ptr; return ptr == other.ptr;
} }
bool basic_partition_map::constant_iterator::operator!=( bool basic_partition_map::constant_iterator::operator!=(
const constant_iterator &other) const { const constant_iterator& other) const {
return ptr != other.ptr; return ptr != other.ptr;
} }
void basic_partition_map::_resize_map() { void basic_partition_map::_resize_map() {
const size_t new_capacity = _capacity * 2; const size_t new_capacity = _capacity * 2;
auto *new_data = new _entry[new_capacity]; auto* new_data = new _entry[new_capacity];
for (size_t i = 0; i < _count; i++) for (size_t i = 0; i < _count; i++) new_data[i] = _data[i];
new_data[i] = _data[i];
delete[] _data; delete[] _data;
_data = new_data; _data = new_data;
@@ -103,26 +102,35 @@ int basic_partition_map::_index_of(const std::string_view name) const {
return 0; return 0;
} }
basic_partition_map::basic_partition_map(const std::string &name, basic_partition_map::basic_partition_map(const std::string& name,
const uint64_t size, const uint64_t size,
const bool logical) { const bool logical) {
_data = new _entry[_capacity]; _data = new _entry[_capacity];
insert(name, size, logical); insert(name, size, logical);
} }
basic_partition_map::basic_partition_map(const basic_partition_map &other) basic_partition_map::basic_partition_map(const basic_partition_map& other)
: _data(new _entry[other._capacity]), _count(other._count), : _data(new _entry[other._capacity]),
_count(other._count),
_capacity(other._capacity) { _capacity(other._capacity) {
std::copy(other._data, other._data + _count, _data); std::copy(other._data, other._data + _count, _data);
} }
basic_partition_map::basic_partition_map(basic_partition_map&& other) noexcept
: _data(new _entry[other._capacity]),
_count(other._count),
_capacity(other._capacity) {
std::copy(other._data, other._data + _count, _data);
other.clear();
}
basic_partition_map::basic_partition_map() : _capacity(6) { basic_partition_map::basic_partition_map() : _capacity(6) {
_data = new _entry[_capacity]; _data = new _entry[_capacity];
} }
basic_partition_map::~basic_partition_map() { delete[] _data; } basic_partition_map::~basic_partition_map() { delete[] _data; }
bool basic_partition_map::insert(const std::string &name, const uint64_t size, bool basic_partition_map::insert(const std::string& name, const uint64_t size,
const bool logical) { const bool logical) {
if (name == _data[_index_of(name)].name) return false; if (name == _data[_index_of(name)].name) return false;
if (_count == _capacity) _resize_map(); if (_count == _capacity) _resize_map();
@@ -134,9 +142,9 @@ bool basic_partition_map::insert(const std::string &name, const uint64_t size,
return true; return true;
} }
void basic_partition_map::merge(const basic_partition_map &map) { void basic_partition_map::merge(const basic_partition_map& map) {
LOGN(MAP, INFO) << "map merge request." << std::endl; LOGN(MAP, INFO) << "map merge request." << std::endl;
for (const auto &[name, props] : map) for (const auto& [name, props] : map)
insert(name, props.size, props.isLogical); insert(name, props.size, props.isLogical);
LOGN(MAP, INFO) << "map merged successfully." << std::endl; LOGN(MAP, INFO) << "map merged successfully." << std::endl;
} }
@@ -155,8 +163,8 @@ bool basic_partition_map::is_logical(const std::string_view name) const {
return false; return false;
} }
basic_partition_map::_returnable_entry _returnable_entry basic_partition_map::get_all(
basic_partition_map::get_all(const std::string_view name) const { const std::string_view name) const {
if (const int pos = _index_of(name); name == _data[pos].name) if (const int pos = _index_of(name); name == _data[pos].name)
return _returnable_entry{_data[pos].props.size, _data[pos].props.isLogical}; return _returnable_entry{_data[pos].props.size, _data[pos].props.isLogical};
@@ -169,7 +177,7 @@ bool basic_partition_map::find(const std::string_view name) const {
return false; return false;
} }
std::string basic_partition_map::find_(const std::string &name) const { std::string basic_partition_map::find_(const std::string& name) const {
if (name == _data[_index_of(name)].name) return name; if (name == _data[_index_of(name)].name) return name;
return {}; return {};
@@ -177,21 +185,18 @@ std::string basic_partition_map::find_(const std::string &name) const {
size_t basic_partition_map::size() const { return _count; } size_t basic_partition_map::size() const { return _count; }
bool basic_partition_map::empty() const { bool basic_partition_map::empty() const { return _count == 0; }
if (_count > 0) return false;
return true;
}
void basic_partition_map::clear() { void basic_partition_map::clear() {
LOGN(MAP, INFO) << "map clean requested. Map is empty now." << std::endl; LOGN(MAP, INFO) << "map clean requested. Cleaning..." << std::endl;
delete[] _data; delete[] _data;
_count = 0; _count = 0;
_capacity = 6; _capacity = 6;
_data = new _entry[_capacity]; _data = new _entry[_capacity];
} }
basic_partition_map & basic_partition_map& basic_partition_map::operator=(
basic_partition_map::operator=(const basic_partition_map &map) { const basic_partition_map& map) {
if (this != &map) { if (this != &map) {
delete[] _data; delete[] _data;
@@ -204,7 +209,7 @@ basic_partition_map::operator=(const basic_partition_map &map) {
return *this; return *this;
} }
bool basic_partition_map::operator==(const basic_partition_map &other) const { bool basic_partition_map::operator==(const basic_partition_map& other) const {
if (this->_capacity != other._capacity || this->_count != other._count) if (this->_capacity != other._capacity || this->_count != other._count)
return false; return false;
@@ -213,15 +218,45 @@ bool basic_partition_map::operator==(const basic_partition_map &other) const {
_data[i].props.size == other._data[i].props.size && _data[i].props.size == other._data[i].props.size &&
_data[i].props.isLogical == other._data[i].props.isLogical) _data[i].props.isLogical == other._data[i].props.isLogical)
continue; continue;
else return false; else
return false;
return true; return true;
} }
bool basic_partition_map::operator!=(const basic_partition_map &other) const { bool basic_partition_map::operator!=(const basic_partition_map& other) const {
return !(*this == other); return !(*this == other);
} }
basic_partition_map::operator bool() const { return _count > 0; }
bool basic_partition_map::operator!() const { return _count == 0; }
Info basic_partition_map::operator[](const int index) const {
if (_count == 0 || index >= _count) return {};
return _data[index];
}
BasicInf basic_partition_map::operator[](const std::string_view& name) const {
if (_count == 0) return {};
if (const int i = _index_of(name); name == _data[i].name)
return {_data[i].props.size, _data[i].props.isLogical};
return {};
}
basic_partition_map::operator std::vector<Info>() const {
std::vector<Info> v;
if (_count == 0) return {};
for (size_t i = 0; i < _count; i++)
v.push_back(
{_data[i].name, {_data[i].props.size, _data[i].props.isLogical}});
return v;
}
basic_partition_map::operator int() const { return static_cast<int>(_count); }
basic_partition_map::iterator basic_partition_map::begin() const { basic_partition_map::iterator basic_partition_map::begin() const {
return iterator(_data); return iterator(_data);
} }
@@ -237,4 +272,4 @@ basic_partition_map::constant_iterator basic_partition_map::cbegin() const {
basic_partition_map::constant_iterator basic_partition_map::cend() const { basic_partition_map::constant_iterator basic_partition_map::cend() const {
return constant_iterator(_data + _count); return constant_iterator(_data + _count);
} }
} // namespace PartitionMap } // namespace PartitionMap

View File

@@ -14,9 +14,11 @@
limitations under the License. limitations under the License.
*/ */
#include <unistd.h>
#include <fstream>
#include <iostream> #include <iostream>
#include <libpartition_map/lib.hpp> #include <libpartition_map/lib.hpp>
#include <unistd.h>
int main() { int main() {
if (getuid() != 0) return 2; if (getuid() != 0) return 2;
@@ -30,7 +32,7 @@ int main() {
const auto map = MyMap.getAll(); const auto map = MyMap.getAll();
if (map.empty()) throw PartitionMap::Error("getAll() empty"); if (map.empty()) throw PartitionMap::Error("getAll() empty");
for (const auto &[name, props] : map) { for (const auto& [name, props] : map) {
std::cout << "Partition: " << name << ", size: " << props.size std::cout << "Partition: " << name << ", size: " << props.size
<< ", logical: " << props.isLogical << std::endl; << ", logical: " << props.isLogical << std::endl;
} }
@@ -44,20 +46,40 @@ int main() {
if (!logicals) if (!logicals)
throw PartitionMap::Error("getLogicalPartitionList() returned nullopt"); throw PartitionMap::Error("getLogicalPartitionList() returned nullopt");
std::cout << "Logical partitions: " << std::endl; std::cout << "Logical partitions: " << std::endl;
for (const auto &name : *logicals) for (const auto& name : *logicals)
std::cout << " - " << name << std::endl; std::cout << " - " << name << std::endl;
const auto physicals = MyMap.getPhysicalPartitionList(); const auto physicals = MyMap.getPhysicalPartitionList();
if (!physicals) if (!physicals)
throw PartitionMap::Error("getPhysicalPartitionList() returned nullopt"); throw PartitionMap::Error("getPhysicalPartitionList() returned nullopt");
std::cout << "Physical partitions: " << std::endl; std::cout << "Physical partitions: " << std::endl;
for (const auto &name : *physicals) for (const auto& name : *physicals)
std::cout << " - " << name << std::endl; std::cout << " - " << name << std::endl;
if (const std::vector<PartitionMap::Info> parts =
static_cast<std::vector<PartitionMap::Info>>(MyMap);
parts.empty())
throw PartitionMap::Error(
"operator std::vector<PartitionMap::Info>() returned empty vector");
auto func = [](const std::string& partition,
const PartitionMap::BasicInf props) -> bool {
std::ofstream f("parts.txt");
f << "Partition: " << partition << ", size: " << props.size
<< ", logical: " << props.isLogical;
f.exceptions(std::ios_base::failbit | std::ios_base::badbit);
return !f.fail();
};
if (!MyMap.doForAllPartitions(func))
throw PartitionMap::Error("doForAllPartitions() progress failed");
std::cout << "Total partitions count: " << (int)MyMap << std::endl;
std::cout << "Boot: " << MyMap.getRealLinkPathOf("boot") << std::endl; std::cout << "Boot: " << MyMap.getRealLinkPathOf("boot") << std::endl;
std::cout << "Boot (realpath): " << MyMap.getRealPathOf("boot") std::cout << "Boot (realpath): " << MyMap.getRealPathOf("boot")
<< std::endl; << std::endl;
std::cout << "Search dir: " << MyMap.getCurrentWorkDir() << std::endl; std::cout << "Search dir: " << MyMap.getCurrentWorkDir() << std::endl;
std::cout << "Search dir test 2: " << static_cast<std::string>(MyMap)
<< std::endl;
std::cout << "Has partition cache? = " << MyMap.hasPartition("cache") std::cout << "Has partition cache? = " << MyMap.hasPartition("cache")
<< std::endl; << std::endl;
std::cout << "system partition is logical? = " << MyMap.isLogical("system") std::cout << "system partition is logical? = " << MyMap.isLogical("system")
@@ -75,9 +97,12 @@ int main() {
if (MyMap != MyMap2) std::cout << "map1 != map2" << std::endl; if (MyMap != MyMap2) std::cout << "map1 != map2" << std::endl;
std::cout << PartitionMap::getLibVersion() << std::endl; std::cout << PartitionMap::getLibVersion() << std::endl;
} catch (PartitionMap::Error &error) { } catch (PartitionMap::Error& error) {
std::cerr << error.what() << std::endl; std::cerr << error.what() << std::endl;
return 1; return 1;
} catch (std::ios_base::failure& error) {
std::cerr << "fstream error: " << error.what() << std::endl;
return 1;
} }
return 0; return 0;