Rework parameter parsing with ParameterOperation functions.
This commit is contained in:
5
Makefile
5
Makefile
@@ -19,6 +19,7 @@ HEADS := \
|
|||||||
src/util.h \
|
src/util.h \
|
||||||
src/crc.h \
|
src/crc.h \
|
||||||
src/fileutil.h \
|
src/fileutil.h \
|
||||||
|
src/parameteroperation.h \
|
||||||
src/filenode.h \
|
src/filenode.h \
|
||||||
src/actionfilenode.h \
|
src/actionfilenode.h \
|
||||||
src/actionfilenodesync.h \
|
src/actionfilenodesync.h \
|
||||||
@@ -28,6 +29,7 @@ OBJS_BASE := \
|
|||||||
$(BUILDDIR)/util.o \
|
$(BUILDDIR)/util.o \
|
||||||
$(BUILDDIR)/crc.o \
|
$(BUILDDIR)/crc.o \
|
||||||
$(BUILDDIR)/fileutil.o \
|
$(BUILDDIR)/fileutil.o \
|
||||||
|
$(BUILDDIR)/parameteroperation.o \
|
||||||
$(BUILDDIR)/filenode.o \
|
$(BUILDDIR)/filenode.o \
|
||||||
$(BUILDDIR)/actionfilenode.o \
|
$(BUILDDIR)/actionfilenode.o \
|
||||||
$(BUILDDIR)/actionfilenodesync.o \
|
$(BUILDDIR)/actionfilenodesync.o \
|
||||||
@@ -73,6 +75,9 @@ $(BUILDDIR)/crc.o: src/crc.c $(HEADS)
|
|||||||
$(BUILDDIR)/fileutil.o: src/fileutil.c $(HEADS)
|
$(BUILDDIR)/fileutil.o: src/fileutil.c $(HEADS)
|
||||||
$(DO_CC)
|
$(DO_CC)
|
||||||
|
|
||||||
|
$(BUILDDIR)/parameteroperation.o: src/parameteroperation.c $(HEADS)
|
||||||
|
$(DO_CC)
|
||||||
|
|
||||||
$(BUILDDIR)/filenode.o: src/filenode.c $(HEADS)
|
$(BUILDDIR)/filenode.o: src/filenode.c $(HEADS)
|
||||||
$(DO_CC)
|
$(DO_CC)
|
||||||
|
|
||||||
|
|||||||
@@ -138,6 +138,7 @@
|
|||||||
<ClCompile Include="..\..\src\filenode.c" />
|
<ClCompile Include="..\..\src\filenode.c" />
|
||||||
<ClCompile Include="..\..\src\fileutil.c" />
|
<ClCompile Include="..\..\src\fileutil.c" />
|
||||||
<ClCompile Include="..\..\src\main.c" />
|
<ClCompile Include="..\..\src\main.c" />
|
||||||
|
<ClCompile Include="..\..\src\parameteroperation.c" />
|
||||||
<ClCompile Include="..\..\src\util.c" />
|
<ClCompile Include="..\..\src\util.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -147,6 +148,7 @@
|
|||||||
<ClInclude Include="..\..\src\crc.h" />
|
<ClInclude Include="..\..\src\crc.h" />
|
||||||
<ClInclude Include="..\..\src\filenode.h" />
|
<ClInclude Include="..\..\src\filenode.h" />
|
||||||
<ClInclude Include="..\..\src\fileutil.h" />
|
<ClInclude Include="..\..\src\fileutil.h" />
|
||||||
|
<ClInclude Include="..\..\src\parameteroperation.h" />
|
||||||
<ClInclude Include="..\..\src\util.h" />
|
<ClInclude Include="..\..\src\util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
<ClCompile Include="..\..\src\actionfilenodesync.c">
|
<ClCompile Include="..\..\src\actionfilenodesync.c">
|
||||||
<Filter>Archivos de código fuente</Filter>
|
<Filter>Archivos de código fuente</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\parameteroperation.c">
|
||||||
|
<Filter>Archivos de código fuente</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\crc.h">
|
<ClInclude Include="..\..\src\crc.h">
|
||||||
@@ -62,6 +65,9 @@
|
|||||||
<ClInclude Include="..\..\src\actionfilenodesync.h">
|
<ClInclude Include="..\..\src\actionfilenodesync.h">
|
||||||
<Filter>Archivos de encabezado</Filter>
|
<Filter>Archivos de encabezado</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\parameteroperation.h">
|
||||||
|
<Filter>Archivos de encabezado</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\README.md" />
|
<None Include="..\..\README.md" />
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ typedef enum EActionFileCmp {
|
|||||||
ActionFileCmp_MakeLeftDirectory
|
ActionFileCmp_MakeLeftDirectory
|
||||||
} ActionFileCmp;
|
} ActionFileCmp;
|
||||||
|
|
||||||
typedef struct TActionFileNode TActionFileNode, *ActionFileNode;
|
typedef struct SActionFileNode TActionFileNode, *ActionFileNode;
|
||||||
struct TActionFileNode {
|
struct SActionFileNode {
|
||||||
ActionFileCmp action;
|
ActionFileCmp action;
|
||||||
FileNode left;
|
FileNode left;
|
||||||
FileNode right;
|
FileNode right;
|
||||||
|
|||||||
301
src/main.c
301
src/main.c
@@ -5,139 +5,12 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "fileutil.h"
|
#include "fileutil.h"
|
||||||
|
#include "parameteroperation.h"
|
||||||
#include "filenode.h"
|
#include "filenode.h"
|
||||||
#include "actionfilenode.h"
|
#include "actionfilenode.h"
|
||||||
#include "actionfilenodesync.h"
|
#include "actionfilenodesync.h"
|
||||||
#include "actionfilenodecopy.h"
|
#include "actionfilenodecopy.h"
|
||||||
|
|
||||||
void Help(char *exe) {
|
|
||||||
char exeFilename[MaxPath];
|
|
||||||
File_GetName(exe, exeFilename);
|
|
||||||
Print("Usage:\n");
|
|
||||||
Print(" %s info [file] {[file] {..}}\n", exeFilename);
|
|
||||||
Print(" %s scan [dir] [tree] \n", exeFilename);
|
|
||||||
Print(" %s rescan [dir] [tree] \n", exeFilename);
|
|
||||||
Print(" %s read [file] [tree]\n", exeFilename);
|
|
||||||
Print(" %s dir [dir]\n", exeFilename);
|
|
||||||
Print(" %s check [dir]\n", exeFilename);
|
|
||||||
Print("\n");
|
|
||||||
Print(" %s sync [dirA] [dirB]\n", exeFilename);
|
|
||||||
Print(" %s resync [dirA] [dirB]\n", exeFilename);
|
|
||||||
Print(" %s synctest [dirA] [dirB]\n", exeFilename);
|
|
||||||
Print(" %s resynctest [dirA] [dirB]\n", exeFilename);
|
|
||||||
Print("\n");
|
|
||||||
Print(" %s copy [dirA] [dirB]\n", exeFilename);
|
|
||||||
Print(" %s recopy [dirA] [dirB]\n", exeFilename);
|
|
||||||
Print(" %s copytest [dirA] [dirB]\n", exeFilename);
|
|
||||||
Print(" %s recopytest [dirA] [dirB]\n", exeFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileNode CheckDir(char *path, int recheck);
|
|
||||||
int Sync(char *pathLeft, char *pathRight, int recheck, int dryRun);
|
|
||||||
int Copy(char *pathLeft, char *pathRight, int reCheck, int dryRun);
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if (argc < 2) {
|
|
||||||
Help(argv[0]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Print("\n================================ FileSync "
|
|
||||||
"===================================\n");
|
|
||||||
if (!strcmp(argv[1], "info") && argc >= 3) {
|
|
||||||
// Informacion de ficheros
|
|
||||||
int i;
|
|
||||||
for (i = 2; i < argc; i++) {
|
|
||||||
if (File_ExistsPath(argv[i])) {
|
|
||||||
FileNode fileNode = FileNode_Build(argv[i]);
|
|
||||||
FileNode_LoadCRC(fileNode, argv[i]);
|
|
||||||
FileNode_PrintNode(fileNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!strcmp(argv[1], "scan") && argc == 4) {
|
|
||||||
// Scan directory information tree and save
|
|
||||||
long long tScan = Time_GetTime();
|
|
||||||
FileNode fileNode;
|
|
||||||
Print("Building FileNode..\n");
|
|
||||||
fileNode = FileNode_Build(argv[2]);
|
|
||||||
tScan = Time_GetTime() - tScan;
|
|
||||||
Print("\ttScan :");
|
|
||||||
PrintElapsedTime(tScan);
|
|
||||||
Print("\n");
|
|
||||||
FileNode_Save(fileNode, argv[3]);
|
|
||||||
} else if (!strcmp(argv[1], "rescan") && argc == 4) {
|
|
||||||
// Scan directory information and save tree
|
|
||||||
FileNode fileNode;
|
|
||||||
Print("Loading FileNode..\n");
|
|
||||||
fileNode = FileNode_Load(argv[3]);
|
|
||||||
if (fileNode) {
|
|
||||||
Print("Rebuilding FileNode..\n");
|
|
||||||
long long tScan = Time_GetTime();
|
|
||||||
fileNode = FileNode_Refresh(fileNode, argv[2]);
|
|
||||||
tScan = Time_GetTime() - tScan;
|
|
||||||
Print("\ttScan :");
|
|
||||||
PrintElapsedTime(tScan);
|
|
||||||
Print("\n");
|
|
||||||
FileNode_Save(fileNode, argv[3]);
|
|
||||||
} else {
|
|
||||||
Print("Building FileNode..\n");
|
|
||||||
long long tScan = Time_GetTime();
|
|
||||||
fileNode = FileNode_Build(argv[2]);
|
|
||||||
tScan = Time_GetTime() - tScan;
|
|
||||||
Print("\ttScan :");
|
|
||||||
PrintElapsedTime(tScan);
|
|
||||||
Print("\n");
|
|
||||||
FileNode_Save(fileNode, argv[3]);
|
|
||||||
}
|
|
||||||
} else if (!strcmp(argv[1], "read") && argc >= 3) {
|
|
||||||
// Read information tree from file
|
|
||||||
FileNode fileNode;
|
|
||||||
fileNode = FileNode_Load(argv[2]);
|
|
||||||
if (fileNode)
|
|
||||||
FileNode_Print(fileNode);
|
|
||||||
} else if (!strcmp(argv[1], "dir") && argc == 3) {
|
|
||||||
// Read directory information tree
|
|
||||||
char *path = argv[2];
|
|
||||||
FileNode fileNode;
|
|
||||||
|
|
||||||
fileNode = CheckDir(path, 1);
|
|
||||||
if (fileNode) {
|
|
||||||
FileNode_Print(fileNode);
|
|
||||||
}
|
|
||||||
} else if (!strcmp(argv[1], "check") && argc == 3) {
|
|
||||||
// Read directory information tree
|
|
||||||
char *path = argv[2];
|
|
||||||
FileNode fileNode;
|
|
||||||
|
|
||||||
fileNode = CheckDir(path, 1);
|
|
||||||
} else if (argc == 4) {
|
|
||||||
char *cmd = argv[1];
|
|
||||||
char *pathLeft = argv[2];
|
|
||||||
char *pathRight = argv[3];
|
|
||||||
if (!strcmp(cmd, "sync")) {
|
|
||||||
Sync(pathLeft, pathRight, 1, 0);
|
|
||||||
} else if (!strcmp(cmd, "resync")) {
|
|
||||||
Sync(pathLeft, pathRight, 0, 0);
|
|
||||||
} else if (!strcmp(cmd, "synctest")) {
|
|
||||||
Sync(pathLeft, pathRight, 1, 1);
|
|
||||||
} else if (!strcmp(cmd, "resynctest")) {
|
|
||||||
Sync(pathLeft, pathRight, 0, 1);
|
|
||||||
} else if (!strcmp(cmd, "copy")) {
|
|
||||||
Copy(pathLeft, pathRight, 1, 0);
|
|
||||||
} else if (!strcmp(cmd, "recopy")) {
|
|
||||||
Copy(pathLeft, pathRight, 0, 0);
|
|
||||||
} else if (!strcmp(cmd, "copytest")) {
|
|
||||||
Copy(pathLeft, pathRight, 1, 1);
|
|
||||||
} else if (!strcmp(cmd, "recopytest")) {
|
|
||||||
Copy(pathLeft, pathRight, 0, 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Help(argv[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileNode CheckDir(char *path, int recheck) {
|
FileNode CheckDir(char *path, int recheck) {
|
||||||
char dirNodesFile[MaxPath];
|
char dirNodesFile[MaxPath];
|
||||||
FileNode fileNode;
|
FileNode fileNode;
|
||||||
@@ -288,4 +161,174 @@ int Copy(char *pathLeft, char *pathRight, int reCheck, int dryRun) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct SApplicationConfiguration TApplicationConfiguration, *ApplicationConfiguration;
|
||||||
|
struct SApplicationConfiguration {
|
||||||
|
char *Dirs[10];
|
||||||
|
bool NoScan;
|
||||||
|
bool Dummy;
|
||||||
|
bool Sync;
|
||||||
|
bool Copy;
|
||||||
|
bool NoAction;
|
||||||
|
char *Log;
|
||||||
|
};
|
||||||
|
TApplicationConfiguration defaultConfig = { {NULL}, false, false, false, false, false, NULL };
|
||||||
|
|
||||||
|
bool SetParam_Dir(int argc, char *argv[], void *data) {
|
||||||
|
ApplicationConfiguration config = (ApplicationConfiguration)data;
|
||||||
|
if (File_ExistsPath(argv[0]) == 0) {
|
||||||
|
Print("Error: Path \"%s\" does not exist.\n", argv[0]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char **destDir = config->Dirs;
|
||||||
|
while (destDir[0] != NULL) { destDir++; }
|
||||||
|
destDir[0] = argv[0];
|
||||||
|
destDir++;
|
||||||
|
destDir = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetParam_NoCheck(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->NoScan = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetParam_Dummy(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->Dummy = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetParam_Sync(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->Sync = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetParam_Copy(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->Copy = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetParam_Log(int argc, char *argv[], void *data) {
|
||||||
|
ApplicationConfiguration config = (ApplicationConfiguration)data;
|
||||||
|
config->Log = argv[0];
|
||||||
|
Print_SetOutFile(config->Log);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Func_Scan(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->NoAction = true;
|
||||||
|
|
||||||
|
// Scan directory information tree and save
|
||||||
|
long long tScan = Time_GetTime();
|
||||||
|
FileNode fileNode;
|
||||||
|
Print("Building FileNode..\n");
|
||||||
|
fileNode = FileNode_Build(argv[0]);
|
||||||
|
tScan = Time_GetTime() - tScan;
|
||||||
|
Print("\ttScan :");
|
||||||
|
PrintElapsedTime(tScan);
|
||||||
|
Print("\n");
|
||||||
|
FileNode_Save(fileNode, argv[1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Func_Rescan(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->NoAction = true;
|
||||||
|
|
||||||
|
// Scan directory information and save tree
|
||||||
|
FileNode fileNode;
|
||||||
|
Print("Loading FileNode..\n");
|
||||||
|
fileNode = FileNode_Load(argv[1]);
|
||||||
|
if (fileNode) {
|
||||||
|
Print("Rebuilding FileNode..\n");
|
||||||
|
long long tScan = Time_GetTime();
|
||||||
|
fileNode = FileNode_Refresh(fileNode, argv[0]);
|
||||||
|
tScan = Time_GetTime() - tScan;
|
||||||
|
Print("\ttScan :");
|
||||||
|
PrintElapsedTime(tScan);
|
||||||
|
Print("\n");
|
||||||
|
FileNode_Save(fileNode, argv[1]);
|
||||||
|
} else {
|
||||||
|
Print("Building FileNode..\n");
|
||||||
|
long long tScan = Time_GetTime();
|
||||||
|
fileNode = FileNode_Build(argv[0]);
|
||||||
|
tScan = Time_GetTime() - tScan;
|
||||||
|
Print("\ttScan :");
|
||||||
|
PrintElapsedTime(tScan);
|
||||||
|
Print("\n");
|
||||||
|
FileNode_Save(fileNode, argv[1]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Func_Read(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->NoAction = true;
|
||||||
|
|
||||||
|
// Read information tree from file
|
||||||
|
FileNode fileNode;
|
||||||
|
fileNode = FileNode_Load(argv[0]);
|
||||||
|
if (fileNode) {
|
||||||
|
FileNode_Print(fileNode);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Func_Check(int argc, char *argv[], void *data) {
|
||||||
|
((ApplicationConfiguration)data)->NoAction = true;
|
||||||
|
|
||||||
|
// Read directory information tree
|
||||||
|
char *path = argv[0];
|
||||||
|
FileNode fileNode;
|
||||||
|
|
||||||
|
fileNode = CheckDir(path, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TParameterOperation _parameterOperations[] = {
|
||||||
|
{ "dir", 1, "Specify a directory", SetParam_Dir },
|
||||||
|
{ "nocheck", 0, "Do not check for changes on directories", SetParam_NoCheck },
|
||||||
|
{ "dummy", 0, "Do not perform operations", SetParam_Dummy },
|
||||||
|
{ "copy", 0, "Copy first directory to second directory", SetParam_Copy },
|
||||||
|
{ "sync", 0, "Synchronize between two directories", SetParam_Sync },
|
||||||
|
{ "log", 1, "Log actions to file", SetParam_Log },
|
||||||
|
|
||||||
|
{ "scan", 2, "Scan directory and save to filenode file", Func_Rescan },
|
||||||
|
{ "rescan", 2, "Rescan directory and save to filenode file", Func_Rescan },
|
||||||
|
{ "read", 1, "Read filenode file", Func_Read },
|
||||||
|
{ "check", 1, "Check changes on a directory", Func_Check },
|
||||||
|
|
||||||
|
{ NULL, 0, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
TApplicationConfiguration config = defaultConfig;
|
||||||
|
|
||||||
|
int parameterParsingResult = ParameterOperation_Parse(argc, argv, _parameterOperations, &config);
|
||||||
|
if (parameterParsingResult <= 0) {
|
||||||
|
ParameterOperation_PrintHelp(_parameterOperations);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (config.NoAction) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print("\n================================ FileSync ===================================\n");
|
||||||
|
|
||||||
|
if (config.Copy == false && config.Sync == false) {
|
||||||
|
Print("Error: Action not specified.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (config.Dirs[0] == NULL || config.Dirs[1] == NULL) {
|
||||||
|
Print("Error: Two directories are needed.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (config.Copy) {
|
||||||
|
Copy(config.Dirs[0], config.Dirs[1], (config.NoScan == false), config.Dummy);
|
||||||
|
}
|
||||||
|
if (config.Sync) {
|
||||||
|
Sync(config.Dirs[0], config.Dirs[1], (config.NoScan == false), config.Dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
58
src/parameteroperation.c
Normal file
58
src/parameteroperation.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "util.h"
|
||||||
|
#include "parameteroperation.h"
|
||||||
|
|
||||||
|
int ParameterOperation_Parse(int argumentCount, char *arguments[], TParameterOperation parameterOperations[], void *data) {
|
||||||
|
int processedParams = 0;
|
||||||
|
char **currentArguments = arguments + 1;
|
||||||
|
for (int i = 1; i < argumentCount; i++) {
|
||||||
|
char *currentArgument = currentArguments[0];
|
||||||
|
currentArguments++;
|
||||||
|
if (currentArgument[0] != '-') {
|
||||||
|
Print("Error: Garbage found \"%s\" in position %d.\n", arguments[i], i + 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while (currentArgument[0] == '-') {
|
||||||
|
currentArgument++;
|
||||||
|
}
|
||||||
|
bool processed = false;
|
||||||
|
int j = 0;
|
||||||
|
while (parameterOperations[j].Name != NULL) {
|
||||||
|
ParameterOperation parameterOperation = ¶meterOperations[j];
|
||||||
|
if (String_CompareCaseInsensitive(currentArgument, parameterOperation->Name) == 0) {
|
||||||
|
if ((i + parameterOperation->NumItems) >= argumentCount) {
|
||||||
|
Print("Error: Parsing parameter \"-%s\" in position %d, missig parameter data.\n", parameterOperations[j].Name, i + 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bool result = parameterOperation->SetFunc(parameterOperation->NumItems, currentArguments, data);
|
||||||
|
if (result == false) {
|
||||||
|
Print("Error: Parsing parameter \"-%s\" in position %d.\n", parameterOperations[j].Name, i + 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
currentArguments += parameterOperation->NumItems;
|
||||||
|
i += parameterOperation->NumItems;
|
||||||
|
processedParams++;
|
||||||
|
processed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (processed == false) {
|
||||||
|
Print("Error: Unknow parameter \"%s\" in position %d.\n", arguments[i], i + 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return processedParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParameterOperation_PrintHelp(TParameterOperation parameterOperations[]) {
|
||||||
|
int i = 0;
|
||||||
|
Print("Parameters:\n");
|
||||||
|
while (parameterOperations[i].Name != NULL) {
|
||||||
|
Print("\t-%s", parameterOperations[i].Name);
|
||||||
|
for (int j = 0; j < parameterOperations[i].NumItems; j++) {
|
||||||
|
Print(" [Item]");
|
||||||
|
}
|
||||||
|
Print(": %s.\n", parameterOperations[i].Description);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/parameteroperation.h
Normal file
18
src/parameteroperation.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _PARAMETEROPERATION_
|
||||||
|
#define _PARAMETEROPERATION_
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
typedef struct SParameterOperation TParameterOperation, *ParameterOperation;
|
||||||
|
struct SParameterOperation {
|
||||||
|
char *Name;
|
||||||
|
int NumItems;
|
||||||
|
char *Description;
|
||||||
|
bool(*SetFunc)(int argumentCount, char *arguments[], void *data);
|
||||||
|
};
|
||||||
|
|
||||||
|
int ParameterOperation_Parse(int argumentCount, char *arguments[], TParameterOperation parameterOperations[], void *data);
|
||||||
|
|
||||||
|
void ParameterOperation_PrintHelp(TParameterOperation parameterOperations[]);
|
||||||
|
|
||||||
|
#endif
|
||||||
51
src/util.c
51
src/util.c
@@ -1,7 +1,9 @@
|
|||||||
#include <stdio.h>
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@@ -13,13 +15,31 @@ char *String_Copy(char *str) {
|
|||||||
char *strnew;
|
char *strnew;
|
||||||
size_t len;
|
size_t len;
|
||||||
len = strlen(str);
|
len = strlen(str);
|
||||||
strnew = malloc(len + 1);
|
strnew = (char *)malloc(len + 1);
|
||||||
if (strnew != NULL) {
|
if (strnew != NULL) {
|
||||||
strcpy(strnew, str);
|
strcpy(strnew, str);
|
||||||
}
|
}
|
||||||
return (strnew);
|
return (strnew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// String_CompareCaseInsensitive
|
||||||
|
//
|
||||||
|
// Compares a string case insensitive
|
||||||
|
int String_CompareCaseInsensitive(char *str0, char *str1) {
|
||||||
|
for (int i = 0; ; i++) {
|
||||||
|
char c0 = tolower(str0[i]);
|
||||||
|
char c1 = tolower(str1[i]);
|
||||||
|
if (c0 != c1) {
|
||||||
|
return (c0 < c1) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c0 == '\0') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if WIN32
|
#if WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
// WIN32
|
// WIN32
|
||||||
@@ -138,21 +158,44 @@ int PrintDataSize(long long size) {
|
|||||||
return Print("% 8.3f TiB", tibSize);
|
return Print("% 8.3f TiB", tibSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILE *outFile = NULL;
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Print_SetOutFile
|
||||||
|
//
|
||||||
|
void Print_SetOutFile(char *fileOut) {
|
||||||
|
if (fileOut == NULL) { return; }
|
||||||
|
outFile = fopen(fileOut, "a");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Print_BuferSize 4096
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Print
|
// Print
|
||||||
//
|
//
|
||||||
// Prints the formated text screen
|
// Prints the formated text screen
|
||||||
int Print(char *fmt, ...) {
|
int Print(char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
char buffer[Print_BuferSize];
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
// Print
|
// Print
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
n = vprintf(fmt, ap);
|
//n = vprintf(fmt, ap);
|
||||||
|
n = vsnprintf(buffer, Print_BuferSize, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
// Flush
|
// Output to stdout
|
||||||
|
fputs(buffer, stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
// Output to outFile
|
||||||
|
if(outFile != NULL){
|
||||||
|
fputs(buffer, outFile);
|
||||||
|
fflush(outFile);
|
||||||
|
}
|
||||||
|
|
||||||
return (n);
|
return (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
src/util.h
15
src/util.h
@@ -4,12 +4,22 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
typedef int bool;
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// String_Copy
|
// String_Copy
|
||||||
//
|
//
|
||||||
// Copies a string.
|
// Copies a string.
|
||||||
char *String_Copy(char *str);
|
char *String_Copy(char *str);
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// String_CompareCaseInsensitive
|
||||||
|
//
|
||||||
|
// Compares a string case insensitive
|
||||||
|
int String_CompareCaseInsensitive(char *str0, char *str1);
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Time_GetTime
|
// Time_GetTime
|
||||||
//
|
//
|
||||||
@@ -40,6 +50,11 @@ int PrintElapsedTime(long long time);
|
|||||||
// Prints the data size (input in bytes)
|
// Prints the data size (input in bytes)
|
||||||
int PrintDataSize(long long size);
|
int PrintDataSize(long long size);
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Print_SetOutFile
|
||||||
|
//
|
||||||
|
void Print_SetOutFile(char *fileOut);
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Print
|
// Print
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -16,20 +16,20 @@ md %testDir%.B
|
|||||||
|
|
||||||
echo:Uno> %testDir%.A\Uno.txt
|
echo:Uno> %testDir%.A\Uno.txt
|
||||||
echo:Dos> %testDir%.A\Dos.txt
|
echo:Dos> %testDir%.A\Dos.txt
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
del %testDir%.A\Uno.txt
|
del %testDir%.A\Uno.txt
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
ping 127.0.0.1 -n 2 > nul
|
ping 127.0.0.1 -n 2 > nul
|
||||||
|
|
||||||
echo:UnoRepuesto> %testDir%.A\Uno.txt
|
echo:UnoRepuesto> %testDir%.A\Uno.txt
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
..\filesync.exe read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
||||||
..\filesync.exe read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
||||||
|
|
||||||
:: Check test results
|
:: Check test results
|
||||||
|
|
||||||
|
|||||||
@@ -16,16 +16,16 @@ md %testDir%.B
|
|||||||
|
|
||||||
echo:Uno> %testDir%.A\Uno.txt
|
echo:Uno> %testDir%.A\Uno.txt
|
||||||
echo:Dos> %testDir%.A\Dos.txt
|
echo:Dos> %testDir%.A\Dos.txt
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
md %testDir%.A\dirUno
|
md %testDir%.A\dirUno
|
||||||
move %testDir%.A\Uno.txt %testDir%.A\dirUno\Uno.txt >NUL
|
move %testDir%.A\Uno.txt %testDir%.A\dirUno\Uno.txt >NUL
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
..\filesync.exe read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
||||||
..\filesync.exe read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
||||||
|
|
||||||
:: Check test results
|
:: Check test results
|
||||||
|
|
||||||
|
|||||||
@@ -16,22 +16,22 @@ md %testDir%.B
|
|||||||
|
|
||||||
echo:Uno> %testDir%.A\Uno.txt
|
echo:Uno> %testDir%.A\Uno.txt
|
||||||
echo:Dos> %testDir%.A\Dos.txt
|
echo:Dos> %testDir%.A\Dos.txt
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
md %testDir%.A\dirUno
|
md %testDir%.A\dirUno
|
||||||
move %testDir%.A\Uno.txt %testDir%.A\dirUno\Uno.txt >NUL
|
move %testDir%.A\Uno.txt %testDir%.A\dirUno\Uno.txt >NUL
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
ping 127.0.0.1 -n 2 > nul
|
ping 127.0.0.1 -n 2 > nul
|
||||||
|
|
||||||
move %testDir%.A\dirUno\Uno.txt %testDir%.A\Uno.txt >NUL
|
move %testDir%.A\dirUno\Uno.txt %testDir%.A\Uno.txt >NUL
|
||||||
rd %testDir%.A\dirUno
|
rd %testDir%.A\dirUno
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
..\filesync.exe read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
||||||
..\filesync.exe read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
||||||
|
|
||||||
:: Check test results
|
:: Check test results
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,17 @@ md %testDir%.B
|
|||||||
|
|
||||||
echo:Uno> %testDir%.A\Uno.txt
|
echo:Uno> %testDir%.A\Uno.txt
|
||||||
echo:Dos> %testDir%.A\Dos.txt
|
echo:Dos> %testDir%.A\Dos.txt
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
ping 127.0.0.1 -n 2 > nul
|
ping 127.0.0.1 -n 2 > nul
|
||||||
|
|
||||||
echo:Updated>> %testDir%.A\Uno.txt
|
echo:Updated>> %testDir%.A\Uno.txt
|
||||||
..\filesync.exe sync %testDir%.A %testDir%.B >> %testDir%.txt
|
..\filesync.exe -sync -dir %testDir%.A -dir %testDir%.B >> %testDir%.txt
|
||||||
|
|
||||||
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
..\filesync.exe read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.A/nodesFile.fs >> %testDir%.txt
|
||||||
..\filesync.exe read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
..\filesync.exe -read %testDir%.B/nodesFile.fs >> %testDir%.txt
|
||||||
|
|
||||||
:: Check test results
|
:: Check test results
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user