Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
Language: Cpp

AlignArrayOfStructures: Left
AlignConsecutiveAssignments: AcrossComments
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossComments
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true

AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false

AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false

BitFieldColonSpacing: Both

BraceWrapping:
AfterCaseLabel: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false

BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakStringLiterals: true

ColumnLimit: 111

ContinuationIndentWidth: 4

DeriveLineEnding: true
DerivePointerAlignment: false

DisableFormat: false

IncludeBlocks: Merge

IndentCaseBlocks: false
IndentCaseLabels: true
IndentExternBlock: Indent
IndentGotoLabels: true
IndentPPDirectives: BeforeHash
IndentWidth: 4
IndentWrappedFunctionNames: true

KeepEmptyLinesAtTheStartOfBlocks: false

InsertTrailingCommas: None

MaxEmptyLinesToKeep: 1

PPIndentWidth: 1

PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0

PointerAlignment: Right

QualifierAlignment: Custom
QualifierOrder: ['inline', 'static', 'restrict', 'type', 'const', 'volatile' ]

ReflowComments: true

SortIncludes: Never

SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeParens: ControlStatementsExceptControlMacros
SpacesInSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInParentheses: false
SpaceBeforeSquareBrackets: false

UseTab: Always
TabWidth: 4

UseCRLF: false
13 changes: 13 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Checks: '-*,readability-identifier-naming'
CheckOptions:
- { key: readability-identifier-naming.VariableCase, value: lower_case }
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
- { key: readability-identifier-naming.FunctionIgnoredRegexp, value: "OPC_.*" }
- { key: readability-identifier-naming.GlobalFunctionCase, value: lower_case }
- { key: readability-identifier-naming.GlobalFunctionIgnoredRegexp, value: "OPC_.*" }
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
- { key: readability-identifier-naming.StructCase, value: lower_case }
- { key: readability-identifier-naming.EnumCase, value: lower_case }
- { key: readability-identifier-naming.TypedefCase, value: lower_case }
- { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }
- { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }
3 changes: 3 additions & 0 deletions run-clang-format.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

find src/ -iname *.h -o -iname *.c | xargs clang-format -i
15 changes: 15 additions & 0 deletions run-clang-tidy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

# Clean up before regenerating compilation files
make clean

# Check whether bear (https://github.com/rizsotto/Bear) is installed
# This is required to generate compile_commands.json that clang-tidy requires
if ! [ -x "$(command -v bear)" ]; then
echo "bear could not be found. Please install it."
exit
fi

bear -- make

find src/ -iname *.h -o -iname *.c | xargs clang-tidy --fix --fix-errors --config-file=.clang-tidy
200 changes: 100 additions & 100 deletions src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,124 +19,124 @@
*** LOCAL VARIABLES ***
******************************************************/

static const char* usage_str = "cretro [-d <0..4>] [-f <FREQUENCY_HZ>] <ROM>";
static char const *usage_str = "cretro [-d <0..4>] [-f <FREQUENCY_HZ>] <ROM>";

/******************************************************
*** LOCAL METHODS ***
******************************************************/

static int safe_strtol(const char* str_to_conv, int* store_into) {
char* end;
const long strtol_in = strtol(str_to_conv, &end, 10);

errno = 0;

if (end == str_to_conv) {
LOG_FATAL("%s: not a decimal number", str_to_conv);
} else if ('\0' != *end) {
LOG_FATAL("%s: extra characters at end of input: %s", str_to_conv, end);
} else if ((LONG_MIN == strtol_in || LONG_MAX == strtol_in) && ERANGE == errno) {
LOG_FATAL("%s out of range of type long", str_to_conv);
} else if (strtol_in > INT_MAX) {
LOG_FATAL("%ld greater than INT_MAX", strtol_in);
} else if (strtol_in < INT_MIN) {
LOG_FATAL("%ld less than INT_MIN", strtol_in);
} else {
*store_into = (int)strtol_in;
return EXIT_SUCCESS;
}

return EXIT_FAILURE;
static int safe_strtol(char const *str_to_conv, int *store_into) {
char *end;
long const strtol_in = strtol(str_to_conv, &end, 10);

errno = 0;

if (end == str_to_conv) {
LOG_FATAL("%s: not a decimal number", str_to_conv);
} else if ('\0' != *end) {
LOG_FATAL("%s: extra characters at end of input: %s", str_to_conv, end);
} else if ((LONG_MIN == strtol_in || LONG_MAX == strtol_in) && ERANGE == errno) {
LOG_FATAL("%s out of range of type long", str_to_conv);
} else if (strtol_in > INT_MAX) {
LOG_FATAL("%ld greater than INT_MAX", strtol_in);
} else if (strtol_in < INT_MIN) {
LOG_FATAL("%ld less than INT_MIN", strtol_in);
} else {
*store_into = (int) strtol_in;
return EXIT_SUCCESS;
}

return EXIT_FAILURE;
}

static void handle_arg_frequency(arg_conf* conf, long frequency) {
// calculate delay from hertz input
LOG_DEBUG("Frequency [Hz] input specified: %ld.", frequency);

if (frequency > MAX_HZ) {
LOG_ERROR("Provided frequency %ld is higher than allowed frequency %ld. Used Fallback: %ld", frequency, MAX_HZ, MAX_HZ);
frequency = MAX_HZ;
}
else if (frequency <= 0) {
LOG_ERROR("Provided frequency %ld is lower or equal to 0. Used Fallback: %ld", frequency, MAX_HZ);
frequency = MAX_HZ;
}

long delay = MAX_HZ / frequency;
if (delay > INT_MAX)
LOG_FATAL("Delay is out of bounds: %d > %d", delay, INT_MAX);

conf->us_delay = (int) (delay);
LOG_INFO("Delay set to %d us.", conf->us_delay);
static void handle_arg_frequency(arg_conf *conf, long frequency) {
// calculate delay from hertz input
LOG_DEBUG("Frequency [Hz] input specified: %ld.", frequency);

if (frequency > MAX_HZ) {
LOG_ERROR("Provided frequency %ld is higher than allowed frequency %ld. Used Fallback: %ld", frequency,
MAX_HZ, MAX_HZ);
frequency = MAX_HZ;
} else if (frequency <= 0) {
LOG_ERROR("Provided frequency %ld is lower or equal to 0. Used Fallback: %ld", frequency, MAX_HZ);
frequency = MAX_HZ;
}

long delay = MAX_HZ / frequency;
if (delay > INT_MAX)
LOG_FATAL("Delay is out of bounds: %d > %d", delay, INT_MAX);

conf->us_delay = (int) (delay);
LOG_INFO("Delay set to %d us.", conf->us_delay);
}

/******************************************************
*** EXPOSED METHODS ***
******************************************************/

arg_conf* cli_config_default(void) {
arg_conf* conf = malloc(sizeof(arg_conf));
arg_conf *cli_config_default(void) {
arg_conf *conf = malloc(sizeof(arg_conf));

conf->debug = FATAL;
conf->us_delay = 0;
conf->rom_path = "";
conf->debug = FATAL;
conf->us_delay = 0;
conf->rom_path = "";

return conf;
return conf;
}

void cli_config_destroy(arg_conf *conf) {
free(conf);
free(conf);
}

int cli_config_handle(arg_conf* const conf, int argc, char **argv) {
int c;

if (argc < 2) {
LOG_FATAL("No ROM path specified!");
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}

// parse all options first
int strtol_in;
while ((c = getopt(argc, argv, "d:f:")) != -1) {
switch (c) {
case 'd':
if (safe_strtol(optarg, &strtol_in))
return EXIT_FAILURE;

conf->debug = strtol_in;
log_set_lvl(conf);
break;
case 'f':
if (safe_strtol(optarg, &strtol_in))
return EXIT_FAILURE;

handle_arg_frequency(conf, strtol_in);
break;
default:
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}
}

// parse the remaining options

if (argc - optind > 1) {
LOG_FATAL("You provided too many arguments!");
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}

if (optind >= argc) {
LOG_FATAL("No ROM path specified!");
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}

// path to rom is the only remaining argument
conf->rom_path = argv[optind++];
LOG_DEBUG("Path to ROM: %s", conf->rom_path);

return EXIT_SUCCESS;
int cli_config_handle(arg_conf *const conf, int argc, char **argv) {
int c;

if (argc < 2) {
LOG_FATAL("No ROM path specified!");
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}

// parse all options first
int strtol_in;
while ((c = getopt(argc, argv, "d:f:")) != -1) {
switch (c) {
case 'd':
if (safe_strtol(optarg, &strtol_in))
return EXIT_FAILURE;

conf->debug = strtol_in;
log_set_lvl(conf);
break;
case 'f':
if (safe_strtol(optarg, &strtol_in))
return EXIT_FAILURE;

handle_arg_frequency(conf, strtol_in);
break;
default:
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}
}

// parse the remaining options

if (argc - optind > 1) {
LOG_FATAL("You provided too many arguments!");
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}

if (optind >= argc) {
LOG_FATAL("No ROM path specified!");
fprintf(stderr, "%s\n", usage_str);
return EXIT_FAILURE;
}

// path to rom is the only remaining argument
conf->rom_path = argv[optind++];
LOG_DEBUG("Path to ROM: %s", conf->rom_path);

return EXIT_SUCCESS;
}
Loading