Add clang-format for formatting, check building the example in CI

This commit is contained in:
Maschell 2022-02-03 16:24:36 +01:00
parent 9d41a89c45
commit d3cf0691ef
26 changed files with 503 additions and 348 deletions

67
.clang-format Normal file
View File

@ -0,0 +1,67 @@
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never

46
.github/workflows/pr.yml vendored Normal file
View File

@ -0,0 +1,46 @@
name: CI-PR
on: [pull_request]
jobs:
clang-format-lib:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./include ./libraries
build-lib:
runs-on: ubuntu-18.04
needs: clang-format-lib
steps:
- uses: actions/checkout@v2
- name: build binary
run: |
docker build . -f Dockerfile.buildlocal -t builder
docker run --rm -v ${PWD}:/project builder make
- uses: actions/upload-artifact@master
with:
name: binary
path: "/lib/*.a"
clang-format-examples:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./plugins/example_plugin/src
build-examples:
runs-on: ubuntu-18.04
needs: clang-format-examples
steps:
- uses: actions/checkout@v2
- name: build binary
run: |
docker build . -f Dockerfile.buildexamples -t builder
cd ./plugins/example_plugin
docker run --rm -v ${PWD}:/project builder make
- uses: actions/upload-artifact@master
with:
name: binary
path: "*.wps"

View File

@ -4,13 +4,38 @@ on:
branches: branches:
- master - master
jobs: jobs:
build: clang-format-lib:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./include ./libraries
clang-format-examples:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./plugins/example_plugin/src
build-examples:
runs-on: ubuntu-18.04
needs: clang-format-examples
steps:
- uses: actions/checkout@v2
- name: build binary
run: |
docker build . -f Dockerfile.buildexamples -t builder
cd ./plugins/example_plugin
docker run --rm -v ${PWD}:/project builder make
push_image:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: clang-format-lib
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: Get release version - name: Get release version
id: get_release_tag id: get_release_tag
run: | run: |
echo RELEASE_VERSION=$(echo $(date '+%Y%m%d')) >> $GITHUB_ENV echo RELEASE_VERSION=$(echo $(date '+%Y%m%d')) >> $GITHUB_ENV
echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//" | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//" | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
echo REPOSITORY_OWNER=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $1}' | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV echo REPOSITORY_OWNER=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $1}' | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV

View File

@ -1,4 +1,4 @@
FROM wiiuenv/devkitppc:20210920 FROM wiiuenv/devkitppc:20211229
WORKDIR tmp_build WORKDIR tmp_build
COPY . . COPY . .

15
Dockerfile.buildexamples Normal file
View File

@ -0,0 +1,15 @@
FROM wiiuenv/devkitppc:20211229
WORKDIR tmp_build
COPY . .
RUN make clean && make && mkdir -p /artifacts/wups && cp -r lib /artifacts/wups && cp -r include /artifacts/wups && cp -r share /artifacts/wups
WORKDIR /artifacts
FROM scratch as libwups
COPY --from=0 /artifacts /artifacts
FROM wiiuenv/devkitppc:20211229
COPY --from=libwups /artifacts $DEVKITPRO
WORKDIR project

3
Dockerfile.buildlocal Normal file
View File

@ -0,0 +1,3 @@
FROM wiiuenv/devkitppc:20211229
WORKDIR project

View File

@ -56,6 +56,10 @@ This has been created by @dimok789 and can be found in the tools folder.
# Future and contribution # Future and contribution
On the Discord you can more information about open tasks and how to contribute: https://discord.gg/bZ2rep2 On the Discord you can more information about open tasks and how to contribute: https://discord.gg/bZ2rep2
## Format the code via docker
`docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./include ./libraries ./plugins/example_plugin/src -i`
# Credits # Credits
Some files are based on brainslug by Chadderz: Some files are based on brainslug by Chadderz:
https://github.com/Chadderz121/brainslug-wii https://github.com/Chadderz121/brainslug-wii

View File

@ -26,9 +26,9 @@
#pragma once #pragma once
#include "wups/common.h" #include "wups/common.h"
#include "wups/meta.h"
#include "wups/function_patching.h"
#include "wups/config.h" #include "wups/config.h"
#include "wups/hooks.h"
#include "wups/config_imports.h" #include "wups/config_imports.h"
#include "wups/function_patching.h"
#include "wups/hooks.h"
#include "wups/meta.h"
#include "wups/storage.h" #include "wups/storage.h"

View File

