mirror of
https://github.com/tailix/libkernaux.git
synced 2024-11-27 11:14:42 -05:00
Fix printf hack in the bindings (#152)
This commit is contained in:
parent
f46438fa85
commit
a1262ac64d
13 changed files with 64 additions and 43 deletions
|
@ -46,7 +46,7 @@ ruby_freebsd_task:
|
||||||
CPATH: '/usr/local/include'
|
CPATH: '/usr/local/include'
|
||||||
LIBRARY_PATH: '/usr/local/lib'
|
LIBRARY_PATH: '/usr/local/lib'
|
||||||
dependencies_script:
|
dependencies_script:
|
||||||
- pkg install --yes autoconf automake git libtool wget
|
- pkg install --yes autoconf automake cppcheck git libtool wget
|
||||||
dependencies_ruby_script:
|
dependencies_ruby_script:
|
||||||
- wget https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.3.tar.gz
|
- wget https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.3.tar.gz
|
||||||
- tar -xzf ruby-3.0.3.tar.gz
|
- tar -xzf ruby-3.0.3.tar.gz
|
||||||
|
|
3
.github/workflows/mruby.yml
vendored
3
.github/workflows/mruby.yml
vendored
|
@ -46,6 +46,3 @@ jobs:
|
||||||
- working-directory: bindings/mruby
|
- working-directory: bindings/mruby
|
||||||
name: lint
|
name: lint
|
||||||
run: rake
|
run: rake
|
||||||
- working-directory: bindings/mruby
|
|
||||||
name: cppcheck
|
|
||||||
run: cppcheck --quiet --error-exitcode=1 --std=c99 --enable=warning,style,performance,portability .
|
|
||||||
|
|
3
.github/workflows/ruby.yml
vendored
3
.github/workflows/ruby.yml
vendored
|
@ -44,6 +44,3 @@ jobs:
|
||||||
- working-directory: bindings/ruby
|
- working-directory: bindings/ruby
|
||||||
name: test & lint
|
name: test & lint
|
||||||
run: SKIP_COVERAGE='${{matrix.packages.skip_coverage}}' rake
|
run: SKIP_COVERAGE='${{matrix.packages.skip_coverage}}' rake
|
||||||
- working-directory: bindings/ruby
|
|
||||||
name: cppcheck
|
|
||||||
run: cppcheck --quiet --error-exitcode=1 --std=c99 --enable=warning,style,performance,portability .
|
|
||||||
|
|
|
@ -202,6 +202,12 @@ make
|
||||||
|
|
||||||
You can test with `make check`.
|
You can test with `make check`.
|
||||||
|
|
||||||
|
#### See also
|
||||||
|
|
||||||
|
* [GitHub Actions](/.github/) for **GNU/Linux** build environment
|
||||||
|
* [Cirrus CI](/.cirrus.yml) for **FreeBSD** build environment
|
||||||
|
* [sourcehut CI](/.openbsd.yml) for **OpenBSD** build environment
|
||||||
|
|
||||||
### Cross
|
### Cross
|
||||||
|
|
||||||
Create configuration script with `./autogen.sh` (if present).
|
Create configuration script with `./autogen.sh` (if present).
|
||||||
|
|
|
@ -4,7 +4,7 @@ desc 'Run default checks'
|
||||||
task default: :lint
|
task default: :lint
|
||||||
|
|
||||||
desc 'Run code analysis tools'
|
desc 'Run code analysis tools'
|
||||||
task lint: :rubocop
|
task lint: %i[rubocop cppcheck]
|
||||||
|
|
||||||
desc 'Fix code style (rubocop --auto-correct)'
|
desc 'Fix code style (rubocop --auto-correct)'
|
||||||
task fix: 'rubocop:auto_correct'
|
task fix: 'rubocop:auto_correct'
|
||||||
|
@ -15,3 +15,15 @@ begin
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc 'Run cppcheck'
|
||||||
|
task :cppcheck do
|
||||||
|
sh(
|
||||||
|
'cppcheck',
|
||||||
|
'--quiet',
|
||||||
|
'--error-exitcode=1',
|
||||||
|
'--std=c99',
|
||||||
|
'--enable=warning,style,performance,portability',
|
||||||
|
__dir__,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <mruby/presym.h>
|
#include <mruby/presym.h>
|
||||||
#include <mruby/string.h>
|
#include <mruby/string.h>
|
||||||
#include <mruby/variable.h>
|
#include <mruby/variable.h>
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <mruby/array.h>
|
#include <mruby/array.h>
|
||||||
#include <mruby/presym.h>
|
#include <mruby/presym.h>
|
||||||
#include <mruby/string.h>
|
#include <mruby/string.h>
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
#include <kernaux.h>
|
#include <kernaux.h>
|
||||||
#include <mruby.h>
|
#include <mruby.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void current_mrb_start(mrb_state *mrb);
|
void current_mrb_start(mrb_state *mrb);
|
||||||
void current_mrb_finish(mrb_state *mrb);
|
void current_mrb_finish(mrb_state *mrb);
|
||||||
mrb_state *current_mrb_get();
|
mrb_state *current_mrb_get();
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <mruby/numeric.h>
|
#include <mruby/numeric.h>
|
||||||
#include <mruby/presym.h>
|
#include <mruby/presym.h>
|
||||||
#include <mruby/string.h>
|
#include <mruby/string.h>
|
||||||
|
|
|
@ -29,8 +29,7 @@ void init_printf(mrb_state *const mrb)
|
||||||
|
|
||||||
mrb_value rb_KernAux_sprintf(mrb_state *const mrb, mrb_value self)
|
mrb_value rb_KernAux_sprintf(mrb_state *const mrb, mrb_value self)
|
||||||
{
|
{
|
||||||
// FIXME: const
|
const char *format;
|
||||||
char *format;
|
|
||||||
mrb_value *args;
|
mrb_value *args;
|
||||||
mrb_int argc;
|
mrb_int argc;
|
||||||
mrb_get_args(mrb, "z*", &format, &args, &argc);
|
mrb_get_args(mrb, "z*", &format, &args, &argc);
|
||||||
|
@ -45,12 +44,9 @@ mrb_value rb_KernAux_sprintf(mrb_state *const mrb, mrb_value self)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: unnecessary
|
|
||||||
const char *const old_format = format;
|
|
||||||
++format;
|
++format;
|
||||||
struct KernAux_PrintfFmt_Spec spec =
|
struct KernAux_PrintfFmt_Spec spec =
|
||||||
// FIXME: no type cast
|
KernAux_PrintfFmt_Spec_create_out(&format);
|
||||||
KernAux_PrintfFmt_Spec_create_out((const char**)&format);
|
|
||||||
|
|
||||||
if (spec.set_width) {
|
if (spec.set_width) {
|
||||||
TAKE_ARG;
|
TAKE_ARG;
|
||||||
|
@ -87,14 +83,16 @@ mrb_value rb_KernAux_sprintf(mrb_state *const mrb, mrb_value self)
|
||||||
DynArg_use_str(&dynarg, RSTRING_CSTR(mrb, arg_rb));
|
DynArg_use_str(&dynarg, RSTRING_CSTR(mrb, arg_rb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1 additional byte for the '%' character.
|
||||||
|
// 1 additional byte for the terminating '\0' character.
|
||||||
|
char old_format[2 + spec.format_limit - spec.format_start];
|
||||||
|
memset(old_format, '\0', sizeof(old_format));
|
||||||
|
old_format[0] = '%';
|
||||||
|
strncpy(&old_format[1], spec.format_start, sizeof(old_format) - 2);
|
||||||
|
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
int slen;
|
int slen;
|
||||||
|
|
||||||
// FIXME: it's a hack
|
|
||||||
// TODO: convert printf format spec to string
|
|
||||||
const char tmp = *format;
|
|
||||||
*format = '\0';
|
|
||||||
|
|
||||||
if (spec.set_width) {
|
if (spec.set_width) {
|
||||||
if (spec.set_precision) {
|
if (spec.set_precision) {
|
||||||
if (dynarg.use_dbl) {
|
if (dynarg.use_dbl) {
|
||||||
|
@ -133,7 +131,6 @@ mrb_value rb_KernAux_sprintf(mrb_state *const mrb, mrb_value self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*format = tmp;
|
|
||||||
mrb_str_cat(mrb, result, buffer, slen);
|
mrb_str_cat(mrb, result, buffer, slen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,13 @@ CLEAN << 'doc'
|
||||||
CLEAN << 'spec/examples.txt'
|
CLEAN << 'spec/examples.txt'
|
||||||
|
|
||||||
desc 'Run default checks'
|
desc 'Run default checks'
|
||||||
task default: %i[test lint yard:cov]
|
task default: %i[test lint]
|
||||||
|
|
||||||
desc 'Run tests'
|
desc 'Run tests'
|
||||||
task test: :spec
|
task test: :spec
|
||||||
|
|
||||||
desc 'Run code analysis tools'
|
desc 'Run code analysis tools'
|
||||||
task lint: :rubocop
|
task lint: %i[rubocop cppcheck yard:cov]
|
||||||
|
|
||||||
desc 'Fix code style (rubocop --auto-correct)'
|
desc 'Fix code style (rubocop --auto-correct)'
|
||||||
task fix: 'rubocop:auto_correct'
|
task fix: 'rubocop:auto_correct'
|
||||||
|
@ -66,6 +66,18 @@ task :console do
|
||||||
sh 'bundle', 'exec', File.expand_path(File.join('bin', 'console'), __dir__)
|
sh 'bundle', 'exec', File.expand_path(File.join('bin', 'console'), __dir__)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc 'Run cppcheck'
|
||||||
|
task :cppcheck do
|
||||||
|
sh(
|
||||||
|
'cppcheck',
|
||||||
|
'--quiet',
|
||||||
|
'--error-exitcode=1',
|
||||||
|
'--std=c99',
|
||||||
|
'--enable=warning,style,performance,portability',
|
||||||
|
__dir__,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
namespace :yard do
|
namespace :yard do
|
||||||
desc 'Measure documentation coverage'
|
desc 'Measure documentation coverage'
|
||||||
task :cov do
|
task :cov do
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
#include <kernaux.h>
|
#include <kernaux.h>
|
||||||
#include <ruby.h>
|
#include <ruby.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
extern ID rb_intern_call;
|
extern ID rb_intern_call;
|
||||||
extern ID rb_intern_freeze;
|
extern ID rb_intern_freeze;
|
||||||
extern ID rb_intern_LESS;
|
extern ID rb_intern_LESS;
|
||||||
|
|
|
@ -31,8 +31,7 @@ VALUE rb_KernAux_sprintf(const int argc, VALUE *const argv, VALUE self)
|
||||||
{
|
{
|
||||||
if (argc == 0) rb_raise(rb_eArgError, "too few arguments");
|
if (argc == 0) rb_raise(rb_eArgError, "too few arguments");
|
||||||
|
|
||||||
// FIXME: const
|
const char *format = StringValueCStr(argv[0]);
|
||||||
char *format = StringValueCStr(argv[0]);
|
|
||||||
int arg_index = 1;
|
int arg_index = 1;
|
||||||
VALUE result = rb_str_new_literal("");
|
VALUE result = rb_str_new_literal("");
|
||||||
|
|
||||||
|
@ -43,12 +42,9 @@ VALUE rb_KernAux_sprintf(const int argc, VALUE *const argv, VALUE self)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: unnecessary
|
|
||||||
const char *const old_format = format;
|
|
||||||
++format;
|
++format;
|
||||||
struct KernAux_PrintfFmt_Spec spec =
|
struct KernAux_PrintfFmt_Spec spec =
|
||||||
// FIXME: no type cast
|
KernAux_PrintfFmt_Spec_create_out(&format);
|
||||||
KernAux_PrintfFmt_Spec_create_out((const char**)&format);
|
|
||||||
|
|
||||||
if (spec.set_width) {
|
if (spec.set_width) {
|
||||||
TAKE_ARG;
|
TAKE_ARG;
|
||||||
|
@ -82,14 +78,16 @@ VALUE rb_KernAux_sprintf(const int argc, VALUE *const argv, VALUE self)
|
||||||
DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
|
DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1 additional byte for the '%' character.
|
||||||
|
// 1 additional byte for the terminating '\0' character.
|
||||||
|
char old_format[2 + spec.format_limit - spec.format_start];
|
||||||
|
memset(old_format, '\0', sizeof(old_format));
|
||||||
|
old_format[0] = '%';
|
||||||
|
strncpy(&old_format[1], spec.format_start, sizeof(old_format) - 2);
|
||||||
|
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
int slen;
|
int slen;
|
||||||
|
|
||||||
// FIXME: it's a hack
|
|
||||||
// TODO: convert printf format spec to string
|
|
||||||
const char tmp = *format;
|
|
||||||
*format = '\0';
|
|
||||||
|
|
||||||
if (spec.set_width) {
|
if (spec.set_width) {
|
||||||
if (spec.set_precision) {
|
if (spec.set_precision) {
|
||||||
if (dynarg.use_dbl) {
|
if (dynarg.use_dbl) {
|
||||||
|
@ -128,7 +126,6 @@ VALUE rb_KernAux_sprintf(const int argc, VALUE *const argv, VALUE self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*format = tmp;
|
|
||||||
rb_str_cat(result, buffer, slen);
|
rb_str_cat(result, buffer, slen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue