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)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -fsanitize=address -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g -Werror")
|
||||
if(CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
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")
|
||||
|
||||
# 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})
|
||||
|
||||
add_link_options(-fsanitize=address)
|
||||
|
||||
target_link_libraries(ModManager ${GLIB_LDFLAGS})
|
||||
target_link_libraries(ModManager ${LIBXML_LIBRARIES})
|
||||
|
||||
+12
-5
@@ -100,22 +100,29 @@ void casefold(const char * folder) {
|
||||
//removes .. & . from the list
|
||||
if(strcmp(dir->d_name, "..") != 0 && strcmp(dir->d_name, ".") != 0) {
|
||||
//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 * destination = g_build_path("/", folder,destinationName, NULL);
|
||||
|
||||
|
||||
if(strcmp(destinationName, dir->d_name) != 0) {
|
||||
|
||||
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) {
|
||||
casefold(file);
|
||||
|
||||
}
|
||||
g_free(file);
|
||||
g_free(destinationName);
|
||||
|
||||
if(dir->d_type == DT_DIR) {
|
||||
casefold(destination);
|
||||
}
|
||||
|
||||
g_free(destination);
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
+45
-8
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "fomod.h"
|
||||
#include "file.h"
|
||||
#include "fomod/fomodTypes.h"
|
||||
#include "libxml/globals.h"
|
||||
|
||||
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 * fileB = (const FOModFile_t *)b;
|
||||
|
||||
return fileA->priority - fileB->priority;
|
||||
return fileB->priority - fileA->priority;
|
||||
}
|
||||
|
||||
static void printfOptionsInOrder(FOModGroup_t group) {
|
||||
@@ -120,9 +121,10 @@ static void sortGroup(FOModGroup_t * group) {
|
||||
}
|
||||
|
||||
//TODO: handle error
|
||||
int processFileOperations(GList * pendingFileOperations, const char * modFolder, const char * destination) {
|
||||
pendingFileOperations = g_list_sort(pendingFileOperations, priorityCmp);
|
||||
GList * currentFileOperation = pendingFileOperations;
|
||||
int 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;
|
||||
|
||||
while(currentFileOperation != NULL) {
|
||||
//TODO: support destination
|
||||
@@ -171,6 +173,13 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
|
||||
FOModFile_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
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -178,6 +187,18 @@ GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendin
|
||||
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) {
|
||||
//everything should be lowercase since we use casefold() before calling any install function
|
||||
char * fomodFolder = g_build_path("/", modFolder, "fomod", NULL);
|
||||
@@ -259,6 +280,10 @@ int installFOMod(const char * modFolder, const char * destination) {
|
||||
min = 0;
|
||||
max = 0;
|
||||
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);
|
||||
char ** choices = g_regex_split(regex, inputBuffer, 0);
|
||||
g_regex_unref(regex);
|
||||
|
||||
for(int choiceId = 0; choices[choiceId] != NULL; choiceId++) {
|
||||
//TODO: safer user input
|
||||
int choice = atoi(choices[choiceId]);
|
||||
FOModPlugin_t plugin = group.plugins[choice];
|
||||
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++) {
|
||||
const FOModFile_t * file = &plugin.files[pluginId];
|
||||
|
||||
FOModFile_t * fileCopy = malloc(sizeof(*file));
|
||||
FOModFile_t * fileCopy = malloc(sizeof(FOModFile_t));
|
||||
*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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
processFileOperations(pendingFileOperations, modFolder, destination);
|
||||
processFileOperations(&pendingFileOperations, modFolder, destination);
|
||||
|
||||
printf("FOMod successfully installed!\n");
|
||||
g_list_free(flagList);
|
||||
g_list_free_full(pendingFileOperations, free);
|
||||
freeFileOperations(pendingFileOperations);
|
||||
freeFOMod(&fomod);
|
||||
g_free(fomodFolder);
|
||||
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.
|
||||
* @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
|
||||
|
||||
@@ -36,6 +36,7 @@ static TypeDescriptor_t getDescriptor(const char * descriptor) {
|
||||
}
|
||||
|
||||
void freeGroup(FOModGroup_t * group) {
|
||||
free(group->name);
|
||||
if(group->pluginCount == 0) return;
|
||||
for(int pluginId = 0; pluginId < group->pluginCount; 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++) {
|
||||
FOModGroup_t * group = &step->groups[groupId];
|
||||
freeGroup(group);
|
||||
free(step->groups[groupId].plugins);
|
||||
}
|
||||
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));
|
||||
|
||||
+5
-1
@@ -137,6 +137,7 @@ static int listAllMods(int argc, char ** argv) {
|
||||
free(home);
|
||||
|
||||
GList * mods = listMods(appid);
|
||||
GList * p_mods = mods;
|
||||
unsigned short index = 0;
|
||||
|
||||
printf("Id | Installed | Name\n");
|
||||
@@ -150,13 +151,15 @@ static int listAllMods(int argc, char ** argv) {
|
||||
printf(DISABLED_COLOR " %d | ✕ | %s\n", index, modName);
|
||||
}
|
||||
|
||||
g_free(modPath);
|
||||
|
||||
index++;
|
||||
mods = g_list_next(mods);
|
||||
}
|
||||
|
||||
|
||||
free(modFolder);
|
||||
free(mods);
|
||||
g_list_free_full(p_mods, free);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -535,6 +538,7 @@ int main(int argc, char ** argv) {
|
||||
int searchStatus;
|
||||
gamePaths = search_games(&searchStatus);
|
||||
|
||||
|
||||
int returnValue = EXIT_SUCCESS;
|
||||
if(searchStatus == EXIT_FAILURE) {
|
||||
returnValue = EXIT_FAILURE;
|
||||
|
||||
+3
-1
@@ -51,6 +51,7 @@ GList * listMods(int appid) {
|
||||
|
||||
Mod_t * mod = alloca(sizeof(Mod_t));
|
||||
mod->modId = modId;
|
||||
//we are going to return this value so no alloca here
|
||||
mod->name = strdup(dir->d_name);
|
||||
//strdup but on the stack
|
||||
//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 * modBFolder = g_build_filename(modFolder, listB->data, ORDER_FILE, NULL);
|
||||
g_free(modFolder);
|
||||
|
||||
FILE * fileA = fopen(modAFolder, "w");
|
||||
FILE * fileB = fopen(modBFolder, "w");
|
||||
@@ -138,6 +140,6 @@ int swapPlace(int appid, int modIdA, int modIdB) {
|
||||
fclose(fileA);
|
||||
fclose(fileB);
|
||||
|
||||
g_list_free(list);
|
||||
g_list_free_full(list, free);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -125,8 +125,11 @@ static ValveLibraries_t * parseVDF(const char * path, size_t * size, int * statu
|
||||
} else {
|
||||
library->apps[library->appsCount - 1].update = strtoul(value, NULL, 10);
|
||||
}
|
||||
free(value);
|
||||
isAppId = !isAppId;
|
||||
break;
|
||||
default:
|
||||
free(value);
|
||||
}
|
||||
//field apps is using braces so the syntax is different
|
||||
if(nextFieldToFill != FIELD_APPS)nextFieldToFill = -1;
|
||||
|
||||
Reference in New Issue
Block a user