@ -25,24 +25,24 @@
#pragma once #pragma once
#include <dirent.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <dirent.h>
#include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define WUPS_SECTION(x) __attribute__((__section__ (".wups." x))) #define WUPS_SECTION(x) __attribute__((__section__(".wups." x)))
#define WUPS_META(id, value) \ #define WUPS_META(id, value) \
extern const char wups_meta_ ## id [] WUPS_SECTION("meta"); \ extern const char wups_meta_##id[] WUPS_SECTION("meta"); \
const char wups_meta_ ## id [] = #id "=" value const char wups_meta_##id[] = #id "=" value
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -19,17 +19,17 @@
#include <stdint.h> #include <stdint.h>
#define WUPS_CONFIG_BUTTON_NONE 0 #define WUPS_CONFIG_BUTTON_NONE 0
#define WUPS_CONFIG_BUTTON_LEFT (1<<0) #define WUPS_CONFIG_BUTTON_LEFT (1 << 0)
#define WUPS_CONFIG_BUTTON_RIGHT (1<<1) #define WUPS_CONFIG_BUTTON_RIGHT (1 << 1)
#define WUPS_CONFIG_BUTTON_UP (1<<2) #define WUPS_CONFIG_BUTTON_UP (1 << 2)
#define WUPS_CONFIG_BUTTON_DOWN (1<<3) #define WUPS_CONFIG_BUTTON_DOWN (1 << 3)
#define WUPS_CONFIG_BUTTON_A (1<<4) #define WUPS_CONFIG_BUTTON_A (1 << 4)
#define WUPS_CONFIG_BUTTON_B (1<<5) #define WUPS_CONFIG_BUTTON_B (1 << 5)
#define WUPS_CONFIG_BUTTON_ZL (1<<6) #define WUPS_CONFIG_BUTTON_ZL (1 << 6)
#define WUPS_CONFIG_BUTTON_ZR (1<<7) #define WUPS_CONFIG_BUTTON_ZR (1 << 7)
#define WUPS_CONFIG_BUTTON_L (1<<8) #define WUPS_CONFIG_BUTTON_L (1 << 8)
#define WUPS_CONFIG_BUTTON_R (1<<9) #define WUPS_CONFIG_BUTTON_R (1 << 9)
typedef int32_t WUPSConfigButtons; typedef int32_t WUPSConfigButtons;
typedef struct { typedef struct {

View File

@ -20,20 +20,20 @@ bool WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const c
const char *falseValue); const char *falseValue);
#define WUPSConfigItemBoolean_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __callback__) \ #define WUPSConfigItemBoolean_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __callback__) \
do { \ do { \
if (!WUPSConfigItemBoolean_AddToCategory(__cat__, __configID__, __displayName__, __defaultValue__, __callback__)) { \ if (!WUPSConfigItemBoolean_AddToCategory(__cat__, __configID__, __displayName__, __defaultValue__, __callback__)) { \
WUPSConfig_Destroy(__config__); \ WUPSConfig_Destroy(__config__); \
return 0; \ return 0; \
} \ } \
} while(0) } while (0)
#define WUPSConfigItemBoolean_AddToCategoryHandledEx(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__) \ #define WUPSConfigItemBoolean_AddToCategoryHandledEx(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__) \
do { \ do { \
if (!WUPSConfigItemBoolean_AddToCategoryEx(__cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__)) { \ if (!WUPSConfigItemBoolean_AddToCategoryEx(__cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__)) { \
WUPSConfig_Destroy(__config__); \ WUPSConfig_Destroy(__config__); \
return 0; \ return 0; \
} \ } \
} while(0) } while (0)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -15,18 +15,17 @@ typedef struct ConfigItemIntegerRange {
typedef void (*IntegerRangeValueChangedCallback)(ConfigItemIntegerRange *, int32_t); typedef void (*IntegerRangeValueChangedCallback)(ConfigItemIntegerRange *, int32_t);
bool bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName,
WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, int32_t defaultValue, int32_t minValue, int32_t maxValue,
int32_t defaultValue, int32_t minValue, int32_t maxValue, IntegerRangeValueChangedCallback callback);
IntegerRangeValueChangedCallback callback);
#define WUPSConfigItemIntegerRange_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__) \ #define WUPSConfigItemIntegerRange_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__) \
do { \ do { \
if (!WUPSConfigItemIntegerRange_AddToCategory(__cat__, __configID__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__)) { \ if (!WUPSConfigItemIntegerRange_AddToCategory(__cat__, __configID__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__)) { \
WUPSConfig_Destroy(__config__); \ WUPSConfig_Destroy(__config__); \
return 0; \ return 0; \
} \ } \
} while(0) } while (0)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -25,12 +25,12 @@ bool WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, co
int pairCount, MultipleValuesChangedCallback callback); int pairCount, MultipleValuesChangedCallback callback);
#define WUPSConfigItemMultipleValues_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__) \ #define WUPSConfigItemMultipleValues_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__) \
do { \ do { \
if(!WUPSConfigItemMultipleValues_AddToCategory(__cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__)) { \ if (!WUPSConfigItemMultipleValues_AddToCategory(__cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__)) { \
WUPSConfig_Destroy(__config__); \ WUPSConfig_Destroy(__config__); \
return 0; \ return 0; \
} \ } \
} while(0) } while (0)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "stdint.h"
#include "config.h" #include "config.h"
#include "stdint.h"
extern "C" int32_t WUPSConfigItem_Create(WUPSConfigItemHandle *out, const char *configID, const char *displayName, WUPSConfigCallbacks_t callbacks, void *context); extern "C" int32_t WUPSConfigItem_Create(WUPSConfigItemHandle *out, const char *configID, const char *displayName, WUPSConfigCallbacks_t callbacks, void *context);
@ -37,17 +37,17 @@ extern "C" int32_t WUPSConfigCategory_GetName(WUPSConfigCategoryHandle handle, c
extern "C" int32_t WUPSConfigCategory_AddItem(WUPSConfigCategoryHandle handle, WUPSConfigItemHandle item_Handle); extern "C" int32_t WUPSConfigCategory_AddItem(WUPSConfigCategoryHandle handle, WUPSConfigItemHandle item_Handle);
#define WUPSConfig_AddCategoryByNameHandled(__config__, __categoryName__, __out__) \ #define WUPSConfig_AddCategoryByNameHandled(__config__, __categoryName__, __out__) \
do { \ do { \
if (WUPSConfig_AddCategoryByName(__config__, __categoryName__, __out__) < 0) { \ if (WUPSConfig_AddCategoryByName(__config__, __categoryName__, __out__) < 0) { \
WUPSConfig_Destroy(__config__); \ WUPSConfig_Destroy(__config__); \
return 0;\ return 0; \
} \ } \
} while(0) } while (0)
#define WUPSConfig_CreateHandled(__config__, __configName__) \ #define WUPSConfig_CreateHandled(__config__, __configName__) \
do { \ do { \
if (WUPSConfig_Create(__config__, __configName__) < 0) { \ if (WUPSConfig_Create(__config__, __configName__) < 0) { \
return 0; \ return 0; \
} \ } \
} while(0) } while (0)

View File

@ -108,65 +108,63 @@ typedef enum wups_loader_entry_type_t {
} wups_loader_entry_type_t; } wups_loader_entry_type_t;
typedef enum WUPSFPTargetProcess { typedef enum WUPSFPTargetProcess {
WUPS_FP_TARGET_PROCESS_ALL = 0xFF, WUPS_FP_TARGET_PROCESS_ALL = 0xFF,
WUPS_FP_TARGET_PROCESS_ROOT_RPX = 1, WUPS_FP_TARGET_PROCESS_ROOT_RPX = 1,
WUPS_FP_TARGET_PROCESS_WII_U_MENU = 2, WUPS_FP_TARGET_PROCESS_WII_U_MENU = 2,
WUPS_FP_TARGET_PROCESS_TVII = 3, WUPS_FP_TARGET_PROCESS_TVII = 3,
WUPS_FP_TARGET_PROCESS_E_MANUAL = 4, WUPS_FP_TARGET_PROCESS_E_MANUAL = 4,
WUPS_FP_TARGET_PROCESS_HOME_MENU = 5, WUPS_FP_TARGET_PROCESS_HOME_MENU = 5,
WUPS_FP_TARGET_PROCESS_ERROR_DISPLAY = 6, WUPS_FP_TARGET_PROCESS_ERROR_DISPLAY = 6,
WUPS_FP_TARGET_PROCESS_MINI_MIIVERSE = 7, WUPS_FP_TARGET_PROCESS_MINI_MIIVERSE = 7,
WUPS_FP_TARGET_PROCESS_BROWSER = 8, WUPS_FP_TARGET_PROCESS_BROWSER = 8,
WUPS_FP_TARGET_PROCESS_MIIVERSE = 9, WUPS_FP_TARGET_PROCESS_MIIVERSE = 9,
WUPS_FP_TARGET_PROCESS_ESHOP = 10, WUPS_FP_TARGET_PROCESS_ESHOP = 10,
WUPS_FP_TARGET_PROCESS_PFID_11 = 11, WUPS_FP_TARGET_PROCESS_PFID_11 = 11,
WUPS_FP_TARGET_PROCESS_DOWNLOAD_MANAGER = 12, WUPS_FP_TARGET_PROCESS_DOWNLOAD_MANAGER = 12,
WUPS_FP_TARGET_PROCESS_PFID_13 = 13, WUPS_FP_TARGET_PROCESS_PFID_13 = 13,
WUPS_FP_TARGET_PROCESS_PFID_14 = 14, WUPS_FP_TARGET_PROCESS_PFID_14 = 14,
WUPS_FP_TARGET_PROCESS_GAME = 15, WUPS_FP_TARGET_PROCESS_GAME = 15,
WUPS_FP_TARGET_PROCESS_GAME_AND_MENU = 16, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU = 16,
} WUPSFPTargetProcess; } WUPSFPTargetProcess;
typedef struct wups_loader_entry_t { typedef struct wups_loader_entry_t {
wups_loader_entry_type_t type; wups_loader_entry_type_t type;
struct { struct {
const void * physical_address; /* (optional) Physical Address. If set, the name and lib will be ignored */ const void *physical_address; /* (optional) Physical Address. If set, the name and lib will be ignored */
const void * virtual_address; /* (optional) Physical Address. If set, the name and lib will be ignored */ const void *virtual_address; /* (optional) Physical Address. If set, the name and lib will be ignored */
const char * name; /* Name of the function that will be replaced */ const char *name; /* Name of the function that will be replaced */
const wups_loader_library_type_t library; /**/ const wups_loader_library_type_t library; /**/
const char * my_function_name; /* Function name of your own, new function (my_XXX) */ const char *my_function_name; /* Function name of your own, new function (my_XXX) */
const void * target; /* Address of our own, new function (my_XXX)*/ const void *target; /* Address of our own, new function (my_XXX)*/
const void * call_addr; /* Address for calling the real function.(real_XXX) */ const void *call_addr; /* Address for calling the real function.(real_XXX) */
const WUPSFPTargetProcess targetProcess; /* Target process*/ const WUPSFPTargetProcess targetProcess; /* Target process*/
} _function; } _function;
} wups_loader_entry_t; } wups_loader_entry_t;
#define WUPS_MUST_REPLACE_PHYSICAL(x, physical_address, virtual_address) WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU) #define WUPS_MUST_REPLACE_PHYSICAL(x, physical_address, virtual_address) WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU)
#define WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, targetProcess) WUPS_MUST_REPLACE_EX(physical_address, virtual_address, real_ ## x, WUPS_LOADER_LIBRARY_OTHER, my_ ## x, x, targetProcess) #define WUPS_MUST_REPLACE_PHYSICAL_FOR_PROCESS(x, physical_address, virtual_address, targetProcess) WUPS_MUST_REPLACE_EX(physical_address, virtual_address, real_##x, WUPS_LOADER_LIBRARY_OTHER, my_##x, x, targetProcess)
#define WUPS_MUST_REPLACE(x, lib, function_name) WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU) #define WUPS_MUST_REPLACE(x, lib, function_name) WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, WUPS_FP_TARGET_PROCESS_GAME_AND_MENU)
#define WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, targetProcess) WUPS_MUST_REPLACE_EX(NULL, NULL, real_ ## x, lib, my_ ## x, function_name, targetProcess) #define WUPS_MUST_REPLACE_FOR_PROCESS(x, lib, function_name, targetProcess) WUPS_MUST_REPLACE_EX(NULL, NULL, real_##x, lib, my_##x, function_name, targetProcess)
#define WUPS_MUST_REPLACE_EX(pAddress, vAddress, original_func, rpl_type, replace_func, replace_function_name, process) \ #define WUPS_MUST_REPLACE_EX(pAddress, vAddress, original_func, rpl_type, replace_func, replace_function_name, process) \
extern const wups_loader_entry_t wups_load_ ## replace_func \ extern const wups_loader_entry_t wups_load_##replace_func \
WUPS_SECTION("load"); \ WUPS_SECTION("load"); \
const wups_loader_entry_t wups_load_ ## replace_func = { \ const wups_loader_entry_t wups_load_##replace_func = { \
.type = WUPS_LOADER_ENTRY_FUNCTION_MANDATORY, \ .type = WUPS_LOADER_ENTRY_FUNCTION_MANDATORY, \
._function = { \ ._function = { \
.physical_address = (const void*) pAddress, \ .physical_address = (const void *) pAddress, \
.virtual_address = (const void*) vAddress, \ .virtual_address = (const void *) vAddress, \
.name = #replace_function_name, \ .name = #replace_function_name, \
.library = rpl_type, \ .library = rpl_type, \
.my_function_name = #replace_func, \ .my_function_name = #replace_func, \
.target = (const void*)&(replace_func), \ .target = (const void *) &(replace_func), \
.call_addr = (const void*)&(original_func), \ .call_addr = (const void *) &(original_func), \
.targetProcess = process\ .targetProcess = process}}
} \
}
#define DECL_FUNCTION(res, name, ...) \ #define DECL_FUNCTION(res, name, ...) \
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".data"))); \ res (*real_##name)(__VA_ARGS__) __attribute__((section(".data"))); \
res my_ ## name(__VA_ARGS__) res my_##name(__VA_ARGS__)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -23,12 +23,11 @@
extern "C" { extern "C" {
#endif #endif
#define WUPS_HOOK_EX(type_def, original_func) \ #define WUPS_HOOK_EX(type_def, original_func) \
extern const wups_loader_hook_t wups_hooks_ ## original_func WUPS_SECTION("hooks"); \ extern const wups_loader_hook_t wups_hooks_##original_func WUPS_SECTION("hooks"); \
const wups_loader_hook_t wups_hooks_ ## original_func = { \ const wups_loader_hook_t wups_hooks_##original_func = { \
.type = type_def, \ .type = type_def, \
.target = (const void*)&(original_func) \ .target = (const void *) &(original_func)}
}
typedef enum wups_loader_hook_type_t { typedef enum wups_loader_hook_type_t {
WUPS_LOADER_HOOK_INIT_WUT_MALLOC, WUPS_LOADER_HOOK_INIT_WUT_MALLOC,
@ -42,85 +41,85 @@ typedef enum wups_loader_hook_type_t {
WUPS_LOADER_HOOK_INIT_WUT_SOCKETS, WUPS_LOADER_HOOK_INIT_WUT_SOCKETS,
WUPS_LOADER_HOOK_FINI_WUT_SOCKETS, WUPS_LOADER_HOOK_FINI_WUT_SOCKETS,
WUPS_LOADER_HOOK_INIT_WRAPPER, /* Calls __init */ WUPS_LOADER_HOOK_INIT_WRAPPER, /* Calls __init */
WUPS_LOADER_HOOK_FINI_WRAPPER, /* Calls __fini */ WUPS_LOADER_HOOK_FINI_WRAPPER, /* Calls __fini */
WUPS_LOADER_HOOK_GET_CONFIG, WUPS_LOADER_HOOK_GET_CONFIG,
WUPS_LOADER_HOOK_CONFIG_CLOSED, WUPS_LOADER_HOOK_CONFIG_CLOSED,
WUPS_LOADER_HOOK_INIT_STORAGE, /* Only for internal usage */ WUPS_LOADER_HOOK_INIT_STORAGE, /* Only for internal usage */
WUPS_LOADER_HOOK_INIT_PLUGIN, /* Called when exiting the plugin loader */ WUPS_LOADER_HOOK_INIT_PLUGIN, /* Called when exiting the plugin loader */
WUPS_LOADER_HOOK_DEINIT_PLUGIN, /* Called when re-entering the plugin loader */ WUPS_LOADER_HOOK_DEINIT_PLUGIN, /* Called when re-entering the plugin loader */
WUPS_LOADER_HOOK_APPLICATION_STARTS, /* Called when an application gets started */ WUPS_LOADER_HOOK_APPLICATION_STARTS, /* Called when an application gets started */
WUPS_LOADER_HOOK_FUNCTIONS_PATCHED, /* Called when the functions where patched */ WUPS_LOADER_HOOK_FUNCTIONS_PATCHED, /* Called when the functions where patched */
WUPS_LOADER_HOOK_RELEASE_FOREGROUND, /* Called when an foreground is going to be released */ WUPS_LOADER_HOOK_RELEASE_FOREGROUND, /* Called when an foreground is going to be released */
WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, /* Called when an foreground is acquired */ WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, /* Called when an foreground is acquired */
WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT, /* Called when an application wants to exit */ WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT, /* Called when an application wants to exit */
WUPS_LOADER_HOOK_APPLICATION_ENDS, /* Called when an application ends */ WUPS_LOADER_HOOK_APPLICATION_ENDS, /* Called when an application ends */
} wups_loader_hook_type_t; } wups_loader_hook_type_t;
typedef struct wups_loader_hook_t { typedef struct wups_loader_hook_t {
wups_loader_hook_type_t type; /* Defines the type of the hook */ wups_loader_hook_type_t type; /* Defines the type of the hook */
const void *target; /* Address of our own, new function */ const void *target; /* Address of our own, new function */
} wups_loader_hook_t; } wups_loader_hook_t;
#define INITIALIZE_PLUGIN() \ #define INITIALIZE_PLUGIN() \
void init_plugin(void);\ void init_plugin(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_PLUGIN,init_plugin); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_PLUGIN, init_plugin); \
void init_plugin() void init_plugin()
#define DEINITIALIZE_PLUGIN() \ #define DEINITIALIZE_PLUGIN() \
void deinit_plugin(void);\ void deinit_plugin(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_DEINIT_PLUGIN,deinit_plugin); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_DEINIT_PLUGIN, deinit_plugin); \
void deinit_plugin() void deinit_plugin()
#define ON_APPLICATION_START() \ #define ON_APPLICATION_START() \
void on_app_starting();\ void on_app_starting(); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_STARTS,on_app_starting); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_STARTS, on_app_starting); \
void on_app_starting() void on_app_starting()
#define ON_FUNCTIONS_PATCHED() \ #define ON_FUNCTIONS_PATCHED() \
void on_functions_patched();\ void on_functions_patched(); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FUNCTIONS_PATCHED,on_functions_patched); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_FUNCTIONS_PATCHED, on_functions_patched); \
void on_functions_patched() void on_functions_patched()
#define ON_RELEASE_FOREGROUND() \ #define ON_RELEASE_FOREGROUND() \
void on_release_foreground(void);\ void on_release_foreground(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_RELEASE_FOREGROUND,on_release_foreground); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_RELEASE_FOREGROUND, on_release_foreground); \
void on_release_foreground(void) void on_release_foreground(void)
#define ON_ACQUIRED_FOREGROUND() \ #define ON_ACQUIRED_FOREGROUND() \
void on_acquired_foreground(void);\ void on_acquired_foreground(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND,on_acquired_foreground); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, on_acquired_foreground); \
void on_acquired_foreground(void) void on_acquired_foreground(void)
#define ON_APPLICATION_REQUESTS_EXIT() \ #define ON_APPLICATION_REQUESTS_EXIT() \
void on_app_requests_exit(void);\ void on_app_requests_exit(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT,on_app_requests_exit); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT, on_app_requests_exit); \
void on_app_requests_exit(void) void on_app_requests_exit(void)
#define ON_APPLICATION_ENDS() \ #define ON_APPLICATION_ENDS() \
void on_app_ending(void);\ void on_app_ending(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_ENDS,on_app_ending); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_ENDS, on_app_ending); \
void on_app_ending(void) void on_app_ending(void)
#define WUPS_GET_CONFIG() \ #define WUPS_GET_CONFIG() \
WUPSConfigHandle on_get_wups_config(void);\ WUPSConfigHandle on_get_wups_config(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_GET_CONFIG,on_get_wups_config); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_GET_CONFIG, on_get_wups_config); \
WUPSConfigHandle on_get_wups_config(void) WUPSConfigHandle on_get_wups_config(void)
#define WUPS_CONFIG_CLOSED() \ #define WUPS_CONFIG_CLOSED() \
void on_wups_config_closed(void);\ void on_wups_config_closed(void); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_CONFIG_CLOSED,on_wups_config_closed); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_CONFIG_CLOSED, on_wups_config_closed); \
void on_wups_config_closed(void) void on_wups_config_closed(void)
#define WUPS_USE_STORAGE(x) \ #define WUPS_USE_STORAGE(x) \
WUPS_META(storage_id, x); \ WUPS_META(storage_id, x); \
void init_storage(wups_loader_init_storage_args_t);\ void init_storage(wups_loader_init_storage_args_t); \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_STORAGE,init_storage); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_STORAGE, init_storage); \
void init_storage(wups_loader_init_storage_args_t args){ \ void init_storage(wups_loader_init_storage_args_t args) { \
WUPS_InitStorage(args);\ WUPS_InitStorage(args); \
} }
#ifdef __cplusplus #ifdef __cplusplus
@ -129,79 +128,79 @@ typedef struct wups_loader_hook_t {
#define __EXTERN_C_MACRO #define __EXTERN_C_MACRO
#endif #endif
#define WUPS_USE_WUT_MALLOC() \ #define WUPS_USE_WUT_MALLOC() \
__EXTERN_C_MACRO void __init_wut_malloc(); \ __EXTERN_C_MACRO void __init_wut_malloc(); \
void on_init_wut_malloc(){ \ void on_init_wut_malloc() { \
__init_wut_malloc(); \ __init_wut_malloc(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_MALLOC,on_init_wut_malloc); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_MALLOC, on_init_wut_malloc); \
__EXTERN_C_MACRO void __fini_wut_malloc(); \ __EXTERN_C_MACRO void __fini_wut_malloc(); \
void on_fini_wut_malloc(){ \ void on_fini_wut_malloc() { \
__fini_wut_malloc(); \ __fini_wut_malloc(); \
} \ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_MALLOC,on_fini_wut_malloc) WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_MALLOC, on_fini_wut_malloc)
#define WUPS_USE_WUT_DEVOPTAB() \ #define WUPS_USE_WUT_DEVOPTAB() \
__EXTERN_C_MACRO void __init_wut_devoptab(); \ __EXTERN_C_MACRO void __init_wut_devoptab(); \
void on_init_wut_devoptab(){ \ void on_init_wut_devoptab() { \
__init_wut_devoptab(); \ __init_wut_devoptab(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB,on_init_wut_devoptab); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB, on_init_wut_devoptab); \
__EXTERN_C_MACRO void __fini_wut_devoptab(); \ __EXTERN_C_MACRO void __fini_wut_devoptab(); \
void on_fini_wut_devoptab(){ \ void on_fini_wut_devoptab() { \
__fini_wut_devoptab(); \ __fini_wut_devoptab(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB,on_fini_wut_devoptab) WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB, on_fini_wut_devoptab)
#define WUPS_USE_WUT_NEWLIB() \ #define WUPS_USE_WUT_NEWLIB() \
__EXTERN_C_MACRO void __init_wut_newlib(); \ __EXTERN_C_MACRO void __init_wut_newlib(); \
void on_init_wut_newlib(){ \ void on_init_wut_newlib() { \
__init_wut_newlib(); \ __init_wut_newlib(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_NEWLIB,on_init_wut_newlib); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_NEWLIB, on_init_wut_newlib); \
__EXTERN_C_MACRO void __fini_wut_newlib(); \ __EXTERN_C_MACRO void __fini_wut_newlib(); \
void on_fini_wut_newlib(){ \ void on_fini_wut_newlib() { \
__fini_wut_newlib(); \ __fini_wut_newlib(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_NEWLIB,on_fini_wut_newlib) WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_NEWLIB, on_fini_wut_newlib)
#define WUPS_USE_WUT_STDCPP() \ #define WUPS_USE_WUT_STDCPP() \
__EXTERN_C_MACRO void __init_wut_stdcpp(); \ __EXTERN_C_MACRO void __init_wut_stdcpp(); \
void on_init_wut_stdcpp(){ \ void on_init_wut_stdcpp() { \
__init_wut_stdcpp(); \ __init_wut_stdcpp(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_STDCPP,on_init_wut_stdcpp); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_STDCPP, on_init_wut_stdcpp); \
__EXTERN_C_MACRO void __fini_wut_stdcpp(); \ __EXTERN_C_MACRO void __fini_wut_stdcpp(); \
void on_fini_wut_stdcpp(){ \ void on_fini_wut_stdcpp() { \
__fini_wut_stdcpp(); \ __fini_wut_stdcpp(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_STDCPP,on_fini_wut_stdcpp) WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_STDCPP, on_fini_wut_stdcpp)
#define WUPS___INIT_WRAPPER() \ #define WUPS___INIT_WRAPPER() \
__EXTERN_C_MACRO void __init(); \ __EXTERN_C_MACRO void __init(); \
void __init_wrapper(){ \ void __init_wrapper() { \
__init(); \ __init(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WRAPPER,__init_wrapper); WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WRAPPER, __init_wrapper);
#define WUPS___FINI_WRAPPER() \ #define WUPS___FINI_WRAPPER() \
__EXTERN_C_MACRO void __fini(); \ __EXTERN_C_MACRO void __fini(); \
void __fini_wrapper(){ \ void __fini_wrapper() { \
__fini(); \ __fini(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WRAPPER,__fini_wrapper); WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WRAPPER, __fini_wrapper);
#define WUPS_USE_WUT_SOCKETS() \ #define WUPS_USE_WUT_SOCKETS() \
__EXTERN_C_MACRO void __attribute__((weak)) __init_wut_socket(); \ __EXTERN_C_MACRO void __attribute__((weak)) __init_wut_socket(); \
void on_init_wut_sockets(){ \ void on_init_wut_sockets() { \
if (&__init_wut_socket) __init_wut_socket(); \ if (&__init_wut_socket) __init_wut_socket(); \
} \ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_SOCKETS,on_init_wut_sockets); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_WUT_SOCKETS, on_init_wut_sockets); \
__EXTERN_C_MACRO void __attribute__((weak)) __fini_wut_socket(); \ __EXTERN_C_MACRO void __attribute__((weak)) __fini_wut_socket(); \
void on_fini_wut_sockets(){ \ void on_fini_wut_sockets() { \
if (&__fini_wut_socket) __fini_wut_socket(); \ if (&__fini_wut_socket) __fini_wut_socket(); \
}\ } \
WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_SOCKETS,on_fini_wut_sockets) WUPS_HOOK_EX(WUPS_LOADER_HOOK_FINI_WUT_SOCKETS, on_fini_wut_sockets)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -32,21 +32,22 @@
extern "C" { extern "C" {
#endif #endif
#define WUPS_PLUGIN_NAME(x) WUPS_META(name, x); \ #define WUPS_PLUGIN_NAME(x) \
WUPS_META(wups, "0.7.0"); \ WUPS_META(name, x); \
WUPS_USE_WUT_MALLOC(); \ WUPS_META(wups, "0.7.0"); \
WUPS_USE_WUT_SOCKETS(); \ WUPS_USE_WUT_MALLOC(); \
WUPS_USE_WUT_NEWLIB(); \ WUPS_USE_WUT_SOCKETS(); \
WUPS_USE_WUT_STDCPP(); \ WUPS_USE_WUT_NEWLIB(); \
WUPS___INIT_WRAPPER(); \ WUPS_USE_WUT_STDCPP(); \
WUPS___FINI_WRAPPER(); \ WUPS___INIT_WRAPPER(); \
WUPS_META(buildtimestamp, __DATE__ " " __TIME__); WUPS___FINI_WRAPPER(); \
WUPS_META(buildtimestamp, __DATE__ " " __TIME__);
#define WUPS_PLUGIN_AUTHOR(x) WUPS_META(author, x) #define WUPS_PLUGIN_AUTHOR(x) WUPS_META(author, x)
#define WUPS_PLUGIN_VERSION(x) WUPS_META(version, x) #define WUPS_PLUGIN_VERSION(x) WUPS_META(version, x)
#define WUPS_PLUGIN_LICENSE(x) WUPS_META(license, x) #define WUPS_PLUGIN_LICENSE(x) WUPS_META(license, x)
#define WUPS_PLUGIN_DESCRIPTION(x) WUPS_META(description, x) #define WUPS_PLUGIN_DESCRIPTION(x) WUPS_META(description, x)
#define WUPS_PLUGIN_CONFIG_REVISION(x) WUPS_META(config_revision, #x) #define WUPS_PLUGIN_CONFIG_REVISION(x) WUPS_META(config_revision, #x)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -15,7 +15,7 @@ typedef enum wups_storage_type_t_ {
} wups_storage_type_t; } wups_storage_type_t;
enum { enum {
WUPS_STORAGE_ERROR_SUCCESS = 0, WUPS_STORAGE_ERROR_SUCCESS = 0,
WUPS_STORAGE_ERROR_NOT_OPENED = -1, WUPS_STORAGE_ERROR_NOT_OPENED = -1,
WUPS_STORAGE_ERROR_ALREADY_OPENED = -2, WUPS_STORAGE_ERROR_ALREADY_OPENED = -2,
WUPS_STORAGE_ERROR_INVALID_ARGS = -3, WUPS_STORAGE_ERROR_INVALID_ARGS = -3,

View File

@ -1,7 +1,7 @@
#include <wups.h> #include "wups/config/WUPSConfigItemBoolean.h"
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include "wups/config/WUPSConfigItemBoolean.h" #include <wups.h>
void WUPSConfigItemBoolean_onDelete(void *context); void WUPSConfigItemBoolean_onDelete(void *context);
@ -50,7 +50,7 @@ int32_t WUPSConfigItemBoolean_getCurrentValueSelectedDisplay(void *context, char
} }
void WUPSConfigItemBoolean_restoreDefault(void *context) { void WUPSConfigItemBoolean_restoreDefault(void *context) {
auto *item = (ConfigItemBoolean *) context; auto *item = (ConfigItemBoolean *) context;
item->value = item->defaultValue; item->value = item->defaultValue;
} }
@ -69,21 +69,20 @@ WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *
} }
item->defaultValue = defaultValue; item->defaultValue = defaultValue;
item->value = defaultValue; item->value = defaultValue;
item->callback = (void *) callback; item->callback = (void *) callback;
snprintf(item->trueValue, sizeof(item->trueValue), "%s", trueValue); snprintf(item->trueValue, sizeof(item->trueValue), "%s", trueValue);
snprintf(item->falseValue, sizeof(item->falseValue), "%s", falseValue); snprintf(item->falseValue, sizeof(item->falseValue), "%s", falseValue);
WUPSConfigCallbacks_t callbacks = { WUPSConfigCallbacks_t callbacks = {
.getCurrentValueDisplay = &WUPSConfigItemBoolean_getCurrentValueDisplay, .getCurrentValueDisplay = &WUPSConfigItemBoolean_getCurrentValueDisplay,
.getCurrentValueSelectedDisplay = &WUPSConfigItemBoolean_getCurrentValueSelectedDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemBoolean_getCurrentValueSelectedDisplay,
.onSelected = &WUPSConfigItemBoolean_onSelected, .onSelected = &WUPSConfigItemBoolean_onSelected,
.restoreDefault = &WUPSConfigItemBoolean_restoreDefault, .restoreDefault = &WUPSConfigItemBoolean_restoreDefault,
.isMovementAllowed = &WUPSConfigItemBoolean_isMovementAllowed, .isMovementAllowed = &WUPSConfigItemBoolean_isMovementAllowed,
.callCallback = &WUPSConfigItemBoolean_callCallback, .callCallback = &WUPSConfigItemBoolean_callCallback,
.onButtonPressed = &WUPSConfigItemBoolean_onButtonPressed, .onButtonPressed = &WUPSConfigItemBoolean_onButtonPressed,
.onDelete = &WUPSConfigItemBoolean_onDelete .onDelete = &WUPSConfigItemBoolean_onDelete};
};
if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) { if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) {
free(item); free(item);

View File

@ -1,7 +1,7 @@
#include <wups.h> #include "wups/config/WUPSConfigItemIntegerRange.h"
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include "wups/config/WUPSConfigItemIntegerRange.h" #include <wups.h>
int32_t WUPSConfigItemIntegerRange_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { int32_t WUPSConfigItemIntegerRange_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) {
auto *item = (ConfigItemIntegerRange *) context; auto *item = (ConfigItemIntegerRange *) context;
@ -54,7 +54,7 @@ int32_t WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay(void *context,
} }
void WUPSConfigItemIntegerRange_restoreDefault(void *context) { void WUPSConfigItemIntegerRange_restoreDefault(void *context) {
auto *item = (ConfigItemIntegerRange *) context; auto *item = (ConfigItemIntegerRange *) context;
item->value = item->defaultValue; item->value = item->defaultValue;
} }
@ -64,7 +64,6 @@ void WUPSConfigItemIntegerRange_onDelete(void *context) {
} }
void WUPSConfigItemIntegerRange_onSelected(void *context, bool isSelected) { void WUPSConfigItemIntegerRange_onSelected(void *context, bool isSelected) {
} }
extern "C" bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, int32_t defaultValue, int32_t minValue, int32_t maxValue, extern "C" bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, int32_t defaultValue, int32_t minValue, int32_t maxValue,
@ -78,21 +77,20 @@ extern "C" bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandl
} }
item->defaultValue = defaultValue; item->defaultValue = defaultValue;
item->value = defaultValue; item->value = defaultValue;
item->minValue = minValue; item->minValue = minValue;
item->maxValue = maxValue; item->maxValue = maxValue;
item->callback = (void *) callback; item->callback = (void *) callback;
WUPSConfigCallbacks_t callbacks = { WUPSConfigCallbacks_t callbacks = {
.getCurrentValueDisplay = &WUPSConfigItemIntegerRange_getCurrentValueDisplay, .getCurrentValueDisplay = &WUPSConfigItemIntegerRange_getCurrentValueDisplay,
.getCurrentValueSelectedDisplay = &WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay,
.onSelected = &WUPSConfigItemIntegerRange_onSelected, .onSelected = &WUPSConfigItemIntegerRange_onSelected,
.restoreDefault = &WUPSConfigItemIntegerRange_restoreDefault, .restoreDefault = &WUPSConfigItemIntegerRange_restoreDefault,
.isMovementAllowed = &WUPSConfigItemIntegerRange_isMovementAllowed, .isMovementAllowed = &WUPSConfigItemIntegerRange_isMovementAllowed,
.callCallback = &WUPSConfigItemIntegerRange_callCallback, .callCallback = &WUPSConfigItemIntegerRange_callCallback,
.onButtonPressed = &WUPSConfigItemIntegerRange_onButtonPressed, .onButtonPressed = &WUPSConfigItemIntegerRange_onButtonPressed,
.onDelete = &WUPSConfigItemIntegerRange_onDelete .onDelete = &WUPSConfigItemIntegerRange_onDelete};
};
if (WUPSConfigItem_Create(&(item->handle), configID, displayName, callbacks, item) < 0) { if (WUPSConfigItem_Create(&(item->handle), configID, displayName, callbacks, item) < 0) {
free(item); free(item);

View File

@ -1,8 +1,8 @@
#include <wups.h> #include "wups/config/WUPSConfigItemMultipleValues.h"
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include "wups/config/WUPSConfigItemMultipleValues.h" #include <wups.h>
void WUPSConfigItemMultipleValues_onDelete(void *context); void WUPSConfigItemMultipleValues_onDelete(void *context);
@ -65,7 +65,7 @@ int32_t WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay(void *contex
} }
void WUPSConfigItemMultipleValues_restoreDefault(void *context) { void WUPSConfigItemMultipleValues_restoreDefault(void *context) {
auto *item = (ConfigItemMultipleValues *) context; auto *item = (ConfigItemMultipleValues *) context;
item->valueIndex = item->defaultValueIndex; item->valueIndex = item->defaultValueIndex;
} }
@ -92,35 +92,34 @@ WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const c
values[i].valueName = nullptr; values[i].valueName = nullptr;
continue; continue;
} }
auto bufLen = strlen(possibleValues[i].valueName) + 1; auto bufLen = strlen(possibleValues[i].valueName) + 1;
values[i].valueName = (char *) malloc(bufLen); values[i].valueName = (char *) malloc(bufLen);
strncpy(values[i].valueName, possibleValues[i].valueName, bufLen); strncpy(values[i].valueName, possibleValues[i].valueName, bufLen);
} }
item->valueCount = pairCount; item->valueCount = pairCount;
item->values = values; item->values = values;
item->valueIndex = defaultValueIndex; item->valueIndex = defaultValueIndex;
item->defaultValueIndex = defaultValueIndex; item->defaultValueIndex = defaultValueIndex;
item->callback = (void *) callback; item->callback = (void *) callback;
if (configID != nullptr) { if (configID != nullptr) {
auto configIDLen = strlen(configID) + 1; auto configIDLen = strlen(configID) + 1;
item->configID = (char *) malloc(configIDLen); item->configID = (char *) malloc(configIDLen);
strncpy(item->configID, configID, configIDLen); strncpy(item->configID, configID, configIDLen);
} else { } else {
item->configID = nullptr; item->configID = nullptr;
} }
WUPSConfigCallbacks_t callbacks = { WUPSConfigCallbacks_t callbacks = {
.getCurrentValueDisplay = &WUPSConfigItemMultipleValues_getCurrentValueDisplay, .getCurrentValueDisplay = &WUPSConfigItemMultipleValues_getCurrentValueDisplay,
.getCurrentValueSelectedDisplay = &WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay,
.onSelected = &WUPSConfigItemMultipleValues_onSelected, .onSelected = &WUPSConfigItemMultipleValues_onSelected,
.restoreDefault = &WUPSConfigItemMultipleValues_restoreDefault, .restoreDefault = &WUPSConfigItemMultipleValues_restoreDefault,
.isMovementAllowed = &WUPSConfigItemMultipleValues_isMovementAllowed, .isMovementAllowed = &WUPSConfigItemMultipleValues_isMovementAllowed,
.callCallback = &WUPSConfigItemMultipleValues_callCallback, .callCallback = &WUPSConfigItemMultipleValues_callCallback,
.onButtonPressed = &WUPSConfigItemMultipleValues_onButtonPressed, .onButtonPressed = &WUPSConfigItemMultipleValues_onButtonPressed,
.onDelete = &WUPSConfigItemMultipleValues_onDelete .onDelete = &WUPSConfigItemMultipleValues_onDelete};
};
if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) { if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) {
free(item); free(item);

View File

@ -1,12 +1,12 @@
#include <wups.h>
#include <cstring>
#include <cstdlib> #include <cstdlib>
#include <cstring>
#include <wups.h>
#include "utils/base64.h" #include "utils/base64.h"
static OpenStorageFunction openfunction_ptr __attribute__((section(".data"))) = nullptr; static OpenStorageFunction openfunction_ptr __attribute__((section(".data"))) = nullptr;
static CloseStorageFunction closefunction_ptr __attribute__((section(".data"))) = nullptr; static CloseStorageFunction closefunction_ptr __attribute__((section(".data"))) = nullptr;
static const char *plugin_id __attribute__((section(".data"))) = nullptr; static const char *plugin_id __attribute__((section(".data"))) = nullptr;
static uint32_t storage_initialized __attribute__((section(".data"))) = false; static uint32_t storage_initialized __attribute__((section(".data"))) = false;
static uint32_t isOpened __attribute__((section(".data"))); static uint32_t isOpened __attribute__((section(".data")));
@ -14,19 +14,19 @@ static uint32_t isDirty __attribute__((section(".data")));
static wups_storage_item_t rootItem __attribute__((section(".data"))); static wups_storage_item_t rootItem __attribute__((section(".data")));
void WUPS_InitStorage(wups_loader_init_storage_args_t args) { void WUPS_InitStorage(wups_loader_init_storage_args_t args) {
openfunction_ptr = args.open_storage_ptr; openfunction_ptr = args.open_storage_ptr;
closefunction_ptr = args.close_storage_ptr; closefunction_ptr = args.close_storage_ptr;
plugin_id = args.plugin_id; plugin_id = args.plugin_id;
storage_initialized = true; storage_initialized = true;
isOpened = false; isOpened = false;
isDirty = false; isDirty = false;
rootItem.key = nullptr; rootItem.key = nullptr;
rootItem.data = nullptr; rootItem.data = nullptr;
rootItem.data_size = 0; rootItem.data_size = 0;
rootItem.pending_delete = false; rootItem.pending_delete = false;
rootItem.type = WUPS_STORAGE_TYPE_ITEM; rootItem.type = WUPS_STORAGE_TYPE_ITEM;
} }
int32_t WUPS_OpenStorage(void) { int32_t WUPS_OpenStorage(void) {
@ -42,7 +42,7 @@ int32_t WUPS_OpenStorage(void) {
if (result == WUPS_STORAGE_ERROR_SUCCESS || result == WUPS_STORAGE_ERROR_INVALID_JSON) { if (result == WUPS_STORAGE_ERROR_SUCCESS || result == WUPS_STORAGE_ERROR_INVALID_JSON) {
isOpened = true; isOpened = true;
isDirty = false; isDirty = false;
} }
return result; return result;
@ -80,12 +80,12 @@ int32_t WUPS_CloseStorage(void) {
if (result == 0) { if (result == 0) {
isOpened = false; isOpened = false;
isDirty = false; isDirty = false;
closeItem(&rootItem); closeItem(&rootItem);
free(rootItem.data); free(rootItem.data);
rootItem.data_size = 0; rootItem.data_size = 0;
rootItem.data = nullptr; rootItem.data = nullptr;
} }
return result; return result;
@ -183,10 +183,10 @@ static wups_storage_item_t *addItem(wups_storage_item_t *parent, const char *key
strcpy(foundItem->key, key); strcpy(foundItem->key, key);
} }
foundItem->type = type; foundItem->type = type;
foundItem->pending_delete = false; foundItem->pending_delete = false;
foundItem->data = nullptr; foundItem->data = nullptr;
foundItem->data_size = 0; foundItem->data_size = 0;
return foundItem; return foundItem;
} }
@ -269,8 +269,8 @@ int32_t WUPS_StoreString(wups_storage_item_t *parent, const char *key, const cha
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING); wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING);
uint32_t size = strlen(string) + 1; uint32_t size = strlen(string) + 1;
item->data = malloc(size); item->data = malloc(size);
item->data_size = size; item->data_size = size;
strcpy((char *) item->data, string); strcpy((char *) item->data, string);
@ -302,8 +302,8 @@ int32_t WUPS_StoreInt(wups_storage_item_t *parent, const char *key, int32_t valu
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_INT); wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_INT);
item->data = malloc(sizeof(int32_t)); item->data = malloc(sizeof(int32_t));
item->data_size = sizeof(int32_t); item->data_size = sizeof(int32_t);
*(int32_t *) item->data = value; *(int32_t *) item->data = value;
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
@ -328,7 +328,7 @@ int32_t WUPS_StoreBinary(wups_storage_item_t *parent, const char *key, const voi
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING); wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING);
item->data = b64_encode((const uint8_t *) data, size); item->data = b64_encode((const uint8_t *) data, size);
item->data_size = strlen((char *) data) + 1; item->data_size = strlen((char *) data) + 1;
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;

