Adder the type alias error_t and refactored the code to use it. also extracted archive function from install.c to archives.c
This commit is contained in:
@@ -26,6 +26,7 @@ set(SOURCES
|
||||
src/getHome.c
|
||||
src/file.c
|
||||
src/order.c
|
||||
src/archives.c
|
||||
src/fomod.c
|
||||
src/fomod/group.c
|
||||
src/fomod/xmlUtil.c
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#include "archives.h"
|
||||
#include "file.h"
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
int unzip(char * path, char * outdir) {
|
||||
char * const args[] = {
|
||||
"unzip",
|
||||
"-LL", // to lowercase
|
||||
"-q",
|
||||
path,
|
||||
"-d",
|
||||
outdir,
|
||||
NULL
|
||||
};
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if(pid == 0) {
|
||||
execv("/usr/bin/unzip", args);
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
int returnValue;
|
||||
waitpid(pid, &returnValue, 0);
|
||||
|
||||
if(returnValue != 0) {
|
||||
fprintf(stderr, "\nFailed to decompress archive\n");
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
int unrar(char * path, char * outdir) {
|
||||
char * const args[] = {
|
||||
"unrar",
|
||||
"x",
|
||||
"-y", //assume yes
|
||||
"-cl", // to lowercase
|
||||
path,
|
||||
outdir,
|
||||
NULL
|
||||
};
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if(pid == 0) {
|
||||
execv("/usr/bin/unrar", args);
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
int returnValue;
|
||||
waitpid(pid, &returnValue, 0);
|
||||
|
||||
if(returnValue != 0) {
|
||||
fprintf(stderr, "\nFailed to decompress archive\n");
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int un7z(char * path, const char * outdir) {
|
||||
gchar * outParameter = g_strjoin("", "-o", outdir, NULL);
|
||||
|
||||
char * const args[] = {
|
||||
"7z",
|
||||
"-y", //assume yes
|
||||
"x",
|
||||
path,
|
||||
outParameter,
|
||||
NULL
|
||||
};
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if(pid == 0) {
|
||||
execv("/usr/bin/7z", args);
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
g_free(outParameter);
|
||||
int returnValue;
|
||||
waitpid(pid, &returnValue, 0);
|
||||
|
||||
if(returnValue != 0) {
|
||||
fprintf(stderr, "\nFailed to decompress archive\n");
|
||||
return returnValue;
|
||||
}
|
||||
//make everything lowercase since 7z don't have an argument for that.
|
||||
casefold(outdir);
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef __ARCHIVES_H__
|
||||
#define __ARCHIVES_H__
|
||||
|
||||
//all of these function will make every file into lowercase
|
||||
|
||||
/**
|
||||
* @brief Execute the unzip command
|
||||
* @param path path to archive
|
||||
* @param outdir output director
|
||||
* @return int return code
|
||||
*/
|
||||
int unzip(char * path, char * outdir);
|
||||
|
||||
/**
|
||||
* @brief Execute the unrar command
|
||||
* @param path path to archive
|
||||
* @param outdir output director
|
||||
* @return int return code
|
||||
*/
|
||||
int unrar(char * path, char * outdir);
|
||||
|
||||
/**
|
||||
* @brief Execute the 7z command
|
||||
* @param path path to archive
|
||||
* @param outdir output director
|
||||
* @return int return code
|
||||
*/
|
||||
int un7z(char * path, const char * outdir);
|
||||
|
||||
#endif
|
||||
+6
-5
@@ -1,9 +1,10 @@
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef __FILE_H__
|
||||
#define __FILE_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include "main.h"
|
||||
|
||||
|
||||
//valid copy flags
|
||||
#define cp_DEFAULT 0
|
||||
@@ -16,7 +17,7 @@
|
||||
* @param source path to the source files
|
||||
* @param dest path to the destination folder
|
||||
* @param flags refer to the "valid copy flags" use them like this CP_LINK | CP_RECURSIVE
|
||||
* @return status code
|
||||
* @return cp return value
|
||||
*/
|
||||
int copy(const char * source, const char * dest, u_int32_t flags);
|
||||
|
||||
@@ -25,7 +26,7 @@ int copy(const char * source, const char * dest, u_int32_t flags);
|
||||
* @param source path to the source files
|
||||
* @param dest path to the destination folder
|
||||
* @param bool enable recursive rm -r
|
||||
* @return status code
|
||||
* @return rm return value
|
||||
*/
|
||||
int delete(const char * path, bool recursive);
|
||||
|
||||
|
||||
+10
-9
@@ -14,6 +14,7 @@
|
||||
#include "file.h"
|
||||
#include "fomod/fomodTypes.h"
|
||||
#include "libxml/globals.h"
|
||||
#include "main.h"
|
||||
|
||||
static int getInputCount(const char * input) {
|
||||
char buff[2];
|
||||
@@ -121,7 +122,7 @@ static void sortGroup(FOModGroup_t * group) {
|
||||
}
|
||||
|
||||
//TODO: handle error
|
||||
int processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination) {
|
||||
error_t 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;
|
||||
@@ -148,7 +149,7 @@ int processFileOperations(GList ** pendingFileOperations, const char * modFolder
|
||||
|
||||
currentFileOperation = g_list_next(currentFileOperation);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendingFileOperations) {
|
||||
@@ -199,7 +200,7 @@ void freeFileOperations(GList * fileOperations) {
|
||||
g_list_free_full(fileOperationsStart, free);
|
||||
}
|
||||
|
||||
int installFOMod(const char * modFolder, const char * destination) {
|
||||
error_t 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);
|
||||
@@ -208,14 +209,14 @@ int installFOMod(const char * modFolder, const char * destination) {
|
||||
fprintf(stderr, "FOMod file not found, are you sure this is a fomod mod ?\n");
|
||||
g_free(fomodFolder);
|
||||
g_free(fomodFile);
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
FOMod_t fomod;
|
||||
int returnValue = parseFOMod(fomodFile, &fomod);
|
||||
if(returnValue != EXIT_SUCCESS) {
|
||||
return returnValue;
|
||||
}
|
||||
if(returnValue == ERR_FAILURE)
|
||||
return ERR_FAILURE;
|
||||
|
||||
g_free(fomodFile);
|
||||
|
||||
GList * flagList = NULL;
|
||||
@@ -283,7 +284,7 @@ int installFOMod(const char * modFolder, const char * destination) {
|
||||
default:
|
||||
//never happen;
|
||||
fprintf(stderr, "unexpected type please report this issue %d, %d", group.type, __LINE__);
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -351,5 +352,5 @@ int installFOMod(const char * modFolder, const char * destination) {
|
||||
freeFileOperations(pendingFileOperations);
|
||||
freeFOMod(&fomod);
|
||||
g_free(fomodFolder);
|
||||
return EXIT_SUCCESS;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
+4
-3
@@ -3,8 +3,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <glib.h>
|
||||
#include "fomod/parser.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "fomod/parser.h"
|
||||
#include "fomod/group.h"
|
||||
#include "fomod/xmlUtil.h"
|
||||
|
||||
@@ -15,7 +16,7 @@
|
||||
* @param destination folder of the new mod that contains the result of the fomod process.
|
||||
* @return int
|
||||
*/
|
||||
int installFOMod(const char * modFolder, const char * destination);
|
||||
error_t 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.
|
||||
@@ -35,7 +36,7 @@ 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);
|
||||
error_t processFileOperations(GList ** pendingFileOperations, const char * modFolder, const char * destination);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
||||
+9
-8
@@ -239,7 +239,7 @@ static int parseConditionalInstalls(xmlNodePtr node, FOMod_t * fomod) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
error_t parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr cur;
|
||||
|
||||
@@ -256,7 +256,7 @@ int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
|
||||
if(doc == NULL) {
|
||||
fprintf(stderr, "Document is not a valid xml file\n");
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,12 +264,13 @@ int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
if(cur == NULL) {
|
||||
fprintf(stderr, "emptyDocument");
|
||||
xmlFreeDoc(doc);
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
if(xmlStrcmp(cur->name, (const xmlChar *) "config") != 0) {
|
||||
fprintf(stderr, "document of the wrong type, root node is '%s' instead of config\n", cur->name);
|
||||
return EXIT_FAILURE;
|
||||
xmlFreeDoc(doc);
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
cur = cur->children;
|
||||
@@ -286,7 +287,7 @@ int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
if(validateNode(&requiredInstallFile, true, "folder", "file", NULL)) {
|
||||
//TODO: handle error
|
||||
printf("%d\n", __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
exit(ERR_FAILURE);
|
||||
}
|
||||
|
||||
int size = countUntilNull(fomod->requiredInstallFiles, sizeof(char **)) + 2;
|
||||
@@ -301,7 +302,7 @@ int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
if(fomod->steps != NULL) {
|
||||
fprintf(stderr, "Multiple 'installSteps' tags");
|
||||
//TODO: handle error
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
xmlChar * stepOrder = xmlGetProp(cur, (xmlChar *)"order");
|
||||
@@ -315,7 +316,7 @@ int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
fprintf(stderr, "Failed to parse the install steps\n");
|
||||
|
||||
//TODO: manage the error properly
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
fomod->steps = steps;
|
||||
@@ -327,5 +328,5 @@ int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
return EXIT_SUCCESS;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
#include "group.h"
|
||||
#include "../main.h"
|
||||
|
||||
//combine installStep and optionalFileGroups
|
||||
typedef struct FOModStep {
|
||||
@@ -30,9 +31,8 @@ typedef struct FOMod {
|
||||
*
|
||||
* @param fomodFile path to the moduleconfig.xml
|
||||
* @param fomod pointer to a new FOMod_t
|
||||
* @return error code.
|
||||
*/
|
||||
int parseFOMod(const char * fomodFile, FOMod_t* fomod);
|
||||
error_t parseFOMod(const char * fomodFile, FOMod_t* fomod);
|
||||
|
||||
/**
|
||||
* @brief Free content of a fomod file.
|
||||
|
||||
@@ -7,12 +7,24 @@
|
||||
|
||||
typedef enum FOModOrder { ASC, DESC, ORD } FOModOrder_t;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param node a pointer to the current node pointer (xmlNode **)
|
||||
* @param skipText if a text element is found skip it.
|
||||
* @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, ...);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
|
||||
FOModOrder_t getFOModOrder(const char * order);
|
||||
|
||||
/**
|
||||
* @brief replace / by \
|
||||
* @param path
|
||||
|
||||
+12
-96
@@ -1,100 +1,12 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "install.h"
|
||||
#include "main.h"
|
||||
#include "file.h"
|
||||
|
||||
static int unzip(char * path, char * outdir) {
|
||||
char * const args[] = {
|
||||
"unzip",
|
||||
"-LL", // to lowercase
|
||||
"-q",
|
||||
path,
|
||||
"-d",
|
||||
outdir,
|
||||
NULL
|
||||
};
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if(pid == 0) {
|
||||
execv("/usr/bin/unzip", args);
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
int returnValue;
|
||||
waitpid(pid, &returnValue, 0);
|
||||
|
||||
if(returnValue != 0) {
|
||||
fprintf(stderr, "\nFailed to decompress archive\n");
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
static int unrar(char * path, char * outdir) {
|
||||
char * const args[] = {
|
||||
"unrar",
|
||||
"x",
|
||||
"-y", //assume yes
|
||||
"-cl", // to lowercase
|
||||
path,
|
||||
outdir,
|
||||
NULL
|
||||
};
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if(pid == 0) {
|
||||
execv("/usr/bin/unrar", args);
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
int returnValue;
|
||||
waitpid(pid, &returnValue, 0);
|
||||
|
||||
if(returnValue != 0) {
|
||||
fprintf(stderr, "\nFailed to decompress archive\n");
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int un7z(char * path, const char * outdir) {
|
||||
gchar * outParameter = g_strjoin("", "-o", outdir, NULL);
|
||||
|
||||
char * const args[] = {
|
||||
"7z",
|
||||
"-y", //assume yes
|
||||
"x",
|
||||
path,
|
||||
outParameter,
|
||||
NULL
|
||||
};
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if(pid == 0) {
|
||||
execv("/usr/bin/7z", args);
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
g_free(outParameter);
|
||||
int returnValue;
|
||||
waitpid(pid, &returnValue, 0);
|
||||
|
||||
if(returnValue != 0) {
|
||||
fprintf(stderr, "\nFailed to decompress archive\n");
|
||||
return returnValue;
|
||||
}
|
||||
//make everything lowercase since 7z don't have an argument for that.
|
||||
casefold(outdir);
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
#include "archives.h"
|
||||
|
||||
static const char * extractLastPart(const char * filePath, const char delimeter) {
|
||||
const int length = strlen(filePath);
|
||||
@@ -118,19 +30,18 @@ static const char * extractFileName(const char * filePath) {
|
||||
return extractLastPart(filePath, '/');
|
||||
}
|
||||
|
||||
int addMod(char * filePath, int appId) {
|
||||
int returnValue = EXIT_SUCCESS;
|
||||
|
||||
error_t addMod(char * filePath, int appId) {
|
||||
error_t resultError = ERR_SUCCESS;
|
||||
if (access(filePath, F_OK) != 0) {
|
||||
fprintf(stderr, "File not found\n");
|
||||
returnValue = EXIT_FAILURE;
|
||||
resultError = ERR_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
char * configFolder = g_build_filename(getenv("HOME"), MANAGER_FILES, NULL);
|
||||
if(g_mkdir_with_parents(configFolder, 0755) < 0) {
|
||||
fprintf(stderr, "Could not create mod folder");
|
||||
returnValue = EXIT_FAILURE;
|
||||
resultError = ERR_FAILURE;
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
@@ -143,6 +54,8 @@ int addMod(char * filePath, int appId) {
|
||||
char * outdir = g_build_filename(configFolder, MOD_FOLDER_NAME, appIdStr, filename, NULL);
|
||||
|
||||
g_mkdir_with_parents(outdir, 0755);
|
||||
|
||||
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);
|
||||
@@ -155,6 +68,9 @@ int addMod(char * filePath, int appId) {
|
||||
returnValue = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if(returnValue == EXIT_FAILURE)
|
||||
resultError = ERR_FAILURE;
|
||||
|
||||
printf("Done\n");
|
||||
|
||||
free(lowercaseExtension);
|
||||
@@ -162,5 +78,5 @@ int addMod(char * filePath, int appId) {
|
||||
exit2:
|
||||
free(configFolder);
|
||||
exit:
|
||||
return returnValue;
|
||||
return resultError;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,7 @@
|
||||
#ifndef __INSTALL_H__
|
||||
#define __INSTALL_H__
|
||||
#include <stdlib.h>
|
||||
#include "main.h"
|
||||
#define INSTALLED_FLAG_FILE "__DO_NOT_REMOVE__"
|
||||
|
||||
/**
|
||||
@@ -8,8 +9,7 @@
|
||||
*
|
||||
* @param filePath path to the mod file
|
||||
* @param appId game for which the mod is destined to be used with.
|
||||
* @return EXIT_SUCCESS or EXIT_FAILURE
|
||||
*/
|
||||
int addMod(char * filePath, int appId);
|
||||
error_t addMod(char * filePath, int appId);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef __MAIN_H__
|
||||
#define __MAIN_H__
|
||||
|
||||
//no function should ever be put here, only keep important macros here
|
||||
|
||||
#define APP_NAME "modmanager"
|
||||
@@ -13,3 +16,7 @@
|
||||
#define GAME_WORK_DIR_NAME "WORK_DIRS"
|
||||
|
||||
#define VERSION "0.1"
|
||||
|
||||
typedef enum { ERR_SUCCESS, ERR_FAILURE } error_t;
|
||||
|
||||
#endif
|
||||
|
||||
+4
-4
@@ -94,7 +94,7 @@ GList * listMods(int appid) {
|
||||
}
|
||||
|
||||
|
||||
int swapPlace(int appid, int modIdA, int modIdB) {
|
||||
error_t swapPlace(int appid, int modIdA, int modIdB) {
|
||||
char appidStr[10];
|
||||
sprintf(appidStr, "%d", appid);
|
||||
|
||||
@@ -116,7 +116,7 @@ int swapPlace(int appid, int modIdA, int modIdB) {
|
||||
|
||||
if(listA == NULL || listB == NULL) {
|
||||
fprintf(stderr, "Invalid modId\n");
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
char * modAFolder = g_build_filename(modFolder, listA->data, ORDER_FILE, NULL);
|
||||
@@ -131,7 +131,7 @@ int swapPlace(int appid, int modIdA, int modIdB) {
|
||||
|
||||
if(fileA == NULL || fileB == NULL) {
|
||||
fprintf(stderr, "Error could not open order file\n");
|
||||
return EXIT_FAILURE;
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
fprintf(fileA, "%d", modIdB);
|
||||
@@ -141,5 +141,5 @@ int swapPlace(int appid, int modIdA, int modIdB) {
|
||||
fclose(fileB);
|
||||
|
||||
g_list_free_full(list, free);
|
||||
return EXIT_SUCCESS;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
#define __ORDER_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include "main.h"
|
||||
|
||||
#define ORDER_FILE "__ORDER__"
|
||||
|
||||
@@ -24,6 +25,6 @@ GList * listMods(int appid);
|
||||
* @param modId
|
||||
* @param modId2
|
||||
*/
|
||||
int swapPlace(int appid, int modId, int modId2);
|
||||
error_t swapPlace(int appid, int modId, int modId2);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __STEAM_H__
|
||||
|
||||
#include "macro.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
Reference in New Issue
Block a user