New naming conventions to avoid conflicts.

i don't know if it was such a great idea but at least it is a starting point.
This commit is contained in:
Marc
2022-10-09 15:46:58 +02:00
parent 9ee12a6c7e
commit b8affcadbc
26 changed files with 320 additions and 295 deletions
+19
View File
@@ -0,0 +1,19 @@
# Current naming conventions (subject to debate)
## Function names
### shared functions
function should start by the name of their module in camelCase followed by an underscore and the name of the function in camelCase
example:
steam_searchGames()
### static functions
there is no rule for now
## Struct names
function should start by the name of their module in camelCase followed by an underscore and the name of the struct in PascalCase
+4 -4
View File
@@ -8,7 +8,7 @@
#include <stdio.h>
#include <glib.h>
int unzip(char * path, char * outdir) {
int archive_unzip(char * path, char * outdir) {
char * const args[] = {
"unzip",
"-LL", // to lowercase
@@ -35,7 +35,7 @@ int unzip(char * path, char * outdir) {
}
}
int unrar(char * path, char * outdir) {
int archive_unrar(char * path, char * outdir) {
char * const args[] = {
"unrar",
"x",
@@ -63,7 +63,7 @@ int unrar(char * path, char * outdir) {
}
int un7z(char * path, const char * outdir) {
int archive_un7z(char * path, const char * outdir) {
gchar * outParameter = g_strjoin("", "-o", outdir, NULL);
char * const args[] = {
@@ -90,7 +90,7 @@ int un7z(char * path, const char * outdir) {
return returnValue;
}
//make everything lowercase since 7z don't have an argument for that.
casefold(outdir);
file_casefold(outdir);
return returnValue;
}
}
+3 -3
View File
@@ -9,7 +9,7 @@
* @param outdir output director
* @return int return code
*/
int unzip(char * path, char * outdir);
int archive_unzip(char * path, char * outdir);
/**
* @brief Execute the unrar command
@@ -17,7 +17,7 @@ int unzip(char * path, char * outdir);
* @param outdir output director
* @return int return code
*/
int unrar(char * path, char * outdir);
int archive_unrar(char * path, char * outdir);
/**
* @brief Execute the 7z command
@@ -25,6 +25,6 @@ int unrar(char * path, char * outdir);
* @param outdir output director
* @return int return code
*/
int un7z(char * path, const char * outdir);
int archive_un7z(char * path, const char * outdir);
#endif
+14 -14
View File
@@ -19,7 +19,7 @@ static u_int32_t countSetBits(u_int32_t n) {
//TODO: add interruption support
//simplest way to copy a file in c(linux)
int copy(const char * path, const char * dest, u_int32_t flags) {
int file_copy(const char * path, const char * dest, u_int32_t flags) {
int flagCount = countSetBits(flags);
if(flagCount > 3) {
fprintf(stderr, "Invalid flags for cp command\n");
@@ -34,15 +34,15 @@ int copy(const char * path, const char * dest, u_int32_t flags) {
strcpy(args[2], dest);
int argIndex = 3;
if(flags & CP_LINK) {
if(flags & FILE_CP_LINK) {
args[argIndex] = "--link";
argIndex += 1;
}
if(flags & CP_RECURSIVE) {
if(flags & FILE_CP_RECURSIVE) {
args[argIndex] = "-r";
argIndex += 1;
}
if(flags & CP_NO_TARGET_DIR) {
if(flags & FILE_CP_NO_TARGET_DIR) {
args[argIndex] = "-T";
argIndex += 1;
}
@@ -61,7 +61,7 @@ int copy(const char * path, const char * dest, u_int32_t flags) {
}
}
int delete(const char * path, bool recursive) {
int file_delete(const char * path, bool recursive) {
int pid = fork();
if(pid == 0) {
if(recursive) {
@@ -77,7 +77,7 @@ int delete(const char * path, bool recursive) {
}
}
int move(const char * source, const char * destination) {
int file_move(const char * source, const char * destination) {
int pid = fork();
if(pid == 0) {
execl("/bin/mv", "/bin/mv", source, destination, NULL);
@@ -92,7 +92,7 @@ int move(const char * source, const char * destination) {
//rename a folder and all subfolder and files to lowercase
//TODO: error handling
void casefold(const char * folder) {
void file_casefold(const char * folder) {
DIR * d = opendir(folder);
struct dirent *dir;
if (d) {
@@ -108,7 +108,7 @@ void casefold(const char * folder) {
if(strcmp(destinationName, dir->d_name) != 0) {
int result = move(file, destination);
int result = file_move(file, destination);
if(result != EXIT_SUCCESS) {
fprintf(stderr, "Move failed: %s => %s \n", dir->d_name, destinationName);
}
@@ -119,7 +119,7 @@ void casefold(const char * folder) {
g_free(destinationName);
if(dir->d_type == DT_DIR) {
casefold(destination);
file_casefold(destination);
}
g_free(destination);
@@ -129,7 +129,7 @@ void casefold(const char * folder) {
}
}
const char * extractLastPart(const char * filePath, const char delimeter) {
const char * file_extractLastPart(const char * filePath, const char delimeter) {
const int length = strlen(filePath);
long index = -1;
for(long i= length - 1; i >= 0; i--) {
@@ -143,10 +143,10 @@ const char * extractLastPart(const char * filePath, const char delimeter) {
return &filePath[index];
}
const char * extractExtension(const char * filePath) {
return extractLastPart(filePath, '.');
const char * file_extractExtension(const char * filePath) {
return file_extractLastPart(filePath, '.');
}
const char * extractFileName(const char * filePath) {
return extractLastPart(filePath, '/');
const char * file_extractFileName(const char * filePath) {
return file_extractLastPart(filePath, '/');
}
+11 -11
View File
@@ -7,10 +7,10 @@
//valid copy flags
#define cp_DEFAULT 0
#define CP_LINK 1
#define CP_RECURSIVE 2
#define CP_NO_TARGET_DIR 4
#define FILE_CP_DEFAULT 0
#define FILE_CP_LINK 1
#define FILE_CP_RECURSIVE 2
#define FILE_CP_NO_TARGET_DIR 4
/**
* @brief execute the cp command from the source to the dest
@@ -19,7 +19,7 @@
* @param flags refer to the "valid copy flags" use them like this CP_LINK | CP_RECURSIVE
* @return cp return value
*/
int copy(const char * source, const char * dest, u_int32_t flags);
int file_copy(const char * source, const char * dest, u_int32_t flags);
/**
* @brief execute the cp command from the source to the dest
@@ -28,7 +28,7 @@ int copy(const char * source, const char * dest, u_int32_t flags);
* @param bool enable recursive rm -r
* @return rm return value
*/
int delete(const char * path, bool recursive);
int file_delete(const char * path, bool recursive);
/**
* @brief Run the mv command
@@ -36,30 +36,30 @@ int delete(const char * path, bool recursive);
* @param destination
* @return mv's exit value
*/
int move(const char * source, const char * destination);
int file_move(const char * source, const char * destination);
/**
* @brief Recursively rename all file and folder to lowercase.
*
* @param folder
*/
void casefold(const char * folder);
void file_casefold(const char * folder);
const char * extractLastPart(const char * filePath, const char delimeter);
const char * file_extractLastPart(const char * filePath, const char delimeter);
/**
* @brief Return the extension of a file by looking for the character '.'
* @param filePath
* @return return a pointer to the address after the '.' or null if it was not found;
*/
const char * extractExtension(const char * filePath);
const char * file_extractExtension(const char * filePath);
/**
* @brief Return the file name by looking for the last character '/'
* @param filePath
* @return return a pointer to the address after the last '/' or null if it was not found (the path might not be a path in this case)
*/
const char * extractFileName(const char * filePath);
const char * file_extractFileName(const char * filePath);
#endif
+89 -40
View File
@@ -13,6 +13,7 @@
#include "fomod.h"
#include "file.h"
#include "fomod/fomodTypes.h"
#include "fomod/group.h"
#include "libxml/globals.h"
#include "main.h"
@@ -43,20 +44,20 @@ static int getInputCount(const char * input) {
}
static gint priorityCmp(gconstpointer a, gconstpointer b) {
const FOModFile_t * fileA = (const FOModFile_t *)a;
const FOModFile_t * fileB = (const FOModFile_t *)b;
const fomod_File_t * fileA = (const fomod_File_t *)a;
const fomod_File_t * fileB = (const fomod_File_t *)b;
return fileB->priority - fileA->priority;
}
static void printfOptionsInOrder(FOModGroup_t group) {
static void fomod_printOptionsInOrder(fomod_Group_t group) {
for(int i = 0; i < group.pluginCount; i++) {
printf("%d, %s\n", i, group.plugins[i].name);
printf("%s\n", group.plugins[i].description);
}
}
static gint flagEqual(const FOModFlag_t * a, const FOModFlag_t * b) {
static gint fomod_flagEqual(const fomod_Flag_t * a, const fomod_Flag_t * b) {
int nameCmp = strcmp(a->name, b->name);
if(nameCmp == 0) {
if(strcmp(a->value, b->value) == 0)
@@ -81,7 +82,7 @@ static int stepCmpDesc(const void * stepA, const void * stepB) {
}
static void sortSteps(FOMod_t * fomod) {
static void fomod_sortSteps(FOMod_t * fomod) {
switch(fomod->stepOrder) {
case ASC:
qsort(fomod->steps, fomod->stepCount, sizeof(*fomod->steps), stepCmpAsc);
@@ -95,25 +96,25 @@ static void sortSteps(FOMod_t * fomod) {
}
}
static int groupCmpAsc(const void * stepA, const void * stepB) {
const FOModGroup_t * step1 = (const FOModGroup_t *)stepA;
const FOModGroup_t * step2 = (const FOModGroup_t *)stepB;
static int fomod_groupCmpAsc(const void * stepA, const void * stepB) {
const fomod_Group_t * step1 = (const fomod_Group_t *)stepA;
const fomod_Group_t * step2 = (const fomod_Group_t *)stepB;
return strcmp(step1->name, step2->name);
}
static int groupCmpDesc(const void * stepA, const void * stepB) {
const FOModGroup_t * step1 = (const FOModGroup_t *)stepA;
const FOModGroup_t * step2 = (const FOModGroup_t *)stepB;
static int fomod_groupCmpDesc(const void * stepA, const void * stepB) {
const fomod_Group_t * step1 = (const fomod_Group_t *)stepA;
const fomod_Group_t * step2 = (const fomod_Group_t *)stepB;
return 1 - strcmp(step1->name, step2->name);
}
static void sortGroup(FOModGroup_t * group) {
static void fomod_sortGroup(fomod_Group_t * group) {
switch(group->order) {
case ASC:
qsort(group->plugins, group->pluginCount, sizeof(*group->plugins), groupCmpAsc);
qsort(group->plugins, group->pluginCount, sizeof(*group->plugins), fomod_groupCmpAsc);
break;
case DESC:
qsort(group->plugins, group->pluginCount, sizeof(*group->plugins), groupCmpDesc);
qsort(group->plugins, group->pluginCount, sizeof(*group->plugins), fomod_groupCmpDesc);
break;
case ORD:
//ord mean that we keep the curent order, so no need to sort anything.
@@ -122,7 +123,7 @@ static void sortGroup(FOModGroup_t * group) {
}
//TODO: handle error
error_t processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination) {
error_t fomod_processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination) {
//priority higher a less important and should be processed first.
*pendingFileOperations = g_list_sort(*pendingFileOperations, priorityCmp);
GList * currentFileOperation = *pendingFileOperations;
@@ -130,17 +131,17 @@ error_t processFileOperations(GList ** pendingFileOperations, const char * modFo
while(currentFileOperation != NULL) {
//TODO: support destination
//no using link since priority is made to override files and link is annoying to deal with when overriding files.
const FOModFile_t * file = (const FOModFile_t *)currentFileOperation->data;
const fomod_File_t * file = (const fomod_File_t *)currentFileOperation->data;
char * source = g_build_path("/", modFolder, file->source, NULL);
//fix the / and \ windows - unix paths
fixPath(source);
xml_fixPath(source);
int copyResult;
if(file->isFolder) {
copyResult = copy(source, destination, CP_NO_TARGET_DIR | CP_RECURSIVE);
copyResult = file_copy(source, destination, FILE_CP_NO_TARGET_DIR | FILE_CP_RECURSIVE);
} else {
copyResult = copy(source, destination, 0);
copyResult = file_copy(source, destination, 0);
}
if(copyResult != EXIT_SUCCESS) {
fprintf(stderr, "Copy failed, some file might be corrupted\n");
@@ -152,15 +153,15 @@ error_t processFileOperations(GList ** pendingFileOperations, const char * modFo
return ERR_SUCCESS;
}
GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendingFileOperations) {
GList * fomod_processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendingFileOperations) {
for(int condId = 0; condId < fomod->condFilesCount; condId++) {
const FOModCondFile_t *condFile = &fomod->condFiles[condId];
const fomod_CondFile_t *condFile = &fomod->condFiles[condId];
bool areAllFlagsValid = true;
//checking if all flags are valid
for(long flagId = 0; flagId < condFile->flagCount; flagId++) {
const GList * link = g_list_find_custom(flagList, &(condFile->requiredFlags[flagId]), (GCompareFunc)flagEqual);
const GList * link = g_list_find_custom(flagList, &(condFile->requiredFlags[flagId]), (GCompareFunc)fomod_flagEqual);
if(link == NULL) {
areAllFlagsValid = false;
break;
@@ -169,9 +170,9 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
if(areAllFlagsValid) {
for(long fileId = 0; fileId < condFile->flagCount; fileId++) {
const FOModFile_t * file = &(condFile->files[fileId]);
const fomod_File_t * file = &(condFile->files[fileId]);
FOModFile_t * fileCopy = malloc(sizeof(*file));
fomod_File_t * fileCopy = malloc(sizeof(*file));
*fileCopy = *file;
//changing pathes to lowercase since we used casefold and the pathes in the xml might not like it
@@ -188,10 +189,10 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
return pendingFileOperations;
}
void freeFileOperations(GList * fileOperations) {
void fomod_freeFileOperations(GList * fileOperations) {
GList * fileOperationsStart = fileOperations;
while(fileOperations != NULL) {
FOModFile_t * file = (FOModFile_t *)fileOperations->data;
fomod_File_t * file = (fomod_File_t *)fileOperations->data;
if(file->destination != NULL)free(file->destination);
if(file->source != NULL)free(file->source);
fileOperations = g_list_next(fileOperations);
@@ -200,7 +201,7 @@ void freeFileOperations(GList * fileOperations) {
g_list_free_full(fileOperationsStart, free);
}
error_t installFOMod(const char * modFolder, const char * destination) {
error_t fomod_installFOMod(const char * modFolder, const char * destination) {
//everything should be lowercase since we use casefold() before calling any install function
char * fomodFolder = g_build_path("/", modFolder, "fomod", NULL);
char * fomodFile = g_build_filename(fomodFolder, "moduleconfig.xml", NULL);
@@ -213,7 +214,7 @@ error_t installFOMod(const char * modFolder, const char * destination) {
}
FOMod_t fomod;
int returnValue = parseFOMod(fomodFile, &fomod);
int returnValue = parser_parseFOMod(fomodFile, &fomod);
if(returnValue == ERR_FAILURE)
return ERR_FAILURE;
@@ -222,14 +223,14 @@ error_t installFOMod(const char * modFolder, const char * destination) {
GList * flagList = NULL;
GList * pendingFileOperations = NULL;
sortSteps(&fomod);
fomod_sortSteps(&fomod);
for(int i = 0; i < fomod.stepCount; i++) {
const FOModStep_t * step = &fomod.steps[i];
bool validFlags = true;
for(int flagId = 0; flagId < step->flagCount; flagId++) {
const GList * flagLink = g_list_find_custom(flagList, &step->requiredFlags[flagId], (GCompareFunc)flagEqual);
const GList * flagLink = g_list_find_custom(flagList, &step->requiredFlags[flagId], (GCompareFunc)fomod_flagEqual);
if(flagLink == NULL) {
validFlags = false;
break;
@@ -239,9 +240,9 @@ error_t installFOMod(const char * modFolder, const char * destination) {
if(!validFlags) continue;
for(int groupId = 0; groupId < step->groupCount; groupId++ ) {
FOModGroup_t group = step->groups[groupId];
fomod_Group_t group = step->groups[groupId];
sortGroup(&group);
fomod_sortGroup(&group);
u_int8_t min;
u_int8_t max;
@@ -250,7 +251,7 @@ error_t installFOMod(const char * modFolder, const char * destination) {
size_t bufferSize = 0;
while(true) {
printfOptionsInOrder(group);
fomod_printOptionsInOrder(group);
switch(group.type) {
case ONE_ONLY:
printf("Select one :\n");
@@ -312,16 +313,16 @@ error_t installFOMod(const char * modFolder, const char * destination) {
for(int choiceId = 0; choices[choiceId] != NULL; choiceId++) {
//TODO: safer user input
int choice = atoi(choices[choiceId]);
FOModPlugin_t plugin = group.plugins[choice];
fomod_Plugin_t plugin = group.plugins[choice];
for(int flagId = 0; flagId < plugin.flagCount; flagId++) {
flagList = g_list_append(flagList, &plugin.flags[flagId]);
}
//do the install
for(int pluginId = 0; pluginId < plugin.fileCount; pluginId++) {
const FOModFile_t * file = &plugin.files[pluginId];
const fomod_File_t * file = &plugin.files[pluginId];
FOModFile_t * fileCopy = malloc(sizeof(FOModFile_t));
fomod_File_t * fileCopy = malloc(sizeof(fomod_File_t));
*fileCopy = *file;
//changing pathes to lowercase since we used casefold and the pathes in the xml might not like it
@@ -344,13 +345,61 @@ error_t installFOMod(const char * modFolder, const char * destination) {
//TODO: manage multiple files with the same name
pendingFileOperations = processCondFiles(&fomod, flagList, pendingFileOperations);
processFileOperations(&pendingFileOperations, modFolder, destination);
pendingFileOperations = fomod_processCondFiles(&fomod, flagList, pendingFileOperations);
fomod_processFileOperations(&pendingFileOperations, modFolder, destination);
printf("FOMod successfully installed!\n");
g_list_free(flagList);
freeFileOperations(pendingFileOperations);
freeFOMod(&fomod);
fomod_freeFileOperations(pendingFileOperations);
fomod_freeFOMod(&fomod);
g_free(fomodFolder);
return ERR_SUCCESS;
}
void fomod_freeFOMod(FOMod_t * fomod) {
for(int i = 0; i < fomod->condFilesCount; i++) {
fomod_CondFile_t * condFile = &(fomod->condFiles[i]);
for(long fileId = 0; fileId < condFile->fileCount; fileId++) {
free(condFile->files[fileId].destination);
free(condFile->files[fileId].source);
}
for(long flagId = 0; flagId < condFile->flagCount; flagId++) {
fomod_Flag_t * flag = &(condFile->requiredFlags[flagId]);
free(flag->name);
free(flag->value);
}
free(condFile->files);
free(condFile->requiredFlags);
}
free(fomod->condFiles);
free(fomod->moduleImage);
free(fomod->moduleName);
int size = fomod_countUntilNull(fomod->requiredInstallFiles, sizeof(char **));
for(int i = 0; i < size; i++) {
free(fomod->requiredInstallFiles[i]);
}
free(fomod->requiredInstallFiles);
for(int i = 0; i < fomod->stepCount; i++) {
FOModStep_t * step = &fomod->steps[i];
for(int groupId = 0; groupId < step->groupCount; groupId++) {
fomod_Group_t * group = &step->groups[groupId];
grp_freeGroup(group);
}
for(int flagId = 0; flagId < step->flagCount; flagId++) {
fomod_Flag_t * flag = &(step->requiredFlags[flagId]);
free(flag->name);
free(flag->value);
}
free(step->groups);
free(step->requiredFlags);
free(step->name);
}
free(fomod->steps);
//set every counter to zero and every pointer to null
memset(fomod, 0, sizeof(FOMod_t));
}
+11 -4
View File
@@ -16,7 +16,7 @@
* @param destination folder of the new mod that contains the result of the fomod process.
* @return int
*/
error_t installFOMod(const char * modFolder, const char * destination);
error_t fomod_installFOMod(const char * modFolder, const char * destination);
/**
* @brief In fomod there is file operations which depends on multiple flags this function find the ones that mach our current flags and append them to a list.
@@ -26,7 +26,7 @@ error_t installFOMod(const char * modFolder, const char * destination);
* @param pendingFileOperations a list of pending FOModFile_t operation to which add the new ones. (can be null)
* @return a list of pendingFileOperations(FOModFile_t)
*/
GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendingFileOperations) __attribute__((warn_unused_result));
GList * fomod_processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendingFileOperations) __attribute__((warn_unused_result));
/**
* @brief FOModFile_t have a priority option and this function execute the file operation while taking this into account.
@@ -36,13 +36,20 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
* @param destination folder of the new mod that contains the result of the process.
* @return error code
*/
error_t processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination);
error_t fomod_processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination);
/**
* @brief
*
* @param fileOperations
*/
void freeFileOperations(GList * fileOperations);
void fomod_freeFileOperations(GList * fileOperations);
/**
* @brief Free content of a fomod file.
* @param fomod
*/
void fomod_freeFOMod(FOMod_t * fomod);
#endif
+8 -8
View File
@@ -4,25 +4,25 @@
#include "stdbool.h"
#include "xmlUtil.h"
typedef struct FOModFlag {
typedef struct fomod_Flag {
char * name;
char * value;
} FOModFlag_t;
} fomod_Flag_t;
typedef struct FOModFile {
typedef struct fomod_File {
char * source;
char * destination;
int priority;
bool isFolder;
} FOModFile_t;
} fomod_File_t;
typedef struct FOModCondFile {
FOModFlag_t * requiredFlags;
typedef struct fomod_CondFile {
fomod_Flag_t * requiredFlags;
unsigned int flagCount;
FOModFile_t * files;
fomod_File_t * files;
unsigned int fileCount;
} FOModCondFile_t;
} fomod_CondFile_t;
#endif
+30 -29
View File
@@ -1,4 +1,5 @@
#include "group.h"
#include "fomodTypes.h"
#include "xmlUtil.h"
#include "string.h"
#include <stdlib.h>
@@ -35,11 +36,11 @@ static TypeDescriptor_t getDescriptor(const char * descriptor) {
}
}
void freeGroup(FOModGroup_t * group) {
void grp_freeGroup(fomod_Group_t * group){
free(group->name);
if(group->pluginCount == 0) return;
for(int pluginId = 0; pluginId < group->pluginCount; pluginId++) {
FOModPlugin_t * plugin = &group->plugins[pluginId];
fomod_Plugin_t * plugin = &group->plugins[pluginId];
if(plugin->fileCount > 0) {
for(int i = 0; i < plugin->fileCount; i++) {
free(plugin->files[i].destination);
@@ -65,10 +66,10 @@ void freeGroup(FOModGroup_t * group) {
group->pluginCount = 0;
}
static int parseConditionFlags(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
static int parseConditionFlags(fomod_Plugin_t * plugin, xmlNodePtr nodeElement) {
xmlNodePtr flagNode = nodeElement->children;
while(flagNode != NULL) {
if(!validateNode(&flagNode, true, "flag", NULL)) {
if(!xml_validateNode(&flagNode, true, "flag", NULL)) {
if(plugin->flagCount > 0) {
free(plugin->flags);
}
@@ -77,12 +78,12 @@ static int parseConditionFlags(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
if(flagNode == NULL)continue;
plugin->flagCount += 1;
plugin->flags = realloc(plugin->flags, plugin->flagCount * sizeof(FOModFlag_t));
plugin->flags = realloc(plugin->flags, plugin->flagCount * sizeof(fomod_Flag_t));
FOModFlag_t * flag = &plugin->flags[plugin->flagCount - 1];
fomod_Flag_t * flag = &plugin->flags[plugin->flagCount - 1];
flag->name = freeAndDup(xmlGetProp(flagNode, (const xmlChar *) "name"));
flag->value = freeAndDup(xmlNodeGetContent(flagNode));
flag->name = xml_freeAndDup(xmlGetProp(flagNode, (const xmlChar *) "name"));
flag->value = xml_freeAndDup(xmlNodeGetContent(flagNode));
flagNode = flagNode->next;
}
@@ -90,10 +91,10 @@ static int parseConditionFlags(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
return EXIT_SUCCESS;
}
static int parseGroupFiles(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
static int parseGroupFiles(fomod_Plugin_t * plugin, xmlNodePtr nodeElement) {
xmlNodePtr fileNode = nodeElement->children;
while(fileNode != NULL) {
if(!validateNode(&fileNode, true, "folder", "file", NULL)) {
if(!xml_validateNode(&fileNode, true, "folder", "file", NULL)) {
fprintf(stderr, "Unexpected node in files");
//TODO: free
return EXIT_FAILURE;
@@ -103,11 +104,11 @@ static int parseGroupFiles(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
plugin->fileCount += 1;
plugin->files = realloc(plugin->files, (plugin->fileCount + 1) * sizeof(FOModFile_t));
FOModFile_t * file = &plugin->files[plugin->fileCount - 1];
plugin->files = realloc(plugin->files, (plugin->fileCount + 1) * sizeof(fomod_File_t));
fomod_File_t * file = &plugin->files[plugin->fileCount - 1];
file->destination = freeAndDup(xmlGetProp(fileNode, (const xmlChar *) "destination"));
file->source = freeAndDup(xmlGetProp(fileNode, (const xmlChar *) "source"));
file->destination = xml_freeAndDup(xmlGetProp(fileNode, (const xmlChar *) "destination"));
file->source = xml_freeAndDup(xmlGetProp(fileNode, (const xmlChar *) "source"));
//TODO: test if it's a number
xmlChar * priority = xmlGetProp(fileNode, (const xmlChar *) "priority");
@@ -123,18 +124,18 @@ static int parseGroupFiles(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
return EXIT_SUCCESS;
}
static int parseNodeElement(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
static int parseNodeElement(fomod_Plugin_t * plugin, xmlNodePtr nodeElement) {
if(xmlStrcmp(nodeElement->name, (const xmlChar *) "description") == 0) {
plugin->description = freeAndDup(xmlNodeGetContent(nodeElement));
plugin->description = xml_freeAndDup(xmlNodeGetContent(nodeElement));
} else if(xmlStrcmp(nodeElement->name, (const xmlChar *) "image") == 0) {
plugin->image = freeAndDup(xmlGetProp(nodeElement, (const xmlChar *) "path"));
plugin->image = xml_freeAndDup(xmlGetProp(nodeElement, (const xmlChar *) "path"));
} else if(xmlStrcmp(nodeElement->name, (const xmlChar *) "conditionFlags") == 0) {
return parseConditionFlags(plugin, nodeElement);
} else if(xmlStrcmp(nodeElement->name, (const xmlChar *) "files") == 0) {
return parseGroupFiles(plugin, nodeElement);
} else if(xmlStrcmp(nodeElement->name, (const xmlChar *) "typeDescriptor") == 0) {
xmlNodePtr typeNode = nodeElement->children;
if(!validateNode(&typeNode, true, "type", NULL)) {
if(!xml_validateNode(&typeNode, true, "type", NULL)) {
fprintf(stderr, "Unexpected node in typeDescriptor");
return EXIT_FAILURE;
}
@@ -145,29 +146,29 @@ static int parseNodeElement(FOModPlugin_t * plugin, xmlNodePtr nodeElement) {
return EXIT_SUCCESS;
}
int parseGroup(xmlNodePtr groupNode, FOModGroup_t* group) {
int grp_parseGroup(xmlNodePtr groupNode, fomod_Group_t* group) {
xmlNodePtr pluginsNode = groupNode->children;
if(!validateNode(&pluginsNode, true, "plugins", NULL)) {
if(!xml_validateNode(&pluginsNode, true, "plugins", NULL)) {
return EXIT_FAILURE;
}
group->name = freeAndDup(xmlGetProp( groupNode, (const xmlChar *) "name"));
group->name = xml_freeAndDup(xmlGetProp( groupNode, (const xmlChar *) "name"));
xmlChar * type = xmlGetProp(groupNode, (const xmlChar *) "type");
group->type = getGroupType((const char *)type);
xmlFree(type);
char * order = (char *) xmlGetProp(pluginsNode, (const xmlChar *) "order");
group->order = getFOModOrder(order);
group->order = fomod_getOrder(order);
xmlFree(order);
FOModPlugin_t * plugins = NULL;
fomod_Plugin_t * plugins = NULL;
int pluginCount = 0;
xmlNodePtr currentPlugin = pluginsNode->children;
while(currentPlugin != NULL) {
if(!validateNode(&currentPlugin, true, "plugin", NULL)) {
if(!xml_validateNode(&currentPlugin, true, "plugin", NULL)) {
//TODO handle error;
printf("%d\n", __LINE__);
exit(EXIT_FAILURE);
@@ -177,12 +178,12 @@ int parseGroup(xmlNodePtr groupNode, FOModGroup_t* group) {
pluginCount += 1;
plugins = realloc(plugins, pluginCount * sizeof(FOModPlugin_t));
FOModPlugin_t * plugin = &plugins[pluginCount - 1];
plugins = realloc(plugins, pluginCount * sizeof(fomod_Plugin_t));
fomod_Plugin_t * plugin = &plugins[pluginCount - 1];
//initialise everything to 0 and null pointers
memset(plugin, 0, sizeof(FOModPlugin_t));
memset(plugin, 0, sizeof(fomod_Plugin_t));
plugin->name = freeAndDup(xmlGetProp(currentPlugin, (const xmlChar *) "name"));
plugin->name = xml_freeAndDup(xmlGetProp(currentPlugin, (const xmlChar *) "name"));
xmlNodePtr nodeElement = currentPlugin->children;
while(nodeElement != NULL) {
@@ -203,6 +204,6 @@ failure:
//we need to free all of our allocations since we can't expect ou parent function to know what we allocated and what we haven't.
group->plugins = plugins;
group->pluginCount = pluginCount;
freeGroup(group);
grp_freeGroup(group);
return EXIT_FAILURE;
}
+11 -10
View File
@@ -3,32 +3,33 @@
#include <libxml/parser.h>
#include "fomodTypes.h"
#include "xmlUtil.h"
typedef enum GroupType_t { ONE_ONLY, ANY, AT_LEAST_ONE, AT_MOST_ONE, ALL } GroupType_t;
typedef enum TypeDescriptor { OPTIONAL, MAYBE_USABLE, NOT_USABLE, REQUIRED, RECOMMENDED } TypeDescriptor_t;
typedef struct FOModPlugin {
typedef struct fomod_Plugin {
char * description;
char * image;
FOModFlag_t * flags;
fomod_Flag_t * flags;
int flagCount;
FOModFile_t * files;
fomod_File_t * files;
int fileCount;
TypeDescriptor_t type;
char * name;
} FOModPlugin_t;
} fomod_Plugin_t;
//combine group and "plugins"
typedef struct FOModGroup {
FOModPlugin_t * plugins;
typedef struct fomod_Group {
fomod_Plugin_t * plugins;
int pluginCount;
GroupType_t type;
char * name;
FOModOrder_t order;
} FOModGroup_t;
fomod_Order_t order;
} fomod_Group_t;
int parseGroup(xmlNodePtr groupNode, FOModGroup_t* group);
void freeGroup(FOModGroup_t * group);
int grp_parseGroup(xmlNodePtr groupNode, fomod_Group_t* group);
void grp_freeGroup(fomod_Group_t * group);
#endif
+35 -81
View File
@@ -1,63 +1,17 @@
#include "parser.h"
#include "fomodTypes.h"
#include "group.h"
#include "libxml/tree.h"
#include "xmlUtil.h"
#include <stdlib.h>
#include <string.h>
//Maybe integrate this into the rest of the code instead of freeing after the fact
void freeFOMod(FOMod_t * fomod) {
for(int i = 0; i < fomod->condFilesCount; i++) {
FOModCondFile_t * condFile = &(fomod->condFiles[i]);
for(long fileId = 0; fileId < condFile->fileCount; fileId++) {
free(condFile->files[fileId].destination);
free(condFile->files[fileId].source);
}
for(long flagId = 0; flagId < condFile->flagCount; flagId++) {
FOModFlag_t * flag = &(condFile->requiredFlags[flagId]);
free(flag->name);
free(flag->value);
}
free(condFile->files);
free(condFile->requiredFlags);
}
free(fomod->condFiles);
free(fomod->moduleImage);
free(fomod->moduleName);
int size = countUntilNull(fomod->requiredInstallFiles, sizeof(char **));
for(int i = 0; i < size; i++) {
free(fomod->requiredInstallFiles[i]);
}
free(fomod->requiredInstallFiles);
for(int i = 0; i < fomod->stepCount; i++) {
FOModStep_t * step = &fomod->steps[i];
for(int groupId = 0; groupId < step->groupCount; groupId++) {
FOModGroup_t * group = &step->groups[groupId];
freeGroup(group);
}
for(int flagId = 0; flagId < step->flagCount; flagId++) {
FOModFlag_t * flag = &(step->requiredFlags[flagId]);
free(flag->name);
free(flag->value);
}
free(step->groups);
free(step->requiredFlags);
free(step->name);
}
free(fomod->steps);
//set every counter to zero and every pointer to null
memset(fomod, 0, sizeof(FOMod_t));
}
static int parseVisibleNode(xmlNodePtr node, FOModStep_t * step) {
xmlNodePtr requiredFlagsNode = node->children;
while (requiredFlagsNode != NULL) {
if(!validateNode(&requiredFlagsNode, true, "flagDependency", NULL)) {
if(!xml_validateNode(&requiredFlagsNode, true, "flagDependency", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
return EXIT_FAILURE;
@@ -66,10 +20,10 @@ static int parseVisibleNode(xmlNodePtr node, FOModStep_t * step) {
if(requiredFlagsNode == NULL)break;
step->flagCount += 1;
step->requiredFlags = realloc(step->requiredFlags, step->flagCount * sizeof(FOModFlag_t));
FOModFlag_t * flag = &(step->requiredFlags[step->flagCount - 1]);
flag->name = freeAndDup(xmlGetProp(requiredFlagsNode, (const xmlChar *) "flag"));
flag->value = freeAndDup(xmlGetProp(requiredFlagsNode, (const xmlChar *) "value"));
step->requiredFlags = realloc(step->requiredFlags, step->flagCount * sizeof(fomod_Flag_t));
fomod_Flag_t * flag = &(step->requiredFlags[step->flagCount - 1]);
flag->name = xml_freeAndDup(xmlGetProp(requiredFlagsNode, (const xmlChar *) "flag"));
flag->value = xml_freeAndDup(xmlGetProp(requiredFlagsNode, (const xmlChar *) "value"));
requiredFlagsNode = requiredFlagsNode->next;
}
@@ -79,11 +33,11 @@ static int parseVisibleNode(xmlNodePtr node, FOModStep_t * step) {
static int parseOptionalFileGroup(xmlNodePtr node, FOModStep_t * step) {
xmlChar * optionOrder = xmlGetProp(node, (const xmlChar *)"order");
step->optionOrder = getFOModOrder((char *)optionOrder);
step->optionOrder = fomod_getOrder((char *)optionOrder);
xmlFree(optionOrder);
xmlNodePtr group = node->children;
while(group != NULL) {
if(!validateNode(&group, true, "group", NULL)) {
if(!xml_validateNode(&group, true, "group", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
return EXIT_FAILURE;
@@ -92,8 +46,8 @@ static int parseOptionalFileGroup(xmlNodePtr node, FOModStep_t * step) {
if(group == NULL)break;
step->groupCount += 1;
step->groups = realloc(step->groups, step->groupCount * sizeof(FOModGroup_t));
int status = parseGroup(group, &step->groups[step->groupCount - 1]);
step->groups = realloc(step->groups, step->groupCount * sizeof(fomod_Group_t));
int status = grp_parseGroup(group, &step->groups[step->groupCount - 1]);
if(status != EXIT_SUCCESS) {
//TODO: handle error
@@ -113,7 +67,7 @@ static FOModStep_t * parseInstallSteps(xmlNodePtr installStepsNode, int * stepCo
xmlNodePtr stepNode = installStepsNode->children;
while(stepNode != NULL) {
//skipping the text node
if(!validateNode(&stepNode, true, "installStep", NULL)) {
if(!xml_validateNode(&stepNode, true, "installStep", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
exit(EXIT_FAILURE);
@@ -125,7 +79,7 @@ static FOModStep_t * parseInstallSteps(xmlNodePtr installStepsNode, int * stepCo
steps = realloc(steps, *stepCount * sizeof(FOModStep_t));
FOModStep_t * step = &steps[*stepCount - 1];
step->name = freeAndDup(xmlGetProp(stepNode, (const xmlChar *)"name"));
step->name = xml_freeAndDup(xmlGetProp(stepNode, (const xmlChar *)"name"));
step->requiredFlags = NULL;
step->flagCount = 0;
step->groupCount = 0;
@@ -147,10 +101,10 @@ static FOModStep_t * parseInstallSteps(xmlNodePtr installStepsNode, int * stepCo
return steps;
}
static int parseDependencies(xmlNodePtr node, FOModCondFile_t * condFile) {
static int parseDependencies(xmlNodePtr node, fomod_CondFile_t * condFile) {
xmlNodePtr flagNode = node->children;
if(!validateNode(&flagNode, true, "flagDependency", NULL)) {
if(!xml_validateNode(&flagNode, true, "flagDependency", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
return EXIT_FAILURE;
@@ -158,32 +112,32 @@ static int parseDependencies(xmlNodePtr node, FOModCondFile_t * condFile) {
while(flagNode != NULL) {
condFile->flagCount += 1;
condFile->requiredFlags = realloc(condFile->requiredFlags, condFile->flagCount * sizeof(FOModFlag_t));
FOModFlag_t * flag = &(condFile->requiredFlags[condFile->flagCount - 1]);
flag->name = freeAndDup(xmlGetProp(flagNode, (const xmlChar *) "flag"));
flag->value = freeAndDup(xmlGetProp(flagNode, (const xmlChar *) "value"));
condFile->requiredFlags = realloc(condFile->requiredFlags, condFile->flagCount * sizeof(fomod_Flag_t));
fomod_Flag_t * flag = &(condFile->requiredFlags[condFile->flagCount - 1]);
flag->name = xml_freeAndDup(xmlGetProp(flagNode, (const xmlChar *) "flag"));
flag->value = xml_freeAndDup(xmlGetProp(flagNode, (const xmlChar *) "value"));
flagNode = flagNode->next;
}
return EXIT_SUCCESS;
}
static int parseFiles(xmlNodePtr node, FOModCondFile_t * condFile) {
static int parseFiles(xmlNodePtr node, fomod_CondFile_t * condFile) {
xmlNodePtr filesNode = node->children;
while(filesNode != NULL) {
if(!validateNode(&filesNode, true, "folder", "file", NULL)) {
if(!xml_validateNode(&filesNode, true, "folder", "file", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
return EXIT_FAILURE;
}
condFile->fileCount += 1;
condFile->files = realloc(condFile->files, condFile->fileCount * sizeof(FOModFile_t));
FOModFile_t * flag = &(condFile->files[condFile->fileCount - 1]);
flag->source = freeAndDup(xmlGetProp(filesNode, (const xmlChar *) "source"));
flag->destination = freeAndDup(xmlGetProp(filesNode, (const xmlChar *) "destination"));
condFile->files = realloc(condFile->files, condFile->fileCount * sizeof(fomod_File_t));
fomod_File_t * flag = &(condFile->files[condFile->fileCount - 1]);
flag->source = xml_freeAndDup(xmlGetProp(filesNode, (const xmlChar *) "source"));
flag->destination = xml_freeAndDup(xmlGetProp(filesNode, (const xmlChar *) "destination"));
flag->priority = 0;
flag->isFolder = xmlStrcmp(filesNode->name, (xmlChar *) "folder") == 0;
@@ -196,7 +150,7 @@ static int parseFiles(xmlNodePtr node, FOModCondFile_t * condFile) {
static int parseConditionalInstalls(xmlNodePtr node, FOMod_t * fomod) {
xmlNodePtr patterns = node->children;
if(patterns != NULL) {
if(!validateNode(&patterns, true, "patterns", NULL)) {
if(!xml_validateNode(&patterns, true, "patterns", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
return EXIT_FAILURE;
@@ -205,7 +159,7 @@ static int parseConditionalInstalls(xmlNodePtr node, FOMod_t * fomod) {
while(currentPattern != NULL) {
xmlNodePtr patternChild = currentPattern->children;
if(!validateNode(&patternChild, true, "pattern", NULL)) {
if(!xml_validateNode(&patternChild, true, "pattern", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
return EXIT_FAILURE;
@@ -213,8 +167,8 @@ static int parseConditionalInstalls(xmlNodePtr node, FOMod_t * fomod) {
while(patternChild != NULL) {
fomod->condFilesCount += 1;
fomod->condFiles = realloc(fomod->condFiles, fomod->condFilesCount * sizeof(FOModCondFile_t));
FOModCondFile_t * condFile = &(fomod->condFiles[fomod->condFilesCount - 1]);
fomod->condFiles = realloc(fomod->condFiles, fomod->condFilesCount * sizeof(fomod_CondFile_t));
fomod_CondFile_t * condFile = &(fomod->condFiles[fomod->condFilesCount - 1]);
condFile->fileCount = 0;
condFile->files = NULL;
@@ -239,7 +193,7 @@ static int parseConditionalInstalls(xmlNodePtr node, FOMod_t * fomod) {
return EXIT_SUCCESS;
}
error_t parseFOMod(const char * fomodFile, FOMod_t* fomod) {
error_t parser_parseFOMod(const char * fomodFile, FOMod_t* fomod) {
xmlDocPtr doc;
xmlNodePtr cur;
@@ -279,22 +233,22 @@ error_t parseFOMod(const char * fomodFile, FOMod_t* fomod) {
//might cause some issues. when will c finally support utf-8
fomod->moduleName = (char *)cur->content;
} else if(xmlStrcmp(cur->name, (const xmlChar *) "moduleImage") == 0) {
fomod->moduleImage = freeAndDup(xmlGetProp(cur, (const xmlChar *)"path"));
fomod->moduleImage = xml_freeAndDup(xmlGetProp(cur, (const xmlChar *)"path"));
} else if(xmlStrcmp(cur->name, (const xmlChar *)"requiredInstallFiles") == 0) {
//TODO: support non empty destination.
xmlNodePtr requiredInstallFile = cur->children;
while(requiredInstallFile != NULL) {
if(validateNode(&requiredInstallFile, true, "folder", "file", NULL)) {
if(xml_validateNode(&requiredInstallFile, true, "folder", "file", NULL)) {
//TODO: handle error
printf("%d\n", __LINE__);
exit(ERR_FAILURE);
}
int size = countUntilNull(fomod->requiredInstallFiles, sizeof(char **)) + 2;
int size = fomod_countUntilNull(fomod->requiredInstallFiles, sizeof(char **)) + 2;
fomod->requiredInstallFiles = realloc(fomod->requiredInstallFiles, sizeof(char *) * size);
//ensure it is null terminated
fomod->requiredInstallFiles[size - 1] = NULL;
fomod->requiredInstallFiles[size - 2] = freeAndDup(xmlGetProp(requiredInstallFile, (const xmlChar *)"source"));
fomod->requiredInstallFiles[size - 2] = xml_freeAndDup(xmlGetProp(requiredInstallFile, (const xmlChar *)"source"));
requiredInstallFile = cur->children;
}
@@ -306,7 +260,7 @@ error_t parseFOMod(const char * fomodFile, FOMod_t* fomod) {
}
xmlChar * stepOrder = xmlGetProp(cur, (xmlChar *)"order");
fomod->stepOrder = getFOModOrder((char *)stepOrder);
fomod->stepOrder = fomod_getOrder((char *)stepOrder);
xmlFree(stepOrder);
int stepCount = 0;
+7 -12
View File
@@ -2,16 +2,17 @@
#define __FOMOD_PARSER_H__
#include "fomodTypes.h"
#include "group.h"
#include "../main.h"
//combine installStep and optionalFileGroups
typedef struct FOModStep {
FOModOrder_t optionOrder;
FOModGroup_t * groups;
fomod_Order_t optionOrder;
fomod_Group_t * groups;
int groupCount;
char * name;
FOModFlag_t * requiredFlags;
fomod_Flag_t * requiredFlags;
int flagCount;
} FOModStep_t;
@@ -19,10 +20,10 @@ typedef struct FOMod {
char * moduleName;
char * moduleImage;
char ** requiredInstallFiles;
FOModOrder_t stepOrder;
fomod_Order_t stepOrder;
FOModStep_t * steps;
int stepCount;
FOModCondFile_t * condFiles;
fomod_CondFile_t * condFiles;
int condFilesCount;
} FOMod_t;
@@ -32,12 +33,6 @@ typedef struct FOMod {
* @param fomodFile path to the moduleconfig.xml
* @param fomod pointer to a new FOMod_t
*/
error_t parseFOMod(const char * fomodFile, FOMod_t* fomod);
/**
* @brief Free content of a fomod file.
* @param fomod
*/
void freeFOMod(FOMod_t * fomod);
error_t parser_parseFOMod(const char * fomodFile, FOMod_t* fomod);
#endif
+5 -5
View File
@@ -3,13 +3,13 @@
#include <string.h>
#include <sys/types.h>
char * freeAndDup(xmlChar * line) {
char * xml_freeAndDup(xmlChar * line) {
char * free = strdup((const char *) line);
xmlFree(line);
return free;
}
FOModOrder_t getFOModOrder(const char * order) {
fomod_Order_t fomod_getOrder(const char * order) {
if(order == NULL || strcmp(order, "Ascending") == 0) {
return ASC;
} else if(strcmp(order, "Explicit") == 0) {
@@ -21,14 +21,14 @@ FOModOrder_t getFOModOrder(const char * order) {
}
//replace \ in the path by /
void fixPath(char * path) {
void xml_fixPath(char * path) {
while(*path != '\0') {
if(*path == '\\')*path = '/';
path++;
}
}
int countUntilNull(void * pointers, size_t typeSize) {
int fomod_countUntilNull(void * pointers, size_t typeSize) {
int i = 0;
char * arithmetic = (char *)pointers;
while(arithmetic != NULL) {
@@ -40,7 +40,7 @@ int countUntilNull(void * pointers, size_t typeSize) {
//names cannot contain false
//need to be null terminated
bool validateNode(xmlNodePtr * node, bool skipText, const char * names, ...) {
bool xml_validateNode(xmlNodePtr * node, bool skipText, const char * names, ...) {
va_list namesPtr;
while(*node != NULL && xmlStrcmp((*node)->name, (const xmlChar *)"text") == 0) {
+6 -6
View File
@@ -5,7 +5,7 @@
#include <stdbool.h>
typedef enum FOModOrder { ASC, DESC, ORD } FOModOrder_t;
typedef enum FOModOrder { ASC, DESC, ORD } fomod_Order_t;
/**
* @brief
@@ -15,21 +15,21 @@ typedef enum FOModOrder { ASC, DESC, ORD } FOModOrder_t;
* @param names variadic of the valid names.
* @return return true if it found a valid node
*/
bool validateNode(xmlNodePtr * node, bool skipText, const char * names, ...);
bool xml_validateNode(xmlNodePtr * node, bool skipText, const char * names, ...);
/**
* @brief Free memory of and xmlChar and return a strdup version. just to make sure there is nothing remaining in libxml
*/
char * freeAndDup(xmlChar * line);
char * xml_freeAndDup(xmlChar * line);
FOModOrder_t getFOModOrder(const char * order);
fomod_Order_t fomod_getOrder(const char * order);
/**
* @brief replace / by \
* @param path
*/
void fixPath(char * path);
void xml_fixPath(char * path);
/**
* @brief Count the number of step before null
@@ -38,6 +38,6 @@ void fixPath(char * path);
* @param typeSize size of each element of the list
* @return size
*/
int countUntilNull(void * pointers, size_t typeSize);
int fomod_countUntilNull(void * pointers, size_t typeSize);
#endif
+2 -2
View File
@@ -8,12 +8,12 @@
error_t getDataPath(int appid, char ** destination) {
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
error_t status = steam_searchGames(&gamePaths);
if(status == ERR_FAILURE) {
return ERR_FAILURE;
}
int gameId = getGameIdFromAppId(appid);
int gameId = steam_gameIdFromAppId(appid);
if(gameId < 0 ) {
return ERR_FAILURE;
}
+6 -6
View File
@@ -9,7 +9,7 @@
#include "archives.h"
#include "file.h"
error_t addMod(char * filePath, int appId) {
error_t install_addMod(char * filePath, int appId) {
error_t resultError = ERR_SUCCESS;
if (access(filePath, F_OK) != 0) {
fprintf(stderr, "File not found\n");
@@ -24,8 +24,8 @@ error_t addMod(char * filePath, int appId) {
goto exit2;
}
const char * filename = extractFileName(filePath);
const char * extension = extractExtension(filename);
const char * filename = file_extractFileName(filePath);
const char * extension = file_extractExtension(filename);
char * lowercaseExtension = g_ascii_strdown(extension, -1);
char appIdStr[20];
@@ -37,11 +37,11 @@ error_t addMod(char * filePath, int appId) {
int returnValue = EXIT_SUCCESS;
printf("Adding mod, this process can be slow depending on your hardware\n");
if(strcmp(lowercaseExtension, "rar") == 0) {
returnValue = unrar(filePath, outdir);
returnValue = archive_unrar(filePath, outdir);
} else if (strcmp(lowercaseExtension, "zip") == 0) {
returnValue = unzip(filePath, outdir);
returnValue = archive_unzip(filePath, outdir);
} else if (strcmp(lowercaseExtension, "7z") == 0) {
returnValue = un7z(filePath, outdir);
returnValue = archive_un7z(filePath, outdir);
} else {
fprintf(stderr, "Unsupported format only zip/7z/rar are supported\n");
returnValue = EXIT_FAILURE;
+1 -1
View File
@@ -10,6 +10,6 @@
* @param filePath path to the mod file
* @param appId game for which the mod is destined to be used with.
*/
error_t addMod(char * filePath, int appId);
error_t install_addMod(char * filePath, int appId);
#endif
+10 -10
View File
@@ -12,7 +12,7 @@
//TODO: detect if the game is running
//TODO: deploy the game
error_t listPlugins(int appid, GList ** plugins) {
error_t order_listPlugins(int appid, GList ** plugins) {
//save appid parsing
@@ -32,7 +32,7 @@ error_t listPlugins(int appid, GList ** plugins) {
struct dirent *dir;
if (d) {
while ((dir = readdir(d)) != NULL) {
const char * extension = extractExtension(dir->d_name);
const char * extension = file_extractExtension(dir->d_name);
if(strcmp(extension, "esp") == 0 || strcmp(extension, "esm") == 0) {
*plugins = g_list_append(*plugins, strdup(dir->d_name));
}
@@ -43,21 +43,21 @@ error_t listPlugins(int appid, GList ** plugins) {
return ERR_SUCCESS;
}
error_t getLoadOrder(int appid, GList ** order) {
error_t order_getLoadOrder(int appid, GList ** order) {
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
error_t status = steam_searchGames(&gamePaths);
if(status == ERR_FAILURE) {
return ERR_FAILURE;
}
GList * l_plugins = NULL;
error_t error = listPlugins(appid, &l_plugins);
error_t error = order_listPlugins(appid, &l_plugins);
if(error == ERR_FAILURE)
return ERR_FAILURE;
int gameId = getGameIdFromAppId(appid);
int gameId = steam_gameIdFromAppId(appid);
if(gameId < 0 ) {
return ERR_FAILURE;
}
@@ -109,14 +109,14 @@ error_t getLoadOrder(int appid, GList ** order) {
return ERR_SUCCESS;
}
error_t setLoadOrder(int appid, GList * loadOrder) {
error_t order_setLoadOrder(int appid, GList * loadOrder) {
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
error_t status = steam_searchGames(&gamePaths);
if(status == ERR_FAILURE) {
return ERR_FAILURE;
}
int gameId = getGameIdFromAppId(appid);
int gameId = steam_gameIdFromAppId(appid);
if(gameId < 0 ) {
return ERR_FAILURE;
}
@@ -141,7 +141,7 @@ error_t setLoadOrder(int appid, GList * loadOrder) {
//TODO: support compression since it can change how we read the file
//https://en.uesp.net/wiki/Skyrim_Mod:Mod_File_Format#Records
//https://www.mwmythicmods.com/argent/tech/es_format.html
error_t getModDependencies(const char * esmPath, GList ** dependencies) {
error_t order_getModDependencies(const char * esmPath, GList ** dependencies) {
FILE * file = fopen(esmPath, "r");
char sectionName[5];
+4 -4
View File
@@ -9,21 +9,21 @@
* @param appid the appid of the game
* @param order a pointer to a null Glist *. in which there will be the list of esm files.
*/
error_t listPlugins(int appid, GList ** list) __attribute__((warn_unused_result));
error_t order_listPlugins(int appid, GList ** list) __attribute__((warn_unused_result));
/**
* @brief fetch the load order of the game it might be null if setLoadOrder was never called.
* @param appid the appid of the game
* @param order a pointer to a null Glist *. in which there will be the list of esm files.
*/
error_t getLoadOrder(int appid, GList ** order) __attribute__((warn_unused_result));
error_t order_getLoadOrder(int appid, GList ** order) __attribute__((warn_unused_result));
/**
* @brief change the plugin load order of the game
* @param appid the appid of the game
* @param loadOrder the load order
*/
error_t setLoadOrder(int appid, GList * loadOrder) __attribute__((warn_unused_result));
error_t order_setLoadOrder(int appid, GList * loadOrder) __attribute__((warn_unused_result));
/**
* @brief List all dependencies for a esm mod.
@@ -31,6 +31,6 @@ error_t setLoadOrder(int appid, GList * loadOrder) __attribute__((warn_unused_re
* @param dependencies a pointer to a null Glist *. in which there will be the list of esm files.
* free it using g_list_free_full(dependencies, free);
*/
error_t getModDependencies(const char * esmPath, GList ** dependencies) __attribute__((warn_unused_result));
error_t order_getModDependencies(const char * esmPath, GList ** dependencies) __attribute__((warn_unused_result));
#endif
+15 -16
View File
@@ -65,7 +65,7 @@ static int usage() {
static error_t validateAppId(const char * appIdStr) {
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
error_t status = steam_searchGames(&gamePaths);
if(status == ERR_FAILURE) {
return ERR_FAILURE;
}
@@ -78,7 +78,7 @@ static error_t validateAppId(const char * appIdStr) {
return -1;
}
int gameId = getGameIdFromAppId((int)appid);
int gameId = steam_gameIdFromAppId((int)appid);
if(gameId < 0) {
fprintf(stderr, "Game is not compatible\n");
return -1;
@@ -97,7 +97,7 @@ static int listGames(int argc, char **) {
if(argc != 2) return usage();
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
error_t status = steam_searchGames(&gamePaths);
if(status == ERR_FAILURE) {
return EXIT_FAILURE;
}
@@ -126,7 +126,7 @@ static int add(int argc, char ** argv) {
return EXIT_FAILURE;
}
addMod(argv[3], appid);
install_addMod(argv[3], appid);
return EXIT_SUCCESS;
}
@@ -143,7 +143,7 @@ static int listAllMods(int argc, char ** argv) {
char * modFolder = g_build_filename(home, MANAGER_FILES, MOD_FOLDER_NAME, appIdStr, NULL);
free(home);
GList * mods = listMods(appid);
GList * mods = order_listMods(appid);
GList * p_mods = mods;
unsigned short index = 0;
@@ -330,7 +330,7 @@ static int deploy(int argc, char ** argv) {
//it might crash / corrupt game file if the user do it while the game is running
//but it's still very unlikely
while(umount2(dataFolder, MNT_FORCE | MNT_DETACH) == 0);
enum overlayErrors status = overlayMount(modsToInstall, dataFolder, gameUpperDir, gameWorkDir);
overlay_errors_t status = overlay_mount(modsToInstall, dataFolder, gameUpperDir, gameWorkDir);
if(status == SUCESS) {
printf("Everything is ready, just launch the game\n");
} else if(status == FAILURE) {
@@ -377,16 +377,16 @@ static int setup(int argc, char ** argv) {
if(access(gameFolder, F_OK) == 0) {
//if the game folder alredy exists just delete it
//this will allow the removal of dlcs and language change
delete(gameFolder, true);
file_delete(gameFolder, true);
}
g_mkdir_with_parents(gameFolder, 0755);
//links don't conflict with overlayfs and avoid coping 17Gb of files.
//but links require the files to be on the same filesystem
int returnValue = copy(dataFolder, gameFolder, CP_RECURSIVE | CP_NO_TARGET_DIR | CP_LINK);
int returnValue = file_copy(dataFolder, gameFolder, FILE_CP_RECURSIVE | FILE_CP_NO_TARGET_DIR | FILE_CP_LINK);
if(returnValue < 0) {
printf("Coping game files. HINT: having the game on the same partition as you home director will make this operation use zero extra space");
returnValue = copy(dataFolder, gameFolder, CP_RECURSIVE | CP_NO_TARGET_DIR);
returnValue = file_copy(dataFolder, gameFolder, FILE_CP_RECURSIVE | FILE_CP_NO_TARGET_DIR);
if(returnValue < 0) {
fprintf(stderr, "Copy failed make sure you have enough space on your device.");
free(dataFolder);
@@ -394,7 +394,7 @@ static int setup(int argc, char ** argv) {
return EXIT_FAILURE;
}
}
casefold(gameFolder);
file_casefold(gameFolder);
free(dataFolder);
free(gameFolder);
@@ -457,7 +457,7 @@ static int removeMod(int argc, char ** argv) {
gchar * filename = g_build_filename(modFolder, mods->data, NULL);
delete(filename, true);
file_delete(filename, true);
g_free(filename);
g_free(modFolder);
@@ -500,13 +500,13 @@ static int fomod(int argc, char ** argv) {
char * destination = g_strconcat(mods->data, "__FOMOD", NULL);
if(access(destination, F_OK) == 0) {
delete(destination, true);
file_delete(destination, true);
}
char * modDestination = g_build_filename(modFolder, destination, NULL);
char * modPath = g_build_filename(modFolder, mods->data, NULL);
//TODO: add error handling
int returnValue = installFOMod(modPath, modDestination);
int returnValue = fomod_installFOMod(modPath, modDestination);
free(destination);
g_list_free_full(modsFirstPointer, free);
@@ -540,7 +540,7 @@ static int swapMod(int argc, char ** argv) {
}
printf("%d, %d\n", modIdA, modIdB);
return swapPlace(appid, modIdA, modIdB);
return order_swapPlace(appid, modIdA, modIdB);
}
int main(int argc, char ** argv) {
@@ -609,7 +609,6 @@ int main(int argc, char ** argv) {
returnValue = swapMod(argc, argv);
else if(strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-v") == 0) {
returnValue = EXIT_SUCCESS;
#ifdef __clang__
printf("%s: Clang: %d.%d.%d\n", VERSION, __clang_major__, __clang_minor__, __clang_patchlevel__);
#elifdef __GNUC__
@@ -624,6 +623,6 @@ int main(int argc, char ** argv) {
exit:
g_free(configFolder);
freeGameTableSingleton();
steam_freeGameTable();
return returnValue;
}
+3 -3
View File
@@ -22,7 +22,7 @@ static gint compareOrder(const void * a, const void * b) {
return ModA->modId - ModB->modId;
}
GList * listMods(int appid) {
GList * order_listMods(int appid) {
char appidStr[10];
sprintf(appidStr, "%d", appid);
@@ -94,7 +94,7 @@ GList * listMods(int appid) {
}
error_t swapPlace(int appid, int modIdA, int modIdB) {
error_t order_swapPlace(int appid, int modIdA, int modIdB) {
char appidStr[10];
sprintf(appidStr, "%d", appid);
@@ -102,7 +102,7 @@ error_t swapPlace(int appid, int modIdA, int modIdB) {
char * modFolder = g_build_filename(home, MANAGER_FILES, MOD_FOLDER_NAME, appidStr, NULL);
free(home);
GList * list = listMods(appid);
GList * list = order_listMods(appid);
GList * listA = list;
GList * listB = list;
+2 -2
View File
@@ -15,7 +15,7 @@
*
* @return GList of char containing the name of the mod folder in order
*/
GList * listMods(int appid);
GList * order_listMods(int appid);
/**
* @brief Change the mod order by swaping two mod
@@ -25,6 +25,6 @@ GList * listMods(int appid);
* @param modId
* @param modId2
*/
error_t swapPlace(int appid, int modId, int modId2);
error_t order_swapPlace(int appid, int modId, int modId2);
#endif
+2 -2
View File
@@ -6,11 +6,11 @@
#include "overlayfs.h"
#include <stdio.h>
enum overlayErrors overlayMount(char ** sources, const char * dest, const char * upperdir, const char * workdir) {
overlay_errors_t overlay_mount(char ** sources, const char * dest, const char * upperdir, const char * workdir) {
char * lowerdir = g_strjoinv(":", sources);
char * mountData = g_strjoin("", "lowerdir=", lowerdir, ",workdir=", workdir, ",upperdir=", upperdir, NULL);
enum overlayErrors result = SUCESS;
overlay_errors_t result = SUCESS;
if(access("/usr/bin/fuse-overlayfs", F_OK) == 0) {
int pid = fork();
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef __OVERLAY_H__
#define __OVERLAY_H__
enum overlayErrors { SUCESS, NOT_INSTALLED, FAILURE };
typedef enum overlay_errors { SUCESS, NOT_INSTALLED, FAILURE } overlay_errors_t;
/**
@@ -13,6 +13,6 @@ enum overlayErrors { SUCESS, NOT_INSTALLED, FAILURE };
* @param workdir a directory that will contains only temporary files.
* @return int error code
*/
enum overlayErrors overlayMount(char ** sources, const char * dest, const char * upperdir, const char * workdir);
overlay_errors_t overlay_mount(char ** sources, const char * dest, const char * upperdir, const char * workdir);
#endif
+12 -12
View File
@@ -44,7 +44,7 @@ static int getFiledId(const char * field) {
}
}
static ValveLibraries_t * parseVDF(const char * path, size_t * size, int * status) {
static steam_Libraries_t * parseVDF(const char * path, size_t * size, int * status) {
FILE * fd = fopen(path, "r");
char * line = NULL;
size_t len = 0;
@@ -53,7 +53,7 @@ static ValveLibraries_t * parseVDF(const char * path, size_t * size, int * statu
bool inQuotes = false;
ValveLibraries_t * libraries = NULL;
steam_Libraries_t * libraries = NULL;
*size = 0;
//skip the "libraryfolders" label & the first opening brace
@@ -90,7 +90,7 @@ static ValveLibraries_t * parseVDF(const char * path, size_t * size, int * statu
} else {
char * value = strndup(buffer, bufferIndex);
ValveLibraries_t * library = &libraries[*size - 1];
steam_Libraries_t * library = &libraries[*size - 1];
switch (nextFieldToFill) {
case FIELD_PATH:
library->path = value;
@@ -120,7 +120,7 @@ static ValveLibraries_t * parseVDF(const char * path, size_t * size, int * statu
case FIELD_APPS:
if(isAppId) {
library->appsCount++;
library->apps = realloc(library->apps, library->appsCount * sizeof(ValveApp_t));
library->apps = realloc(library->apps, library->appsCount * sizeof(steam_App_t));
unsigned int appid = strtoul(value, NULL, 10);
library->apps[library->appsCount - 1].appid = appid;
} else {
@@ -146,8 +146,8 @@ static ValveLibraries_t * parseVDF(const char * path, size_t * size, int * statu
braceDepth++;
if(braceDepth == 1) {
*size += 1;
libraries = realloc(libraries, sizeof(ValveLibraries_t) * (*size));
memset(&libraries[*size - 1], 0, sizeof(ValveLibraries_t));
libraries = realloc(libraries, sizeof(steam_Libraries_t) * (*size));
memset(&libraries[*size - 1], 0, sizeof(steam_Libraries_t));
}
break;
case '}':
@@ -179,7 +179,7 @@ exit:
return libraries;
}
static void freeLibraries(ValveLibraries_t * libraries, int size) {
static void freeLibraries(steam_Libraries_t * libraries, int size) {
for(int i = 0; i < size; i++) {
free(libraries[i].path);
free(libraries[i].label);
@@ -193,17 +193,17 @@ static void freeLibraries(ValveLibraries_t * libraries, int size) {
static GHashTable* gameTableSingleton = NULL;
void freeGameTableSingleton() {
void steam_freeGameTable() {
if(gameTableSingleton != NULL)g_hash_table_destroy(gameTableSingleton);
}
error_t search_games(GHashTable ** p_hashTable) {
error_t steam_searchGames(GHashTable ** p_hashTable) {
if(gameTableSingleton != NULL) {
*p_hashTable = gameTableSingleton;
return ERR_SUCCESS;
}
ValveLibraries_t * libraries = NULL;
steam_Libraries_t * libraries = NULL;
size_t size = 0;
char * home = getHome();
@@ -231,7 +231,7 @@ error_t search_games(GHashTable ** p_hashTable) {
//fill the table
for(unsigned long i = 0; i < size; i++) {
for(unsigned long j = 0; j < libraries[i].appsCount; j++) {
int gameId = getGameIdFromAppId(libraries[i].apps[j].appid);
int gameId = steam_gameIdFromAppId(libraries[i].apps[j].appid);
if(gameId >= 0) {
int * key = malloc(sizeof(int));
*key = gameId;
@@ -247,7 +247,7 @@ error_t search_games(GHashTable ** p_hashTable) {
}
int getGameIdFromAppId(u_int32_t appid) {
int steam_gameIdFromAppId(u_int32_t appid) {
for(unsigned long k = 0; k < LEN(GAMES_APPIDS); k++) {
if(appid == GAMES_APPIDS[k]) {
return k;
+8 -8
View File
@@ -10,21 +10,21 @@
#include <unistd.h>
#include <glib.h>
typedef struct ValveApp {
typedef struct steam_App {
unsigned int appid;
unsigned int update;
} ValveApp_t;
} steam_App_t;
typedef struct ValveLibraries {
typedef struct steam_Libraries {
char * path;
char * label;
char * contentId;
unsigned long totalSize;
char * update_clean_bytes_tally;
char * time_last_update_corruption;
ValveApp_t * apps;
steam_App_t * apps;
size_t appsCount;
} ValveLibraries_t;
} steam_Libraries_t;
//todo add the older games
// order has to be the same as in GAMES_NAMES
@@ -52,9 +52,9 @@ _Static_assert(LEN(GAMES_APPIDS) == LEN(GAMES_NAMES), "Game APPIDS and Game Name
* @param status pointer to a status variable that will be modified to EXIT_SUCCESS or EXIT_FAILURE
* @return GHashTable* a map appid(int) => path(char *) to the corresponding steam library
*/
error_t search_games(GHashTable** tablePointer);
error_t steam_searchGames(GHashTable** tablePointer);
void freeGameTableSingleton(void);
void steam_freeGameTable(void);
/**
* @brief search the index of the game inside GAMES_NAMES or GAMES_APPIDS
@@ -62,6 +62,6 @@ void freeGameTableSingleton(void);
* @param appid
* @return -1 in case of failure or the index of the game.
*/
int getGameIdFromAppId(u_int32_t appid);
int steam_gameIdFromAppId(u_int32_t appid);
#endif