View File

@ -26,8 +26,8 @@ char *b64_encode(const uint8_t *in, size_t len) {
if (in == NULL || len == 0) if (in == NULL || len == 0)
return NULL; return NULL;
elen = b64_encoded_size(len); elen = b64_encoded_size(len);
out = (char *) malloc(elen + 1); out = (char *) malloc(elen + 1);
out[elen] = '\0'; out[elen] = '\0';
for (i = 0, j = 0; i < len; i += 3, j += 4) { for (i = 0, j = 0; i < len; i += 3, j += 4) {
@ -35,7 +35,7 @@ char *b64_encode(const uint8_t *in, size_t len) {
v = i + 1 < len ? v << 8 | in[i + 1] : v << 8; v = i + 1 < len ? v << 8 | in[i + 1] : v << 8;
v = i + 2 < len ? v << 8 | in[i + 2] : v << 8; v = i + 2 < len ? v << 8 | in[i + 2] : v << 8;
out[j] = b64chars[(v >> 18) & 0x3F]; out[j] = b64chars[(v >> 18) & 0x3F];
out[j + 1] = b64chars[(v >> 12) & 0x3F]; out[j + 1] = b64chars[(v >> 12) & 0x3F];
if (i + 1 < len) { if (i + 1 < len) {
out[j + 2] = b64chars[(v >> 6) & 0x3F]; out[j + 2] = b64chars[(v >> 6) & 0x3F];
@ -77,8 +77,7 @@ size_t b64_decoded_size(const char *in) {
static const int b64invs[] = { static const int b64invs[] = {
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
};
static int b64_isvalidchar(char c) { static int b64_isvalidchar(char c) {
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
// based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/ // based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/

View File

@ -1,14 +1,14 @@
#include <wups.h> #include <coreinit/filesystem.h>
#include <whb/libmanager.h> #include <coreinit/thread.h>
#include <coreinit/time.h>
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include <utils/logger.h> #include <utils/logger.h>
#include <coreinit/time.h> #include <whb/libmanager.h>
#include <coreinit/thread.h>
#include <coreinit/filesystem.h>
#include <whb/log_cafe.h> #include <whb/log_cafe.h>
#include <whb/log_module.h> #include <whb/log_module.h>
#include <whb/log_udp.h> #include <whb/log_udp.h>
#include <wups.h>
#include <wups/config/WUPSConfigItemBoolean.h> #include <wups/config/WUPSConfigItemBoolean.h>
/** /**
@ -35,22 +35,22 @@ bool logFSOpen = true;
/** /**
Get's called ONCE when the loader exits, but BEFORE the ON_APPLICATION_START gets called or functions are overridden. Get's called ONCE when the loader exits, but BEFORE the ON_APPLICATION_START gets called or functions are overridden.
**/ **/
INITIALIZE_PLUGIN(){ INITIALIZE_PLUGIN() {
if (!WHBLogModuleInit()) { if (!WHBLogModuleInit()) {
WHBLogCafeInit(); WHBLogCafeInit();
WHBLogUdpInit(); WHBLogUdpInit();
} }
DEBUG_FUNCTION_LINE("INITIALIZE_PLUGIN of example_plugin!"); DEBUG_FUNCTION_LINE("INITIALIZE_PLUGIN of example_plugin!");
// Open storage to read values // Open storage to read values
WUPS_OpenStorage(); WUPS_OpenStorage();
// Try to get value from storage // Try to get value from storage
if(WUPS_GetBool(nullptr, "logFSOpen", &logFSOpen) != WUPS_STORAGE_ERROR_SUCCESS){ if (WUPS_GetBool(nullptr, "logFSOpen", &logFSOpen) != WUPS_STORAGE_ERROR_SUCCESS) {
// Add the value to the storage if it's missing. // Add the value to the storage if it's missing.
WUPS_StoreBool(nullptr, "logFSOpen", logFSOpen); WUPS_StoreBool(nullptr, "logFSOpen", logFSOpen);
} }
// Close storage // Close storage
WUPS_CloseStorage(); WUPS_CloseStorage();
} }
@ -59,7 +59,7 @@ INITIALIZE_PLUGIN(){
Gets called when the plugin loader is re-entered => when the plugin is unloaded. Gets called when the plugin loader is re-entered => when the plugin is unloaded.
The overridden functions are restored before this is getting called. The overridden functions are restored before this is getting called.
**/ **/
DEINITIALIZE_PLUGIN(){ DEINITIALIZE_PLUGIN() {
DEBUG_FUNCTION_LINE("DEINITIALIZE_PLUGIN of example_plugin!"); DEBUG_FUNCTION_LINE("DEINITIALIZE_PLUGIN of example_plugin!");
} }
@ -68,19 +68,19 @@ DEINITIALIZE_PLUGIN(){
This is called BEFORE the functions are overridden. This is called BEFORE the functions are overridden.
Make sure to initialize all functions you're using in the overridden functions! Make sure to initialize all functions you're using in the overridden functions!
**/ **/
ON_APPLICATION_START(){ ON_APPLICATION_START() {
if (!WHBLogModuleInit()) { if (!WHBLogModuleInit()) {
WHBLogCafeInit(); WHBLogCafeInit();
WHBLogUdpInit(); WHBLogUdpInit();
} }
DEBUG_FUNCTION_LINE("ON_APPLICATION_START of example_plugin!"); DEBUG_FUNCTION_LINE("ON_APPLICATION_START of example_plugin!");
} }
/** /**
Gets called when an application request to exit. Gets called when an application request to exit.
**/ **/
ON_APPLICATION_REQUESTS_EXIT(){ ON_APPLICATION_REQUESTS_EXIT() {
DEBUG_FUNCTION_LINE("ON_APPLICATION_REQUESTS_EXIT of example_plugin!"); DEBUG_FUNCTION_LINE("ON_APPLICATION_REQUESTS_EXIT of example_plugin!");
} }
@ -93,7 +93,7 @@ void logFSOpenChanged(ConfigItemBoolean *item, bool newValue) {
WUPS_GET_CONFIG() { WUPS_GET_CONFIG() {
// We open the storage so we can persist the configuration the user did. // We open the storage so we can persist the configuration the user did.
WUPS_OpenStorage(); WUPS_OpenStorage();
WUPSConfigHandle config; WUPSConfigHandle config;
WUPSConfig_CreateHandled(&config, "Example Plugin"); WUPSConfig_CreateHandled(&config, "Example Plugin");
@ -142,7 +142,7 @@ WUPS_CONFIG_CLOSED() {
DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) { DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) {
int result = real_FSOpenFile(pClient, pCmd, path, mode, handle, error); int result = real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
if (logFSOpen) { if (logFSOpen) {
DEBUG_FUNCTION_LINE("FSOpenFile called for folder %s! Result %d",path,result); DEBUG_FUNCTION_LINE("FSOpenFile called for folder %s! Result %d", path, result);
} }
return result; return result;
} }
@ -155,4 +155,4 @@ WUPS_MUST_REPLACE(FUNCTION_NAME_IN_THIS_FILE, NAME_OF_LIB_WHICH_CONTAINS_THIS_
Define this for each function you want to override. Define this for each function you want to override.
**/ **/
WUPS_MUST_REPLACE(FSOpenFile, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile); WUPS_MUST_REPLACE(FSOpenFile, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile);

View File

@ -8,18 +8,21 @@ extern "C" {
#include <whb/log.h> #include <whb/log.h>
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#define OSFATAL_FUNCTION_LINE(FMT, ARGS...)do { \ #define OSFATAL_FUNCTION_LINE(FMT, ARGS...) \
OSFatal_printf("[%s]%s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
OSFatal_printf("[%s]%s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0) } while (0)
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE(FMT, ARGS...) \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0); } while (0);
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) \
WHBLogWritef("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ do { \
WHBLogWritef("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0); } while (0);
#ifdef __cplusplus #ifdef __cplusplus