mirror of
https://github.com/tailix/libkernaux.git
synced 2024-10-30 11:54:01 -04:00
Ruby: move dynamic argument handling to separate module
This commit is contained in:
parent
bac9b21145
commit
bdc80917b4
3 changed files with 94 additions and 20 deletions
45
pkgs/ruby/ext/default/dynarg.c
Normal file
45
pkgs/ruby/ext/default/dynarg.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "dynarg.h"
|
||||
|
||||
struct DynArg DynArg_create()
|
||||
{
|
||||
struct DynArg dynarg;
|
||||
DynArg_init(&dynarg);
|
||||
return dynarg;
|
||||
}
|
||||
|
||||
void DynArg_init(struct DynArg *const dynarg)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->dbl = 0.0;
|
||||
dynarg->arg.str = "";
|
||||
}
|
||||
|
||||
void DynArg_use_char(struct DynArg *const dynarg, const char chr)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.chr = chr;
|
||||
}
|
||||
|
||||
void DynArg_use_double(struct DynArg *const dynarg, const double dbl)
|
||||
{
|
||||
dynarg->use_dbl = true;
|
||||
dynarg->dbl = dbl;
|
||||
}
|
||||
|
||||
void DynArg_use_long_long(struct DynArg *const dynarg, const long long ll)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.ll = ll;
|
||||
}
|
||||
|
||||
void DynArg_use_str(struct DynArg *const dynarg, const char *const str)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.str = str;
|
||||
}
|
||||
|
||||
void DynArg_use_unsigned_long_long(struct DynArg *const dynarg, const unsigned long long ull)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.ull = ull;
|
||||
}
|
35
pkgs/ruby/ext/default/dynarg.h
Normal file
35
pkgs/ruby/ext/default/dynarg.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef INCLUDED_DYNARG
|
||||
#define INCLUDED_DYNARG
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct DynArg {
|
||||
bool use_dbl;
|
||||
double dbl;
|
||||
// TODO: check if this will work on different endianness.
|
||||
union {
|
||||
char chr;
|
||||
long long ll;
|
||||
const char *str;
|
||||
unsigned long long ull;
|
||||
} __attribute__((packed)) arg;
|
||||
};
|
||||
|
||||
struct DynArg DynArg_create();
|
||||
void DynArg_init(struct DynArg *dynarg);
|
||||
|
||||
void DynArg_use_char(struct DynArg *dynarg, char chr);
|
||||
void DynArg_use_double(struct DynArg *dynarg, double dbl);
|
||||
void DynArg_use_long_long(struct DynArg *dynarg, long long ll);
|
||||
void DynArg_use_str(struct DynArg *dynarg, const char *str);
|
||||
void DynArg_use_unsigned_long_long(struct DynArg *dynarg, unsigned long long ull);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,6 +1,8 @@
|
|||
#include <kernaux.h>
|
||||
#include <ruby.h>
|
||||
|
||||
#include "dynarg.h"
|
||||
|
||||
#ifdef HAVE_KERNAUX_SNPRINTF
|
||||
|
||||
static VALUE rb_KernAux_snprintf1(int argc, const VALUE *argv, VALUE self);
|
||||
|
@ -89,37 +91,29 @@ VALUE rb_KernAux_snprintf1(
|
|||
int width = 0;
|
||||
if (has_width && argc > 2) width = NUM2INT(argv_rb[2]);
|
||||
|
||||
bool use_dbl = false;
|
||||
double dbl;
|
||||
union {
|
||||
const char *str;
|
||||
long long ll;
|
||||
unsigned long long ull;
|
||||
char chr;
|
||||
} __attribute__((packed)) arg = { .str = "" };
|
||||
struct DynArg dynarg = DynArg_create();
|
||||
|
||||
if (argc == (has_width ? 4 : 3)) {
|
||||
VALUE arg_rb = argv_rb[has_width ? 3 : 2];
|
||||
|
||||
if (c == 'd' || c == 'i') {
|
||||
RB_INTEGER_TYPE_P(arg_rb);
|
||||
arg.ll = NUM2LL(arg_rb);
|
||||
DynArg_use_long_long(&dynarg, NUM2LL(arg_rb));
|
||||
} else if (c == 'u' || c == 'x' || c == 'X' || c == 'o' || c == 'b') {
|
||||
RB_INTEGER_TYPE_P(arg_rb);
|
||||
arg.ull = NUM2ULL(arg_rb);
|
||||
DynArg_use_unsigned_long_long(&dynarg, NUM2ULL(arg_rb));
|
||||
} else if (c == 'f' || c == 'F' ||
|
||||
c == 'e' || c == 'E' ||
|
||||
c == 'g' || c == 'G')
|
||||
{
|
||||
RB_FLOAT_TYPE_P(arg_rb);
|
||||
use_dbl = true;
|
||||
dbl = NUM2DBL(arg_rb);
|
||||
DynArg_use_double(&dynarg, NUM2DBL(arg_rb));
|
||||
} else if (c == 'c') {
|
||||
Check_Type(arg_rb, T_STRING);
|
||||
arg.chr = *StringValuePtr(arg_rb);
|
||||
DynArg_use_char(&dynarg, *StringValuePtr(arg_rb));
|
||||
} else if (c == 's') {
|
||||
Check_Type(arg_rb, T_STRING);
|
||||
arg.str = StringValueCStr(arg_rb);
|
||||
DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,13 +122,13 @@ VALUE rb_KernAux_snprintf1(
|
|||
|
||||
int slen;
|
||||
if (has_width) {
|
||||
slen = use_dbl
|
||||
? kernaux_snprintf(str, size, format, width, dbl)
|
||||
: kernaux_snprintf(str, size, format, width, arg);
|
||||
slen = dynarg.use_dbl
|
||||
? kernaux_snprintf(str, size, format, width, dynarg.dbl)
|
||||
: kernaux_snprintf(str, size, format, width, dynarg.arg);
|
||||
} else {
|
||||
slen = use_dbl
|
||||
? kernaux_snprintf(str, size, format, dbl)
|
||||
: kernaux_snprintf(str, size, format, arg);
|
||||
slen = dynarg.use_dbl
|
||||
? kernaux_snprintf(str, size, format, dynarg.dbl)
|
||||
: kernaux_snprintf(str, size, format, dynarg.arg);
|
||||
}
|
||||
|
||||
const VALUE output_rb =
|
||||
|
|
Loading…
Reference in a new issue