commit
ce0f68f790
|
@ -10,6 +10,163 @@ Thumbs.db
|
||||||
.Spotlight-V100
|
.Spotlight-V100
|
||||||
.Trashes
|
.Trashes
|
||||||
|
|
||||||
.idea
|
### JetBrains template
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff:
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/dictionaries
|
||||||
|
|
||||||
|
# Sensitive or high-churn files:
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.xml
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
|
||||||
|
# Gradle:
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# CMake
|
||||||
cmake-build-*
|
cmake-build-*
|
||||||
build
|
|
||||||
|
# Mongo Explorer plugin:
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
### macOS template
|
||||||
|
# General
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.TemporaryItems
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
### Linux template
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
### Windows template
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
### C template
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
|
@ -0,0 +1 @@
|
||||||
|
caesiumclt
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
|
@ -0,0 +1,29 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<file>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||||
|
</file>
|
||||||
|
<class>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||||
|
</class>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||||
|
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||||
|
</extensions>
|
||||||
|
</Objective-C-extensions>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
|
@ -0,0 +1,125 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="ClangTidyInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="DeprecatedAPI" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="DuplicateSwitchCase" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="EndlessLoop" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="EqualityInConditionalOperator" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="FormatSpecifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="FunctionImplicitDeclarationInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HidesUpperScope" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HidingNonVirtualFunction" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ImplicitIntegerAndEnumConversion" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ImplicitPointerAndIntegerConversion" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="IncompatibleEnums" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="IncompatibleInitializers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="IncompatiblePointers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="InfiniteRecursion" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="KRUnspecifiedParameters" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="LocalValueEscapesScope" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="MissingReturn" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="MissingSwitchCase" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="NotImplementedFunctions" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="NotInitializedVariable" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="NotSuperclass" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="OCDFAInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="OCLoopDoesntUseConditionVariableInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="OCSimplifyInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="OCUnusedGlobalDeclarationInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="OCUnusedMacroInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="OCUnusedStructInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="OCUnusedTemplateParameterInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="RedundantCast" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ResourceNotFoundInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="SignednessMismatch" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnreachableCode" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnusedExpressionResult" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnusedImportStatement" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnusedLocalVariable" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnusedLocalization" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnusedParameter" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnusedValue" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ValueMayNotFitIntoReceiver" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="Inspection" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
<component name="CidrRootsConfiguration">
|
||||||
|
<sourceRoots>
|
||||||
|
<file path="$PROJECT_DIR$/src" />
|
||||||
|
</sourceRoots>
|
||||||
|
<excludeRoots>
|
||||||
|
<file path="$PROJECT_DIR$/cmake-build-debug/CMakeFiles" />
|
||||||
|
</excludeRoots>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/caesium-clt.iml" filepath="$PROJECT_DIR$/.idea/caesium-clt.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<component name="DependencyValidationManager">
|
||||||
|
<scope name="Inspection" pattern="!file:src/optparse.c&&!file:src/optparse.h&&!file:src/tinydir.h&&!file:.gitignore" />
|
||||||
|
</component>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -3,8 +3,8 @@ project(caesiumclt)
|
||||||
|
|
||||||
# The version number.
|
# The version number.
|
||||||
set(VERSION_MAJOR 0)
|
set(VERSION_MAJOR 0)
|
||||||
set(VERSION_MINOR 10)
|
set(VERSION_MINOR 11)
|
||||||
set(VERSION_PATCH 2)
|
set(VERSION_PATCH 0)
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
"src/config.h.in"
|
"src/config.h.in"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
## Caesium CommandLineTools
|
## Caesium CommandLineTools
|
||||||
##### caesium-clt - v0.10.2-beta (build 20170318) - Copyright © Matteo Paonessa, 2017. All Rights Reserved.
|
##### caesium-clt - v0.11.0-beta (build 20171109) - Copyright © Matteo Paonessa, 2017. All Rights Reserved.
|
||||||
[](https://travis-ci.org/Lymphatus/caesium-clt)
|
[](https://travis-ci.org/Lymphatus/caesium-clt)
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
----------
|
----------
|
||||||
|
|
||||||
###### TESTED PLATFORMS
|
###### TESTED PLATFORMS
|
||||||
* Mac OS X Sierra (v10.12.3)
|
* Mac OS X High Sierra (v10.13.1)
|
||||||
* Ubuntu 16.04
|
* Ubuntu 16.04
|
||||||
* Windows 10
|
* Windows 10
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ $ caesiumclt -q 0 -RS -o ~/output/ ~/Pictures
|
||||||
----------
|
----------
|
||||||
|
|
||||||
###### CHANGELOG
|
###### CHANGELOG
|
||||||
|
* 0.11.0-beta - Fixing paths issues and dry-run option
|
||||||
* 0.10.2-beta - Bugfixes & full Windows support
|
* 0.10.2-beta - Bugfixes & full Windows support
|
||||||
* 0.10.1-beta - All features are available
|
* 0.10.1-beta - All features are available
|
||||||
* 0.10.0-beta - Switched to cmake build system and libcaesium
|
* 0.10.0-beta - Switched to cmake build system and libcaesium
|
||||||
|
|
|
@ -39,9 +39,9 @@ const char *get_error_message(int code)
|
||||||
case 9:
|
case 9:
|
||||||
return "Input files provided. Cannot mix them with a folder.";
|
return "Input files provided. Cannot mix them with a folder.";
|
||||||
case 10:
|
case 10:
|
||||||
return "-R is useless on files.";
|
return "-R has no effects on files.";
|
||||||
case 11:
|
case 11:
|
||||||
return "-S is useless without -R.";
|
return "-S has no effect without -R.";
|
||||||
case 12:
|
case 12:
|
||||||
return "Cannot set output folder inside the input one";
|
return "Cannot set output folder inside the input one";
|
||||||
|
|
||||||
|
|
143
src/helper.c
143
src/helper.c
|
@ -1,6 +1,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <direct.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include "optparse.h"
|
#include "optparse.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -11,7 +16,7 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
{
|
{
|
||||||
struct optparse opts;
|
struct optparse opts;
|
||||||
//Initialize application options
|
//Initialize application options
|
||||||
cclt_options parameters = {NULL, NULL, false, false, 0, 0, 0};
|
cclt_options parameters = {NULL, "", "", false, false, 0, 0, 0, false};
|
||||||
|
|
||||||
//Parse command line args
|
//Parse command line args
|
||||||
optparse_init(&opts, argv);
|
optparse_init(&opts, argv);
|
||||||
|
@ -21,33 +26,36 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
{"output", 'o', OPTPARSE_REQUIRED},
|
{"output", 'o', OPTPARSE_REQUIRED},
|
||||||
{"recursive", 'R', OPTPARSE_NONE},
|
{"recursive", 'R', OPTPARSE_NONE},
|
||||||
{"keep-structure", 'S', OPTPARSE_NONE},
|
{"keep-structure", 'S', OPTPARSE_NONE},
|
||||||
|
{"dry-run", 'd', OPTPARSE_NONE},
|
||||||
{"version", 'v', OPTPARSE_NONE},
|
{"version", 'v', OPTPARSE_NONE},
|
||||||
{"help", 'h', OPTPARSE_NONE},
|
{"help", 'h', OPTPARSE_NONE},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
int option;
|
|
||||||
|
|
||||||
|
int option;
|
||||||
while ((option = optparse_long(&opts, longopts, NULL)) != -1) {
|
while ((option = optparse_long(&opts, longopts, NULL)) != -1) {
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'q':
|
case 'q':
|
||||||
options->jpeg.quality = atoi(opts.optarg);
|
options->jpeg.quality = (int) strtol(opts.optarg, (char **) NULL, 10);;
|
||||||
if (options->jpeg.quality < 0 || options->jpeg.quality > 100) {
|
if (options->jpeg.quality < 0 || options->jpeg.quality > 100) {
|
||||||
display_error(ERROR, 1);
|
display_error(ERROR, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
options->jpeg.exif_copy = true;
|
options->jpeg.exif_copy = true;
|
||||||
break;
|
|
||||||
case 'o':
|
case 'o':
|
||||||
if (opts.optarg[strlen(opts.optarg) - 1] == '/' || opts.optarg[strlen(opts.optarg) - 1] == '\\') {
|
if (opts.optarg[0] == '~') {
|
||||||
parameters.output_folder = malloc((strlen(opts.optarg) + 1) * sizeof(char));
|
|
||||||
snprintf(parameters.output_folder, strlen(opts.optarg) + 1, "%s", opts.optarg);
|
snprintf(parameters.output_folder, strlen(opts.optarg) + 1, "%s", opts.optarg);
|
||||||
} else {
|
} else {
|
||||||
parameters.output_folder = malloc((strlen(opts.optarg) + 2) * sizeof(char));
|
realpath(opts.optarg, parameters.output_folder);
|
||||||
|
}
|
||||||
|
if (parameters.output_folder[strlen(opts.optarg) - 1] != '/' &&
|
||||||
|
parameters.output_folder[strlen(opts.optarg) - 1] != '\\') {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
snprintf(parameters.output_folder, strlen(opts.optarg) + 2, "%s\\", opts.optarg);
|
snprintf(parameters.output_folder, strlen(parameters.output_folder) + 2, "%s\\", parameters.output_folder);
|
||||||
#else
|
#else
|
||||||
snprintf(parameters.output_folder, strlen(opts.optarg) + 2, "%s/", opts.optarg);
|
snprintf(parameters.output_folder, strlen(parameters.output_folder) + 2, "%s/",
|
||||||
|
parameters.output_folder);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -57,6 +65,9 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
case 'S':
|
case 'S':
|
||||||
parameters.keep_structure = true;
|
parameters.keep_structure = true;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
parameters.dry_run = true;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
fprintf(stdout, "%d.%d.%d\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
|
fprintf(stdout, "%d.%d.%d\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
@ -69,22 +80,46 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
display_error(ERROR, 2);
|
display_error(ERROR, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remaining arguments
|
//Remaining arguments
|
||||||
char *arg;
|
char *arg;
|
||||||
bool files_flag = false, folders_flag = false;
|
bool files_flag = false, folders_flag = false;
|
||||||
|
char resolved_path[MAX_PATH_SIZE];
|
||||||
while ((arg = optparse_arg(&opts))) {
|
while ((arg = optparse_arg(&opts))) {
|
||||||
if (folders_flag) {
|
if (folders_flag) {
|
||||||
display_error(WARNING, 8);
|
display_error(WARNING, 8);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if it's a directory and add its content
|
//Check if it's a directory and add its content
|
||||||
if (is_directory(arg)) {
|
if (arg[0] == '~') {
|
||||||
|
if (arg[strlen(arg) - 1] == '/' || arg[strlen(arg) - 1] == '\\') {
|
||||||
|
snprintf(resolved_path, strlen(arg), "%s", arg);
|
||||||
|
} else {
|
||||||
|
#ifdef _WIN32
|
||||||
|
snprintf(resolved_path, strlen(arg) + 1, "%s\\", arg);
|
||||||
|
#else
|
||||||
|
snprintf(resolved_path, strlen(arg) + 1, "%s/", arg);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realpath(arg, resolved_path);
|
||||||
|
}
|
||||||
|
if (is_directory(resolved_path)) {
|
||||||
if (!files_flag) {
|
if (!files_flag) {
|
||||||
folders_flag = true;
|
folders_flag = true;
|
||||||
parameters.input_folder = strdup(arg);
|
|
||||||
|
if (resolved_path[strlen(resolved_path) - 1] != '/' && resolved_path[strlen(resolved_path) - 1] != '\\') {
|
||||||
|
#ifdef _WIN32
|
||||||
|
resolved_path[strlen(resolved_path)] = '\\';
|
||||||
|
#else
|
||||||
|
resolved_path[strlen(resolved_path)] = '/';
|
||||||
|
#endif
|
||||||
|
resolved_path[strlen(resolved_path)] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(parameters.input_folder, strlen(resolved_path) + 1, "%s", resolved_path);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
count = scan_folder(arg, ¶meters, parameters.recursive);
|
count = scan_folder(resolved_path, ¶meters, parameters.recursive);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
display_error(WARNING, 3);
|
display_error(WARNING, 3);
|
||||||
}
|
}
|
||||||
|
@ -93,7 +128,6 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
files_flag = true;
|
files_flag = true;
|
||||||
parameters.input_folder = NULL;
|
|
||||||
parameters.input_files = realloc(parameters.input_files, (parameters.files_count + 1) * sizeof(char *));
|
parameters.input_files = realloc(parameters.input_files, (parameters.files_count + 1) * sizeof(char *));
|
||||||
parameters.input_files[parameters.files_count] = malloc((strlen(arg) + 1) * sizeof(char));
|
parameters.input_files[parameters.files_count] = malloc((strlen(arg) + 1) * sizeof(char));
|
||||||
snprintf(parameters.input_files[parameters.files_count], strlen(arg) + 1, "%s", arg);
|
snprintf(parameters.input_files[parameters.files_count], strlen(arg) + 1, "%s", arg);
|
||||||
|
@ -102,8 +136,12 @@ cclt_options parse_arguments(char **argv, cs_image_pars *options)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if the output folder is a subfolder of the input to avoid infinite loops
|
//Check if the output folder is a subfolder of the input to avoid infinite loops
|
||||||
|
//but just if the -R option is set
|
||||||
|
//However, if the folders are the same, we can let it go as it will overwrite the files
|
||||||
if (folders_flag) {
|
if (folders_flag) {
|
||||||
if (strstr(parameters.output_folder, parameters.input_folder) != NULL) {
|
if (strstr(parameters.output_folder, parameters.input_folder) != NULL
|
||||||
|
&& strcmp(parameters.output_folder, parameters.input_folder) != 0
|
||||||
|
&& parameters.recursive) {
|
||||||
display_error(ERROR, 12);
|
display_error(ERROR, 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +176,10 @@ int start_compression(cclt_options *options, cs_image_pars *parameters)
|
||||||
|
|
||||||
for (int i = 0; i < options->files_count; i++) {
|
for (int i = 0; i < options->files_count; i++) {
|
||||||
char *filename = get_filename(options->input_files[i]);
|
char *filename = get_filename(options->input_files[i]);
|
||||||
char *output_full_path;
|
char *output_full_path = NULL;
|
||||||
|
char *original_output_full_path = NULL;
|
||||||
|
bool overwriting = false;
|
||||||
|
off_t file_size = 0;
|
||||||
//If we don't need to keep the structure, we put all the files in one folder by just the filename
|
//If we don't need to keep the structure, we put all the files in one folder by just the filename
|
||||||
if (!options->keep_structure) {
|
if (!options->keep_structure) {
|
||||||
output_full_path = malloc((strlen(filename) + strlen(options->output_folder) + 1) * sizeof(char));
|
output_full_path = malloc((strlen(filename) + strlen(options->output_folder) + 1) * sizeof(char));
|
||||||
|
@ -146,18 +187,23 @@ int start_compression(cclt_options *options, cs_image_pars *parameters)
|
||||||
options->output_folder, filename);
|
options->output_folder, filename);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Otherwise, we nee to compute the whole directory structure
|
* Otherwise, we need to compute the whole directory structure
|
||||||
* We are sure we have a folder only as input, so that's the root
|
* We are sure we have a folder only as input, so that's the root
|
||||||
* Just compute the subfolders without the filename, make them and append the filename
|
* Just compute the subfolders without the filename, make them and append the filename
|
||||||
* A piece of cake <3
|
* A piece of cake <3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t index = strspn(options->input_folder, options->input_files[i]) + 1;
|
size_t index = strspn(options->input_folder, options->input_files[i]);
|
||||||
size_t size = strlen(options->input_files[i]) - index - strlen(filename);
|
size_t size = strlen(options->input_files[i]) - index - strlen(filename);
|
||||||
char output_full_folder[strlen(options->output_folder) + size + 1];
|
char output_full_folder[strlen(options->output_folder) + size + 1];
|
||||||
snprintf(output_full_folder, strlen(options->output_folder) + size + 1, "%s%s", options->output_folder, &options->input_files[i][index]);
|
|
||||||
|
snprintf(output_full_folder, strlen(options->output_folder) + size + 1, "%s%s",
|
||||||
|
options->output_folder, &options->input_files[i][index]);
|
||||||
output_full_path = malloc((strlen(output_full_folder) + strlen(filename) + 1) * sizeof(char));
|
output_full_path = malloc((strlen(output_full_folder) + strlen(filename) + 1) * sizeof(char));
|
||||||
snprintf(output_full_path, strlen(output_full_folder) + strlen(filename) + 1, "%s%s", output_full_folder, filename);
|
snprintf(output_full_path, strlen(output_full_folder) + strlen(filename) + 1, "%s%s",
|
||||||
|
output_full_folder,
|
||||||
|
filename);
|
||||||
|
|
||||||
mkpath(output_full_folder);
|
mkpath(output_full_folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,24 +213,47 @@ int start_compression(cclt_options *options, cs_image_pars *parameters)
|
||||||
filename,
|
filename,
|
||||||
output_full_path);
|
output_full_path);
|
||||||
|
|
||||||
input_file_size = get_file_size(options->input_files[i]);
|
//If the file already exist, create a temporary file
|
||||||
options->input_total_size += input_file_size;
|
if (file_exists(output_full_path)) {
|
||||||
if (cs_compress(options->input_files[i], output_full_path, parameters)) {
|
original_output_full_path = strdup(output_full_path);
|
||||||
compressed_files++;
|
output_full_path = realloc(output_full_path, (strlen(output_full_path) + 4) * sizeof(char));
|
||||||
output_file_size = get_file_size(output_full_path);
|
snprintf(output_full_path, (strlen(original_output_full_path) + 4), "%s.cs", original_output_full_path);
|
||||||
options->output_total_size += output_file_size;
|
overwriting = true;
|
||||||
|
|
||||||
char *human_input_size = get_human_size(input_file_size);
|
|
||||||
char *human_output_size = get_human_size(output_file_size);
|
|
||||||
|
|
||||||
fprintf(stdout, "%s -> %s [%.2f%%]\n",
|
|
||||||
human_input_size,
|
|
||||||
human_output_size,
|
|
||||||
((float) output_file_size - input_file_size) * 100 / input_file_size);
|
|
||||||
} else {
|
|
||||||
options->input_total_size -= get_file_size(options->input_files[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file_size = get_file_size(options->input_files[i]);
|
||||||
|
if (file_size == 0) {
|
||||||
|
//We could not open the file
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
input_file_size = file_size;
|
||||||
|
options->input_total_size += input_file_size;
|
||||||
|
|
||||||
|
//Prevent compression if running in dry mode
|
||||||
|
if (!options->dry_run) {
|
||||||
|
if (cs_compress(options->input_files[i], output_full_path, parameters)) {
|
||||||
|
compressed_files++;
|
||||||
|
output_file_size = get_file_size(output_full_path);
|
||||||
|
options->output_total_size += output_file_size;
|
||||||
|
|
||||||
|
char *human_input_size = get_human_size(input_file_size);
|
||||||
|
char *human_output_size = get_human_size(output_file_size);
|
||||||
|
|
||||||
|
fprintf(stdout, "%s -> %s [%.2f%%]\n",
|
||||||
|
human_input_size,
|
||||||
|
human_output_size,
|
||||||
|
((float) output_file_size - input_file_size) * 100 / input_file_size);
|
||||||
|
} else {
|
||||||
|
options->input_total_size -= get_file_size(options->input_files[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rename if we were overwriting
|
||||||
|
if (overwriting && !options->dry_run) {
|
||||||
|
rename(output_full_path, original_output_full_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(original_output_full_path);
|
||||||
free(output_full_path);
|
free(output_full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/helper.h
12
src/helper.h
|
@ -3,16 +3,24 @@
|
||||||
|
|
||||||
#include <caesium.h>
|
#include <caesium.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define MAX_PATH_SIZE _MAX_PATH
|
||||||
|
#else
|
||||||
|
#include <limits.h>
|
||||||
|
#define MAX_PATH_SIZE PATH_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct cclt_options
|
typedef struct cclt_options
|
||||||
{
|
{
|
||||||
char **input_files;
|
char **input_files;
|
||||||
char *input_folder;
|
char input_folder[MAX_PATH_SIZE];
|
||||||
char *output_folder;
|
char output_folder[MAX_PATH_SIZE];
|
||||||
bool recursive;
|
bool recursive;
|
||||||
bool keep_structure;
|
bool keep_structure;
|
||||||
int files_count;
|
int files_count;
|
||||||
off_t input_total_size;
|
off_t input_total_size;
|
||||||
off_t output_total_size;
|
off_t output_total_size;
|
||||||
|
bool dry_run;
|
||||||
} cclt_options;
|
} cclt_options;
|
||||||
|
|
||||||
cclt_options parse_arguments(char *argv[], cs_image_pars *options);
|
cclt_options parse_arguments(char *argv[], cs_image_pars *options);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
//Exit if no arguments
|
//Exit if less than 2 arguments
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
print_help();
|
print_help();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -27,10 +27,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
start_compression(&options, &compress_options);
|
start_compression(&options, &compress_options);
|
||||||
|
|
||||||
//Cleanup the two memory allocated objects
|
//Cleanup the memory allocated objects
|
||||||
free(options.output_folder);
|
|
||||||
free(options.input_files);
|
free(options.input_files);
|
||||||
free(options.input_folder);
|
|
||||||
|
|
||||||
//Get the difference
|
//Get the difference
|
||||||
diff = clock() - start;
|
diff = clock() - start;
|
||||||
|
|
|
@ -99,11 +99,6 @@ int optparse(struct optparse *options, const char *optstring)
|
||||||
int type = argtype(optstring, option[0]);
|
int type = argtype(optstring, option[0]);
|
||||||
char *next = options->argv[options->optind + 1];
|
char *next = options->argv[options->optind + 1];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case -1: {
|
|
||||||
options->optind++;
|
|
||||||
char str[2] = {option[0]};
|
|
||||||
return opterror(options, MSG_INVALID, str);
|
|
||||||
}
|
|
||||||
case OPTPARSE_NONE:
|
case OPTPARSE_NONE:
|
||||||
if (option[1]) {
|
if (option[1]) {
|
||||||
options->subopt++;
|
options->subopt++;
|
||||||
|
@ -134,8 +129,13 @@ int optparse(struct optparse *options, const char *optstring)
|
||||||
else
|
else
|
||||||
options->optarg = 0;
|
options->optarg = 0;
|
||||||
return option[0];
|
return option[0];
|
||||||
|
default:
|
||||||
|
case -1: {
|
||||||
|
options->optind++;
|
||||||
|
char str[2] = {option[0]};
|
||||||
|
return opterror(options, MSG_INVALID, str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *optparse_arg(struct optparse *options)
|
char *optparse_arg(struct optparse *options)
|
||||||
|
|
188
src/utils.c
188
src/utils.c
|
@ -4,6 +4,7 @@
|
||||||
#include <caesium.h>
|
#include <caesium.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "tinydir.h"
|
#include "tinydir.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
@ -22,6 +23,7 @@ void print_help()
|
||||||
"\t-o, --output\t\toutput folder\n"
|
"\t-o, --output\t\toutput folder\n"
|
||||||
"\t-R, --recursive\t\tif input is a folder, scan subfolders too\n"
|
"\t-R, --recursive\t\tif input is a folder, scan subfolders too\n"
|
||||||
"\t-S, --keep-structure\tkeep the folder structure, use with -R\n"
|
"\t-S, --keep-structure\tkeep the folder structure, use with -R\n"
|
||||||
|
"\t-d, --dry-run\t\tdo not really compress files but just show output paths\n"
|
||||||
"\t-h, --help\t\tdisplay this help and exit\n"
|
"\t-h, --help\t\tdisplay this help and exit\n"
|
||||||
"\t-v, --version\t\toutput version information and exit\n\n");
|
"\t-v, --version\t\toutput version information and exit\n\n");
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
@ -30,18 +32,18 @@ void print_help()
|
||||||
bool is_directory(const char *path)
|
bool is_directory(const char *path)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
tinydir_dir dir;
|
tinydir_dir dir;
|
||||||
|
|
||||||
return tinydir_open(&dir, path) != -1;
|
return tinydir_open(&dir, path) != -1;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
tinydir_file file;
|
tinydir_file file;
|
||||||
|
|
||||||
if (tinydir_file_open(&file, path) == -1) {
|
if (tinydir_file_open(&file, path) == -1) {
|
||||||
display_error(ERROR, 6);
|
display_error(ERROR, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bool) file.is_dir;
|
return (bool) file.is_dir;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +64,10 @@ int scan_folder(const char *directory, cclt_options *options, bool recursive)
|
||||||
} else {
|
} else {
|
||||||
options->input_files = realloc(options->input_files, (options->files_count + 1) * sizeof(char *));
|
options->input_files = realloc(options->input_files, (options->files_count + 1) * sizeof(char *));
|
||||||
options->input_files[options->files_count] = malloc((strlen(file.path) + 1) * sizeof(char));
|
options->input_files[options->files_count] = malloc((strlen(file.path) + 1) * sizeof(char));
|
||||||
snprintf(options->input_files[options->files_count],
|
snprintf(options->input_files[options->files_count],
|
||||||
strlen(file.path) + 1, "%s", file.path);
|
strlen(file.path) + 1, "%s", file.path);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
options->input_files[options->files_count] = str_replace(options->input_files[options->files_count], "/", "\\");
|
options->input_files[options->files_count] = str_replace(options->input_files[options->files_count], "/", "\\");
|
||||||
#endif
|
#endif
|
||||||
options->files_count++;
|
options->files_count++;
|
||||||
n++;
|
n++;
|
||||||
|
@ -107,13 +109,10 @@ char *get_filename(char *full_path)
|
||||||
|
|
||||||
//Get just the filename
|
//Get just the filename
|
||||||
tofree = strdup(full_path);
|
tofree = strdup(full_path);
|
||||||
//TODO change to strncpy
|
|
||||||
strcpy(tofree, full_path);
|
|
||||||
//TODO Windows?
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
while ((token = strsep(&tofree, "\\")) != NULL) {
|
while ((token = strsep(&tofree, "\\")) != NULL) {
|
||||||
#else
|
#else
|
||||||
while ((token = strsep(&tofree, "/")) != NULL) {
|
while ((token = strsep(&tofree, "/")) != NULL) {
|
||||||
#endif
|
#endif
|
||||||
if (tofree == NULL) {
|
if (tofree == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -127,19 +126,24 @@ char *get_filename(char *full_path)
|
||||||
|
|
||||||
off_t get_file_size(const char *path)
|
off_t get_file_size(const char *path)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(path, "rb");
|
FILE *f = fopen(path, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
display_error(ERROR, 7);
|
display_error(WARNING, 7);
|
||||||
}
|
return 0;
|
||||||
fseek(f, 0, SEEK_END);
|
}
|
||||||
unsigned long len = (unsigned long)ftell(f);
|
fseek(f, 0, SEEK_END);
|
||||||
fclose(f);
|
off_t len = ftell(f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_human_size(off_t size)
|
char *get_human_size(off_t size)
|
||||||
{
|
{
|
||||||
|
if (size == 0) {
|
||||||
|
return "0.00 B";
|
||||||
|
}
|
||||||
|
|
||||||
//We should not get more than TB images
|
//We should not get more than TB images
|
||||||
char *unit[5] = {"B", "KB", "MB", "GB", "TB"};
|
char *unit[5] = {"B", "KB", "MB", "GB", "TB"};
|
||||||
//Index of the array containing the correct unit
|
//Index of the array containing the correct unit
|
||||||
|
@ -158,88 +162,94 @@ char *get_human_size(off_t size)
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool file_exists(const char *file_path)
|
||||||
|
{
|
||||||
|
struct stat buffer;
|
||||||
|
return (stat(file_path, &buffer) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *str_replace(char *orig, char *rep, char *with) {
|
char *str_replace(char *orig, char *rep, char *with) {
|
||||||
char *result; // the return string
|
char *result; // the return string
|
||||||
char *ins; // the next insert point
|
char *ins; // the next insert point
|
||||||
char *tmp; // varies
|
char *tmp; // varies
|
||||||
int len_rep; // length of rep (the string to remove)
|
int len_rep; // length of rep (the string to remove)
|
||||||
int len_with; // length of with (the string to replace rep with)
|
int len_with; // length of with (the string to replace rep with)
|
||||||
int len_front; // distance between rep and end of last rep
|
int len_front; // distance between rep and end of last rep
|
||||||
int count; // number of replacements
|
int count; // number of replacements
|
||||||
|
|
||||||
if (!orig || !rep)
|
if (!orig || !rep)
|
||||||
return NULL;
|
return NULL;
|
||||||
len_rep = strlen(rep);
|
len_rep = strlen(rep);
|
||||||
if (len_rep == 0)
|
if (len_rep == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!with)
|
if (!with)
|
||||||
with = "";
|
with = "";
|
||||||
len_with = strlen(with);
|
len_with = strlen(with);
|
||||||
|
|
||||||
ins = orig;
|
ins = orig;
|
||||||
for (count = 0; tmp = strstr(ins, rep); ++count) {
|
for (count = 0; tmp = strstr(ins, rep); ++count) {
|
||||||
ins = tmp + len_rep;
|
ins = tmp + len_rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
|
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
ins = strstr(orig, rep);
|
ins = strstr(orig, rep);
|
||||||
len_front = ins - orig;
|
len_front = ins - orig;
|
||||||
tmp = strncpy(tmp, orig, len_front) + len_front;
|
tmp = strncpy(tmp, orig, len_front) + len_front;
|
||||||
tmp = strcpy(tmp, with) + len_with;
|
tmp = strcpy(tmp, with) + len_with;
|
||||||
orig += len_front + len_rep;
|
orig += len_front + len_rep;
|
||||||
}
|
}
|
||||||
strcpy(tmp, orig);
|
strcpy(tmp, orig);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strsep (char **stringp, const char *delim)
|
char *strsep (char **stringp, const char *delim)
|
||||||
{
|
{
|
||||||
char *begin, *end;
|
char *begin, *end;
|
||||||
|
|
||||||
begin = *stringp;
|
begin = *stringp;
|
||||||
if (begin == NULL)
|
if (begin == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* A frequent case is when the delimiter string contains only one
|
/* A frequent case is when the delimiter string contains only one
|
||||||
character. Here we don't need to call the expensive `strpbrk'
|
character. Here we don't need to call the expensive `strpbrk'
|
||||||
function and instead work using `strchr'. */
|
function and instead work using `strchr'. */
|
||||||
if (delim[0] == '\0' || delim[1] == '\0')
|
if (delim[0] == '\0' || delim[1] == '\0')
|
||||||
{
|
{
|
||||||
char ch = delim[0];
|
char ch = delim[0];
|
||||||
|
|
||||||
if (ch == '\0')
|
if (ch == '\0')
|
||||||
end = NULL;
|
end = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*begin == ch)
|
if (*begin == ch)
|
||||||
end = begin;
|
end = begin;
|
||||||
else if (*begin == '\0')
|
else if (*begin == '\0')
|
||||||
end = NULL;
|
end = NULL;
|
||||||
else
|
else
|
||||||
end = strchr (begin + 1, ch);
|
end = strchr (begin + 1, ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Find the end of the token. */
|
/* Find the end of the token. */
|
||||||
end = strpbrk (begin, delim);
|
end = strpbrk (begin, delim);
|
||||||
|
|
||||||
if (end)
|
if (end)
|
||||||
{
|
{
|
||||||
/* Terminate the token and set *STRINGP past NUL character. */
|
/* Terminate the token and set *STRINGP past NUL character. */
|
||||||
*end++ = '\0';
|
*end++ = '\0';
|
||||||
*stringp = end;
|
*stringp = end;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* No more delimiters; this is the last token. */
|
/* No more delimiters; this is the last token. */
|
||||||
*stringp = NULL;
|
*stringp = NULL;
|
||||||
|
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,8 @@ char* get_human_size(off_t size);
|
||||||
|
|
||||||
int mkpath(const char *pathname);
|
int mkpath(const char *pathname);
|
||||||
|
|
||||||
|
bool file_exists(const char* file_path);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *str_replace(char *orig, char *rep, char *with);
|
char *str_replace(char *orig, char *rep, char *with);
|
||||||
char *strsep(char **stringp, const char *delim);
|
char *strsep(char **stringp, const char *delim);
|
||||||
|
|
Loading…
Reference in New Issue