fixed some memory leaks
This commit is contained in:
+6
-3
@@ -4,8 +4,12 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||||||
set(CMAKE_BUILD_TYPE Release)
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -fsanitize=address -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations")
|
if(CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
set(CMAKE_C_FLAGS_DEBUG "-g -Werror")
|
add_link_options(-fsanitize=address)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmaybe-uninitialized")
|
||||||
|
set(CMAKE_C_FLAGS_DEBUG "-g -fsanitize=address -Werror -O0")
|
||||||
set(CMAKE_C_FLAGS_RELEASE "-O2")
|
set(CMAKE_C_FLAGS_RELEASE "-O2")
|
||||||
|
|
||||||
# generate the compile_commands for vscode / clang
|
# generate the compile_commands for vscode / clang
|
||||||
@@ -38,7 +42,6 @@ pkg_search_module(LIBXML REQUIRED libxml-2.0)
|
|||||||
|
|
||||||
target_include_directories(ModManager PRIVATE ${GLIB_INCLUDE_DIRS} ${LIBXML_INCLUDE_DIRS} ${AUDIT_INCLUDE_DIRS})
|
target_include_directories(ModManager PRIVATE ${GLIB_INCLUDE_DIRS} ${LIBXML_INCLUDE_DIRS} ${AUDIT_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_link_options(-fsanitize=address)
|
|
||||||
|
|
||||||
target_link_libraries(ModManager ${GLIB_LDFLAGS})
|
target_link_libraries(ModManager ${GLIB_LDFLAGS})
|
||||||
target_link_libraries(ModManager ${LIBXML_LIBRARIES})
|
target_link_libraries(ModManager ${LIBXML_LIBRARIES})
|
||||||
|
|||||||
+16
-9
@@ -100,22 +100,29 @@ void casefold(const char * folder) {
|
|||||||
//removes .. & . from the list
|
//removes .. & . from the list
|
||||||
if(strcmp(dir->d_name, "..") != 0 && strcmp(dir->d_name, ".") != 0) {
|
if(strcmp(dir->d_name, "..") != 0 && strcmp(dir->d_name, ".") != 0) {
|
||||||
//only look at ascii and hope for the best.
|
//only look at ascii and hope for the best.
|
||||||
gchar * file = g_build_path("/", folder, dir->d_name, NULL);
|
gchar * file = g_build_filename(folder, dir->d_name, NULL);
|
||||||
|
|
||||||
gchar * destinationName = g_ascii_strdown(dir->d_name, -1);
|
gchar * destinationName = g_ascii_strdown(dir->d_name, -1);
|
||||||
gchar * destination = g_build_path("/", folder,destinationName, NULL);
|
gchar * destination = g_build_path("/", folder,destinationName, NULL);
|
||||||
|
|
||||||
int result = move(file, destination);
|
|
||||||
if(result != EXIT_SUCCESS) {
|
|
||||||
fprintf(stderr, "Move failed: %s => %s \n", dir->d_name, destinationName);
|
|
||||||
}
|
|
||||||
g_free(destinationName);
|
|
||||||
g_free(destination);
|
|
||||||
|
|
||||||
if(dir->d_type == DT_DIR) {
|
if(strcmp(destinationName, dir->d_name) != 0) {
|
||||||
casefold(file);
|
|
||||||
|
int result = move(file, destination);
|
||||||
|
if(result != EXIT_SUCCESS) {
|
||||||
|
fprintf(stderr, "Move failed: %s => %s \n", dir->d_name, destinationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
g_free(file);
|
g_free(file);
|
||||||
|
g_free(destinationName);
|
||||||
|
|
||||||
|
if(dir->d_type == DT_DIR) {
|
||||||
|
casefold(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(destination);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(d);
|
closedir(d);
|
||||||
|
|||||||
+45
-8
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "fomod.h"
|
#include "fomod.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
#include "fomod/fomodTypes.h"
|
||||||
#include "libxml/globals.h"
|
#include "libxml/globals.h"
|
||||||
|
|
||||||
static int getInputCount(const char * input) {
|
static int getInputCount(const char * input) {
|
||||||
@@ -44,7 +45,7 @@ static gint priorityCmp(gconstpointer a, gconstpointer b) {
|
|||||||
const FOModFile_t * fileA = (const FOModFile_t *)a;
|
const FOModFile_t * fileA = (const FOModFile_t *)a;
|
||||||
const FOModFile_t * fileB = (const FOModFile_t *)b;
|
const FOModFile_t * fileB = (const FOModFile_t *)b;
|
||||||
|
|
||||||
return fileA->priority - fileB->priority;
|
return fileB->priority - fileA->priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printfOptionsInOrder(FOModGroup_t group) {
|
static void printfOptionsInOrder(FOModGroup_t group) {
|
||||||
@@ -120,9 +121,10 @@ static void sortGroup(FOModGroup_t * group) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: handle error
|
//TODO: handle error
|
||||||
int processFileOperations(GList * pendingFileOperations, const char * modFolder, const char * destination) {
|
int processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination) {
|
||||||
pendingFileOperations = g_list_sort(pendingFileOperations, priorityCmp);
|
//priority higher a less important and should be processed first.
|
||||||
GList * currentFileOperation = pendingFileOperations;
|
*pendingFileOperations = g_list_sort(*pendingFileOperations, priorityCmp);
|
||||||
|
GList * currentFileOperation = *pendingFileOperations;
|
||||||
|
|
||||||
while(currentFileOperation != NULL) {
|
while(currentFileOperation != NULL) {
|
||||||
//TODO: support destination
|
//TODO: support destination
|
||||||
@@ -171,6 +173,13 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
|
|||||||
FOModFile_t * fileCopy = malloc(sizeof(*file));
|
FOModFile_t * fileCopy = malloc(sizeof(*file));
|
||||||
*fileCopy = *file;
|
*fileCopy = *file;
|
||||||
|
|
||||||
|
//changing pathes to lowercase since we used casefold and the pathes in the xml might not like it
|
||||||
|
char * destination = g_ascii_strdown(file->destination, -1);
|
||||||
|
fileCopy->destination = destination;
|
||||||
|
|
||||||
|
char * source = g_ascii_strdown(file->source, -1);
|
||||||
|
fileCopy->source = source;
|
||||||
|
|
||||||
pendingFileOperations = g_list_append(pendingFileOperations, fileCopy);
|
pendingFileOperations = g_list_append(pendingFileOperations, fileCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,6 +187,18 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
|
|||||||
return pendingFileOperations;
|
return pendingFileOperations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void freeFileOperations(GList * fileOperations) {
|
||||||
|
GList * fileOperationsStart = fileOperations;
|
||||||
|
while(fileOperations != NULL) {
|
||||||
|
FOModFile_t * file = (FOModFile_t *)fileOperations->data;
|
||||||
|
if(file->destination != NULL)free(file->destination);
|
||||||
|
if(file->source != NULL)free(file->source);
|
||||||
|
fileOperations = g_list_next(fileOperations);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free_full(fileOperationsStart, free);
|
||||||
|
}
|
||||||
|
|
||||||
int installFOMod(const char * modFolder, const char * destination) {
|
int installFOMod(const char * modFolder, const char * destination) {
|
||||||
//everything should be lowercase since we use casefold() before calling any install function
|
//everything should be lowercase since we use casefold() before calling any install function
|
||||||
char * fomodFolder = g_build_path("/", modFolder, "fomod", NULL);
|
char * fomodFolder = g_build_path("/", modFolder, "fomod", NULL);
|
||||||
@@ -259,6 +280,10 @@ int installFOMod(const char * modFolder, const char * destination) {
|
|||||||
min = 0;
|
min = 0;
|
||||||
max = 0;
|
max = 0;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
//never happen;
|
||||||
|
fprintf(stderr, "unexpected type please report this issue %d, %d", group.type, __LINE__);
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -277,11 +302,14 @@ int installFOMod(const char * modFolder, const char * destination) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//processing user input
|
||||||
|
|
||||||
GRegex* regex = g_regex_new("\\s*", 0, 0, NULL);
|
GRegex* regex = g_regex_new("\\s*", 0, 0, NULL);
|
||||||
char ** choices = g_regex_split(regex, inputBuffer, 0);
|
char ** choices = g_regex_split(regex, inputBuffer, 0);
|
||||||
g_regex_unref(regex);
|
g_regex_unref(regex);
|
||||||
|
|
||||||
for(int choiceId = 0; choices[choiceId] != NULL; choiceId++) {
|
for(int choiceId = 0; choices[choiceId] != NULL; choiceId++) {
|
||||||
|
//TODO: safer user input
|
||||||
int choice = atoi(choices[choiceId]);
|
int choice = atoi(choices[choiceId]);
|
||||||
FOModPlugin_t plugin = group.plugins[choice];
|
FOModPlugin_t plugin = group.plugins[choice];
|
||||||
for(int flagId = 0; flagId < plugin.flagCount; flagId++) {
|
for(int flagId = 0; flagId < plugin.flagCount; flagId++) {
|
||||||
@@ -292,9 +320,18 @@ int installFOMod(const char * modFolder, const char * destination) {
|
|||||||
for(int pluginId = 0; pluginId < plugin.fileCount; pluginId++) {
|
for(int pluginId = 0; pluginId < plugin.fileCount; pluginId++) {
|
||||||
const FOModFile_t * file = &plugin.files[pluginId];
|
const FOModFile_t * file = &plugin.files[pluginId];
|
||||||
|
|
||||||
FOModFile_t * fileCopy = malloc(sizeof(*file));
|
FOModFile_t * fileCopy = malloc(sizeof(FOModFile_t));
|
||||||
*fileCopy = *file;
|
*fileCopy = *file;
|
||||||
|
|
||||||
|
//changing pathes to lowercase since we used casefold and the pathes in the xml might not like it
|
||||||
|
char * destination = g_ascii_strdown(file->destination, -1);
|
||||||
|
fileCopy->destination = strdup(destination);
|
||||||
|
g_free(destination);
|
||||||
|
|
||||||
|
char * source = g_ascii_strdown(file->source, -1);
|
||||||
|
fileCopy->source = strdup(source);
|
||||||
|
g_free(source);
|
||||||
|
|
||||||
pendingFileOperations = g_list_append(pendingFileOperations, fileCopy);
|
pendingFileOperations = g_list_append(pendingFileOperations, fileCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,14 +341,14 @@ int installFOMod(const char * modFolder, const char * destination) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: manage multiple files with the same name
|
||||||
|
|
||||||
pendingFileOperations = processCondFiles(&fomod, flagList, pendingFileOperations);
|
pendingFileOperations = processCondFiles(&fomod, flagList, pendingFileOperations);
|
||||||
processFileOperations(pendingFileOperations, modFolder, destination);
|
processFileOperations(&pendingFileOperations, modFolder, destination);
|
||||||
|
|
||||||
printf("FOMod successfully installed!\n");
|
printf("FOMod successfully installed!\n");
|
||||||
g_list_free(flagList);
|
g_list_free(flagList);
|
||||||
g_list_free_full(pendingFileOperations, free);
|
freeFileOperations(pendingFileOperations);
|
||||||
freeFOMod(&fomod);
|
freeFOMod(&fomod);
|
||||||
g_free(fomodFolder);
|
g_free(fomodFolder);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
+7
-2
@@ -35,8 +35,13 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
|
|||||||
* @param destination folder of the new mod that contains the result of the process.
|
* @param destination folder of the new mod that contains the result of the process.
|
||||||
* @return error code
|
* @return error code
|
||||||
*/
|
*/
|
||||||
int processFileOperations(GList * pendingFileOperations, const char * modFolder, const char * destination);
|
int processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param fileOperations
|
||||||
|
*/
|
||||||
|
void freeFileOperations(GList * fileOperations);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ static TypeDescriptor_t getDescriptor(const char * descriptor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void freeGroup(FOModGroup_t * group) {
|
void freeGroup(FOModGroup_t * group) {
|
||||||
|
free(group->name);
|
||||||
if(group->pluginCount == 0) return;
|
if(group->pluginCount == 0) return;
|
||||||
for(int pluginId = 0; pluginId < group->pluginCount; pluginId++) {
|
for(int pluginId = 0; pluginId < group->pluginCount; pluginId++) {
|
||||||
FOModPlugin_t * plugin = &group->plugins[pluginId];
|
FOModPlugin_t * plugin = &group->plugins[pluginId];
|
||||||
|
|||||||
+2
-1
@@ -36,16 +36,17 @@ void freeFOMod(FOMod_t * fomod) {
|
|||||||
for(int groupId = 0; groupId < step->groupCount; groupId++) {
|
for(int groupId = 0; groupId < step->groupCount; groupId++) {
|
||||||
FOModGroup_t * group = &step->groups[groupId];
|
FOModGroup_t * group = &step->groups[groupId];
|
||||||
freeGroup(group);
|
freeGroup(group);
|
||||||
free(step->groups[groupId].plugins);
|
|
||||||
}
|
}
|
||||||
for(int flagId = 0; flagId < step->flagCount; flagId++) {
|
for(int flagId = 0; flagId < step->flagCount; flagId++) {
|
||||||
FOModFlag_t * flag = &(step->requiredFlags[flagId]);
|
FOModFlag_t * flag = &(step->requiredFlags[flagId]);
|
||||||
free(flag->name);
|
free(flag->name);
|
||||||
free(flag->value);
|
free(flag->value);
|
||||||
}
|
}
|
||||||
|
free(step->groups);
|
||||||
free(step->requiredFlags);
|
free(step->requiredFlags);
|
||||||
free(step->name);
|
free(step->name);
|
||||||
}
|
}
|
||||||
|
free(fomod->steps);
|
||||||
|
|
||||||
//set every counter to zero and every pointer to null
|
//set every counter to zero and every pointer to null
|
||||||
memset(fomod, 0, sizeof(FOMod_t));
|
memset(fomod, 0, sizeof(FOMod_t));
|
||||||
|
|||||||
+5
-1
@@ -137,6 +137,7 @@ static int listAllMods(int argc, char ** argv) {
|
|||||||
free(home);
|
free(home);
|
||||||
|
|
||||||
GList * mods = listMods(appid);
|
GList * mods = listMods(appid);
|
||||||
|
GList * p_mods = mods;
|
||||||
unsigned short index = 0;
|
unsigned short index = 0;
|
||||||
|
|
||||||
printf("Id | Installed | Name\n");
|
printf("Id | Installed | Name\n");
|
||||||
@@ -150,13 +151,15 @@ static int listAllMods(int argc, char ** argv) {
|
|||||||
printf(DISABLED_COLOR " %d | ✕ | %s\n", index, modName);
|
printf(DISABLED_COLOR " %d | ✕ | %s\n", index, modName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free(modPath);
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
mods = g_list_next(mods);
|
mods = g_list_next(mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
free(modFolder);
|
free(modFolder);
|
||||||
free(mods);
|
g_list_free_full(p_mods, free);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,6 +538,7 @@ int main(int argc, char ** argv) {
|
|||||||
int searchStatus;
|
int searchStatus;
|
||||||
gamePaths = search_games(&searchStatus);
|
gamePaths = search_games(&searchStatus);
|
||||||
|
|
||||||
|
|
||||||
int returnValue = EXIT_SUCCESS;
|
int returnValue = EXIT_SUCCESS;
|
||||||
if(searchStatus == EXIT_FAILURE) {
|
if(searchStatus == EXIT_FAILURE) {
|
||||||
returnValue = EXIT_FAILURE;
|
returnValue = EXIT_FAILURE;
|
||||||
|
|||||||
+3
-1
@@ -51,6 +51,7 @@ GList * listMods(int appid) {
|
|||||||
|
|
||||||
Mod_t * mod = alloca(sizeof(Mod_t));
|
Mod_t * mod = alloca(sizeof(Mod_t));
|
||||||
mod->modId = modId;
|
mod->modId = modId;
|
||||||
|
//we are going to return this value so no alloca here
|
||||||
mod->name = strdup(dir->d_name);
|
mod->name = strdup(dir->d_name);
|
||||||
//strdup but on the stack
|
//strdup but on the stack
|
||||||
//add one for the \0
|
//add one for the \0
|
||||||
@@ -120,6 +121,7 @@ int swapPlace(int appid, int modIdA, int modIdB) {
|
|||||||
|
|
||||||
char * modAFolder = g_build_filename(modFolder, listA->data, ORDER_FILE, NULL);
|
char * modAFolder = g_build_filename(modFolder, listA->data, ORDER_FILE, NULL);
|
||||||
char * modBFolder = g_build_filename(modFolder, listB->data, ORDER_FILE, NULL);
|
char * modBFolder = g_build_filename(modFolder, listB->data, ORDER_FILE, NULL);
|
||||||
|
g_free(modFolder);
|
||||||
|
|
||||||
FILE * fileA = fopen(modAFolder, "w");
|
FILE * fileA = fopen(modAFolder, "w");
|
||||||
FILE * fileB = fopen(modBFolder, "w");
|
FILE * fileB = fopen(modBFolder, "w");
|
||||||
@@ -138,6 +140,6 @@ int swapPlace(int appid, int modIdA, int modIdB) {
|
|||||||
fclose(fileA);
|
fclose(fileA);
|
||||||
fclose(fileB);
|
fclose(fileB);
|
||||||
|
|
||||||
g_list_free(list);
|
g_list_free_full(list, free);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,8 +125,11 @@ static ValveLibraries_t * parseVDF(const char * path, size_t * size, int * statu
|
|||||||
} else {
|
} else {
|
||||||
library->apps[library->appsCount - 1].update = strtoul(value, NULL, 10);
|
library->apps[library->appsCount - 1].update = strtoul(value, NULL, 10);
|
||||||
}
|
}
|
||||||
|
free(value);
|
||||||
isAppId = !isAppId;
|
isAppId = !isAppId;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
free(value);
|
||||||
}
|
}
|
||||||
//field apps is using braces so the syntax is different
|
//field apps is using braces so the syntax is different
|
||||||
if(nextFieldToFill != FIELD_APPS)nextFieldToFill = -1;
|
if(nextFieldToFill != FIELD_APPS)nextFieldToFill = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user