Remove old mruby extensions
This commit is contained in:
parent
c9af091331
commit
84cecb90f2
|
@ -65,9 +65,6 @@ ScriptBinding scriptBindingImpl =
|
||||||
|
|
||||||
ScriptBinding *scriptBinding = &scriptBindingImpl;
|
ScriptBinding *scriptBinding = &scriptBindingImpl;
|
||||||
|
|
||||||
|
|
||||||
void fileBindingInit(mrb_state *);
|
|
||||||
void timeBindingInit(mrb_state *);
|
|
||||||
void kernelBindingInit(mrb_state *);
|
void kernelBindingInit(mrb_state *);
|
||||||
|
|
||||||
void tableBindingInit(mrb_state *);
|
void tableBindingInit(mrb_state *);
|
||||||
|
@ -89,8 +86,6 @@ static void mrbBindingInit(mrb_state *mrb)
|
||||||
int arena = mrb_gc_arena_save(mrb);
|
int arena = mrb_gc_arena_save(mrb);
|
||||||
|
|
||||||
/* Init standard classes */
|
/* Init standard classes */
|
||||||
fileBindingInit(mrb);
|
|
||||||
timeBindingInit(mrb);
|
|
||||||
kernelBindingInit(mrb);
|
kernelBindingInit(mrb);
|
||||||
|
|
||||||
/* Init RGSS classes */
|
/* Init RGSS classes */
|
||||||
|
|
|
@ -1,605 +0,0 @@
|
||||||
/*
|
|
||||||
** file.cpp
|
|
||||||
**
|
|
||||||
** This file is part of mkxp.
|
|
||||||
**
|
|
||||||
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
|
|
||||||
**
|
|
||||||
** mkxp is free software: you can redistribute it and/or modify
|
|
||||||
** it under the terms of the GNU General Public License as published by
|
|
||||||
** the Free Software Foundation, either version 2 of the License, or
|
|
||||||
** (at your option) any later version.
|
|
||||||
**
|
|
||||||
** mkxp is distributed in the hope that it will be useful,
|
|
||||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
** GNU General Public License for more details.
|
|
||||||
**
|
|
||||||
** You should have received a copy of the GNU General Public License
|
|
||||||
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "file.h"
|
|
||||||
|
|
||||||
#include "debugwriter.h"
|
|
||||||
|
|
||||||
#include "../binding-util.h"
|
|
||||||
#include <mruby/string.h>
|
|
||||||
#include <mruby/array.h>
|
|
||||||
#include <mruby/class.h>
|
|
||||||
|
|
||||||
#include <SDL_rwops.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
extern mrb_value timeFromSecondsInt(mrb_state *mrb, time_t seconds);
|
|
||||||
|
|
||||||
static void
|
|
||||||
checkValid(mrb_state *mrb, FileImpl *p, int rwMode = FileImpl::ReadWrite)
|
|
||||||
{
|
|
||||||
MrbData *data = getMrbData(mrb);
|
|
||||||
|
|
||||||
if (p->closed)
|
|
||||||
mrb_raise(mrb, data->exc[IO], "closed stream");
|
|
||||||
|
|
||||||
if (!(p->mode & rwMode))
|
|
||||||
{
|
|
||||||
const char *errorMsg = 0;
|
|
||||||
|
|
||||||
switch (rwMode)
|
|
||||||
{
|
|
||||||
case FileImpl::Read :
|
|
||||||
errorMsg = "not openend for reading"; break;
|
|
||||||
case FileImpl::Write :
|
|
||||||
errorMsg = "not openend for writing"; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
mrb_raise(mrb, data->exc[IO], errorMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern const mrb_data_type FileType =
|
|
||||||
{
|
|
||||||
"File",
|
|
||||||
freeInstance<FileImpl>
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
getOpenMode(const char *mode)
|
|
||||||
{
|
|
||||||
#define STR_CASE(cs, ret) else if (!strcmp(mode, cs)) { return FileImpl:: ret; }
|
|
||||||
|
|
||||||
if (!strcmp(mode, "r"))
|
|
||||||
return FileImpl::Read;
|
|
||||||
STR_CASE("rb", Read)
|
|
||||||
STR_CASE("r+", ReadWrite)
|
|
||||||
STR_CASE("w", Write)
|
|
||||||
STR_CASE("wb", Write)
|
|
||||||
STR_CASE("w+", ReadWrite)
|
|
||||||
STR_CASE("rw", ReadWrite)
|
|
||||||
STR_CASE("a", Write)
|
|
||||||
STR_CASE("a+", ReadWrite)
|
|
||||||
|
|
||||||
Debug() << "getOpenMode failed for:" << mode;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleErrno(mrb_state *mrb)
|
|
||||||
{
|
|
||||||
MrbException exc;
|
|
||||||
const char *msg;
|
|
||||||
mrb_value arg1;
|
|
||||||
|
|
||||||
#define ENO(_eno, _msg) \
|
|
||||||
case _eno: { exc = Errno##_eno; msg = _msg; break; }
|
|
||||||
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
ENO(EACCES, "");
|
|
||||||
ENO(EBADF, "");
|
|
||||||
ENO(EEXIST, "");
|
|
||||||
ENO(EINVAL, "");
|
|
||||||
ENO(EMFILE, "");
|
|
||||||
ENO(ENOMEM, "");
|
|
||||||
ENO(ERANGE, "");
|
|
||||||
default:
|
|
||||||
exc = IO; msg = "Unknown Errno: %S";
|
|
||||||
arg1 = mrb_any_to_s(mrb, mrb_fixnum_value(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef ENO
|
|
||||||
|
|
||||||
mrb_raisef(mrb, getMrbData(mrb)->exc[exc], msg, arg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GUARD_ERRNO(stmnt) \
|
|
||||||
{ \
|
|
||||||
errno = 0; \
|
|
||||||
{ stmnt } \
|
|
||||||
if (errno != 0) \
|
|
||||||
handleErrno(mrb); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char *
|
|
||||||
findLastDot(char *str)
|
|
||||||
{
|
|
||||||
char *find = 0;
|
|
||||||
char *ptr = str;
|
|
||||||
|
|
||||||
/* Dot in front is not considered */
|
|
||||||
if (*ptr == '.')
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
for (; *ptr; ++ptr)
|
|
||||||
{
|
|
||||||
/* Dot in dirpath is not considered */
|
|
||||||
if (*ptr == '/')
|
|
||||||
{
|
|
||||||
ptr++;
|
|
||||||
if (*ptr == '.')
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*ptr == '.')
|
|
||||||
find = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return find;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* File class methods */
|
|
||||||
MRB_FUNCTION(fileBasename)
|
|
||||||
{
|
|
||||||
mrb_value filename;
|
|
||||||
const char *suffix = 0;
|
|
||||||
|
|
||||||
mrb_get_args(mrb, "S|z", &filename, &suffix);
|
|
||||||
|
|
||||||
char *_filename = RSTRING_PTR(filename);
|
|
||||||
char *base = basename(_filename);
|
|
||||||
|
|
||||||
char *ext = 0;
|
|
||||||
|
|
||||||
if (suffix)
|
|
||||||
{
|
|
||||||
ext = findLastDot(base);
|
|
||||||
if (ext && !strcmp(ext, suffix))
|
|
||||||
*ext = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
mrb_value str = mrb_str_new_cstr(mrb, base);
|
|
||||||
|
|
||||||
/* Restore param string */
|
|
||||||
if (ext)
|
|
||||||
*ext = '.';
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileDelete)
|
|
||||||
{
|
|
||||||
mrb_int argc;
|
|
||||||
mrb_value *argv;
|
|
||||||
|
|
||||||
mrb_get_args(mrb, "*", &argv, &argc);
|
|
||||||
|
|
||||||
for (int i = 0; i < argc; ++i)
|
|
||||||
{
|
|
||||||
mrb_value &v = argv[i];
|
|
||||||
|
|
||||||
if (!mrb_string_p(v))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *filename = RSTRING_PTR(v);
|
|
||||||
GUARD_ERRNO( unlink(filename); )
|
|
||||||
}
|
|
||||||
|
|
||||||
return mrb_nil_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileDirname)
|
|
||||||
{
|
|
||||||
mrb_value filename;
|
|
||||||
mrb_get_args(mrb, "S", &filename);
|
|
||||||
|
|
||||||
char *_filename = RSTRING_PTR(filename);
|
|
||||||
char *dir = dirname(_filename);
|
|
||||||
|
|
||||||
return mrb_str_new_cstr(mrb, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileExpandPath)
|
|
||||||
{
|
|
||||||
const char *path;
|
|
||||||
const char *defDir = 0;
|
|
||||||
|
|
||||||
mrb_get_args(mrb, "z|z", &path, &defDir);
|
|
||||||
|
|
||||||
// FIXME No idea how to integrate 'default_dir' right now
|
|
||||||
if (defDir)
|
|
||||||
Debug() << "FIXME: File.expand_path: default_dir not implemented";
|
|
||||||
|
|
||||||
char buffer[PATH_MAX];
|
|
||||||
char *unused = realpath(path, buffer);
|
|
||||||
(void) unused;
|
|
||||||
|
|
||||||
return mrb_str_new_cstr(mrb, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileExtname)
|
|
||||||
{
|
|
||||||
mrb_value filename;
|
|
||||||
mrb_get_args(mrb, "S", &filename);
|
|
||||||
|
|
||||||
char *ext = findLastDot(RSTRING_PTR(filename));
|
|
||||||
|
|
||||||
return mrb_str_new_cstr(mrb, ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileOpen)
|
|
||||||
{
|
|
||||||
mrb_value path;
|
|
||||||
const char *mode = "r";
|
|
||||||
mrb_value block = mrb_nil_value();
|
|
||||||
|
|
||||||
mrb_get_args(mrb, "S|z&", &path, &mode, &block);
|
|
||||||
|
|
||||||
/* We manually check errno because we're supplying the
|
|
||||||
* filename on ENOENT */
|
|
||||||
errno = 0;
|
|
||||||
FILE *f = fopen(RSTRING_PTR(path), mode);
|
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
if (errno == ENOENT)
|
|
||||||
mrb_raisef(mrb, getMrbData(mrb)->exc[ErrnoENOENT],
|
|
||||||
"No such file or directory - %S", path);
|
|
||||||
else
|
|
||||||
handleErrno(mrb);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_RWops *ops = SDL_RWFromFP(f, SDL_TRUE);
|
|
||||||
FileImpl *p = new FileImpl(ops, getOpenMode(mode));
|
|
||||||
|
|
||||||
mrb_value obj = wrapObject(mrb, p, FileType);
|
|
||||||
setProperty(mrb, obj, CSpath, path);
|
|
||||||
|
|
||||||
if (mrb_type(block) == MRB_TT_PROC)
|
|
||||||
{
|
|
||||||
// FIXME inquire how GC behaviour works here for obj
|
|
||||||
mrb_value ret = mrb_yield(mrb, block, obj);
|
|
||||||
p->close();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileRename)
|
|
||||||
{
|
|
||||||
const char *from, *to;
|
|
||||||
mrb_get_args(mrb, "zz", &from, &to);
|
|
||||||
|
|
||||||
GUARD_ERRNO( rename(from, to); )
|
|
||||||
|
|
||||||
return mrb_fixnum_value(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MRB_FUNCTION(mrbNoop)
|
|
||||||
{
|
|
||||||
MRB_FUN_UNUSED_PARAM;
|
|
||||||
|
|
||||||
return mrb_nil_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* File instance methods */
|
|
||||||
MRB_METHOD(fileClose)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p);
|
|
||||||
|
|
||||||
GUARD_ERRNO( p->close(); )
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
readLine(FILE *f, std::vector<char> &buffer)
|
|
||||||
{
|
|
||||||
buffer.clear();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (feof(f))
|
|
||||||
break;
|
|
||||||
|
|
||||||
int c = fgetc(f);
|
|
||||||
|
|
||||||
if (c == '\n' || c == EOF)
|
|
||||||
break;
|
|
||||||
|
|
||||||
buffer.push_back(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileEachLine)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p, FileImpl::Read);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
mrb_value block;
|
|
||||||
mrb_get_args(mrb, "&", &block);
|
|
||||||
|
|
||||||
(void) f;
|
|
||||||
std::vector<char> buffer;
|
|
||||||
|
|
||||||
mrb_value str = mrb_str_buf_new(mrb, 0);
|
|
||||||
|
|
||||||
while (feof(f) == 0)
|
|
||||||
{
|
|
||||||
GUARD_ERRNO( readLine(f, buffer); )
|
|
||||||
|
|
||||||
if (buffer.empty() && feof(f) != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
size_t lineLen = buffer.size();
|
|
||||||
mrb_str_resize(mrb, str, lineLen);
|
|
||||||
memcpy(RSTRING_PTR(str), &buffer[0], lineLen);
|
|
||||||
|
|
||||||
mrb_yield(mrb, block, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileEachByte)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p, FileImpl::Read);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
mrb_value block;
|
|
||||||
mrb_get_args(mrb, "&", &block);
|
|
||||||
|
|
||||||
GUARD_ERRNO(
|
|
||||||
while (feof(f) == 0)
|
|
||||||
{
|
|
||||||
mrb_int byte = fgetc(f);
|
|
||||||
|
|
||||||
if (byte == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
mrb_yield(mrb, block, mrb_fixnum_value(byte));
|
|
||||||
})
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileIsEof)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
bool isEof;
|
|
||||||
GUARD_ERRNO( isEof = feof(f) != 0; )
|
|
||||||
|
|
||||||
return mrb_bool_value(isEof);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileSetPos)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
mrb_int pos;
|
|
||||||
mrb_get_args(mrb, "i", &pos);
|
|
||||||
|
|
||||||
GUARD_ERRNO( fseek(f, pos, SEEK_SET); )
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileGetPos)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
long pos;
|
|
||||||
GUARD_ERRNO( pos = ftell(f); )
|
|
||||||
|
|
||||||
return mrb_fixnum_value(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileRead)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p, FileImpl::Read);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
long cur, size;
|
|
||||||
GUARD_ERRNO( cur = ftell(f); )
|
|
||||||
GUARD_ERRNO( fseek(f, 0, SEEK_END); )
|
|
||||||
GUARD_ERRNO( size = ftell(f); )
|
|
||||||
GUARD_ERRNO( fseek(f, cur, SEEK_SET); )
|
|
||||||
|
|
||||||
mrb_int length = size - cur;
|
|
||||||
mrb_get_args(mrb, "|i", &length);
|
|
||||||
|
|
||||||
mrb_value str = mrb_str_new(mrb, 0, 0);
|
|
||||||
mrb_str_resize(mrb, str, length);
|
|
||||||
|
|
||||||
GUARD_ERRNO( int unused = fread(RSTRING_PTR(str), 1, length, f); (void) unused; )
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME this function always splits on newline right now,
|
|
||||||
// to make rs fully work, I'll have to use some strrstr magic I guess
|
|
||||||
MRB_METHOD(fileReadLines)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p, FileImpl::Read);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
mrb_value arg;
|
|
||||||
int argc = mrb_get_args(mrb, "|o", &arg);
|
|
||||||
|
|
||||||
const char *rs = "\n"; (void) rs;
|
|
||||||
|
|
||||||
if (argc > 0)
|
|
||||||
{
|
|
||||||
Debug() << "FIXME: File.readlines: rs not implemented";
|
|
||||||
|
|
||||||
if (mrb_string_p(arg))
|
|
||||||
rs = RSTRING_PTR(arg);
|
|
||||||
else if (mrb_nil_p(arg))
|
|
||||||
rs = "\n";
|
|
||||||
else
|
|
||||||
mrb_raise(mrb, getMrbData(mrb)->exc[TypeError], "Expected string or nil"); // FIXME add "got <> instead" remark
|
|
||||||
}
|
|
||||||
|
|
||||||
mrb_value ary = mrb_ary_new(mrb);
|
|
||||||
std::vector<char> buffer;
|
|
||||||
|
|
||||||
while (feof(f) == 0)
|
|
||||||
{
|
|
||||||
GUARD_ERRNO( readLine(f, buffer); )
|
|
||||||
|
|
||||||
if (buffer.empty() && feof(f) != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
mrb_value str = mrb_str_new(mrb, &buffer[0], buffer.size());
|
|
||||||
mrb_ary_push(mrb, ary, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ary;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileWrite)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p, FileImpl::Write);
|
|
||||||
FILE *f = p->fp();
|
|
||||||
|
|
||||||
mrb_value str;
|
|
||||||
mrb_get_args(mrb, "S", &str);
|
|
||||||
|
|
||||||
size_t count;
|
|
||||||
GUARD_ERRNO( count = fwrite(RSTRING_PTR(str), 1, RSTRING_LEN(str), f); )
|
|
||||||
|
|
||||||
return mrb_fixnum_value(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileGetPath)
|
|
||||||
{
|
|
||||||
FileImpl *p = getPrivateData<FileImpl>(mrb, self);
|
|
||||||
checkValid(mrb, p);
|
|
||||||
|
|
||||||
return getProperty(mrb, self, CSpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
getFileStat(mrb_state *mrb, struct stat &fileStat)
|
|
||||||
{
|
|
||||||
const char *filename;
|
|
||||||
mrb_get_args(mrb, "z", &filename);
|
|
||||||
|
|
||||||
stat(filename, &fileStat);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(fileGetMtime)
|
|
||||||
{
|
|
||||||
mrb_value path = getProperty(mrb, self, CSpath);
|
|
||||||
|
|
||||||
struct stat fileStat;
|
|
||||||
stat(RSTRING_PTR(path), &fileStat);
|
|
||||||
|
|
||||||
return timeFromSecondsInt(mrb, fileStat.st_mtim.tv_sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FileTest module functions */
|
|
||||||
MRB_FUNCTION(fileTestDoesExist)
|
|
||||||
{
|
|
||||||
const char *filename;
|
|
||||||
mrb_get_args(mrb, "z", &filename);
|
|
||||||
|
|
||||||
int result = access(filename, F_OK);
|
|
||||||
|
|
||||||
return mrb_bool_value(result == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileTestIsFile)
|
|
||||||
{
|
|
||||||
struct stat fileStat;
|
|
||||||
getFileStat(mrb, fileStat);
|
|
||||||
|
|
||||||
return mrb_bool_value(S_ISREG(fileStat.st_mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileTestIsDirectory)
|
|
||||||
{
|
|
||||||
struct stat fileStat;
|
|
||||||
getFileStat(mrb, fileStat);
|
|
||||||
|
|
||||||
return mrb_bool_value(S_ISDIR(fileStat.st_mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(fileTestSize)
|
|
||||||
{
|
|
||||||
struct stat fileStat;
|
|
||||||
getFileStat(mrb, fileStat);
|
|
||||||
|
|
||||||
return mrb_fixnum_value(fileStat.st_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fileBindingInit(mrb_state *mrb)
|
|
||||||
{
|
|
||||||
mrb_define_method(mrb, mrb->kernel_module, "open", fileOpen, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1) | MRB_ARGS_BLOCK());
|
|
||||||
|
|
||||||
RClass *klass = defineClass(mrb, "IO");
|
|
||||||
klass = mrb_define_class(mrb, "File", klass);
|
|
||||||
|
|
||||||
mrb_define_class_method(mrb, klass, "basename", fileBasename, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
|
|
||||||
mrb_define_class_method(mrb, klass, "delete", fileDelete, MRB_ARGS_REQ(1) | MRB_ARGS_ANY());
|
|
||||||
mrb_define_class_method(mrb, klass, "dirname", fileDirname, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_class_method(mrb, klass, "expand_path", fileExpandPath, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
|
|
||||||
mrb_define_class_method(mrb, klass, "extname", fileExtname, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_class_method(mrb, klass, "open", fileOpen, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1) | MRB_ARGS_BLOCK());
|
|
||||||
mrb_define_class_method(mrb, klass, "rename", fileRename, MRB_ARGS_REQ(2));
|
|
||||||
|
|
||||||
/* IO */
|
|
||||||
mrb_define_method(mrb, klass, "binmode", mrbNoop, MRB_ARGS_NONE());
|
|
||||||
mrb_define_method(mrb, klass, "close", fileClose, MRB_ARGS_NONE());
|
|
||||||
mrb_define_method(mrb, klass, "each_line", fileEachLine, MRB_ARGS_BLOCK());
|
|
||||||
mrb_define_method(mrb, klass, "each_byte", fileEachByte, MRB_ARGS_BLOCK());
|
|
||||||
mrb_define_method(mrb, klass, "eof?", fileIsEof, MRB_ARGS_NONE());
|
|
||||||
mrb_define_method(mrb, klass, "pos", fileGetPos, MRB_ARGS_NONE());
|
|
||||||
mrb_define_method(mrb, klass, "pos=", fileSetPos, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_method(mrb, klass, "read", fileRead, MRB_ARGS_OPT(1));
|
|
||||||
mrb_define_method(mrb, klass, "readlines", fileReadLines, MRB_ARGS_OPT(1));
|
|
||||||
mrb_define_method(mrb, klass, "write", fileWrite, MRB_ARGS_REQ(1));
|
|
||||||
|
|
||||||
/* File */
|
|
||||||
mrb_define_method(mrb, klass, "mtime", fileGetMtime, MRB_ARGS_NONE());
|
|
||||||
mrb_define_method(mrb, klass, "path", fileGetPath, MRB_ARGS_NONE());
|
|
||||||
|
|
||||||
/* FileTest */
|
|
||||||
RClass *module = mrb_define_module(mrb, "MKXPFileTest");
|
|
||||||
mrb_define_module_function(mrb, module, "exist?", fileTestDoesExist, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_module_function(mrb, module, "directory?", fileTestIsDirectory, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_module_function(mrb, module, "file?", fileTestIsFile, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_module_function(mrb, module, "size", fileTestSize, MRB_ARGS_REQ(1));
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
** file.h
|
|
||||||
**
|
|
||||||
** This file is part of mkxp.
|
|
||||||
**
|
|
||||||
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
|
|
||||||
**
|
|
||||||
** mkxp is free software: you can redistribute it and/or modify
|
|
||||||
** it under the terms of the GNU General Public License as published by
|
|
||||||
** the Free Software Foundation, either version 2 of the License, or
|
|
||||||
** (at your option) any later version.
|
|
||||||
**
|
|
||||||
** mkxp is distributed in the hope that it will be useful,
|
|
||||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
** GNU General Public License for more details.
|
|
||||||
**
|
|
||||||
** You should have received a copy of the GNU General Public License
|
|
||||||
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BINDING_FILE_H
|
|
||||||
#define BINDING_FILE_H
|
|
||||||
|
|
||||||
#include "../binding-util.h"
|
|
||||||
|
|
||||||
#include <SDL_rwops.h>
|
|
||||||
|
|
||||||
struct FileImpl
|
|
||||||
{
|
|
||||||
SDL_RWops *ops;
|
|
||||||
bool closed;
|
|
||||||
|
|
||||||
enum OpenMode
|
|
||||||
{
|
|
||||||
Read = 1 << 0,
|
|
||||||
Write = 1 << 1,
|
|
||||||
ReadWrite = Read | Write
|
|
||||||
};
|
|
||||||
|
|
||||||
int mode;
|
|
||||||
|
|
||||||
FileImpl(SDL_RWops *ops, int mode)
|
|
||||||
: ops(ops),
|
|
||||||
closed(false),
|
|
||||||
mode(mode)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void close()
|
|
||||||
{
|
|
||||||
if (closed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDL_RWclose(ops);
|
|
||||||
closed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *fp()
|
|
||||||
{
|
|
||||||
return ops->hidden.stdio.fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
~FileImpl()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DECL_TYPE(File);
|
|
||||||
|
|
||||||
#endif // BINDING_FILE_H
|
|
|
@ -48,126 +48,6 @@ MRB_FUNCTION(kernelEval)
|
||||||
return mrb_load_nstring(mrb, exp, expLen);
|
return mrb_load_nstring(mrb, exp, expLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printP(mrb_state *mrb,
|
|
||||||
const char *conv, const char *sep)
|
|
||||||
{
|
|
||||||
mrb_int argc;
|
|
||||||
mrb_value *argv;
|
|
||||||
mrb_get_args(mrb, "*", &argv, &argc);
|
|
||||||
|
|
||||||
mrb_value buffer = mrb_str_buf_new(mrb, 128);
|
|
||||||
mrb_value arg;
|
|
||||||
|
|
||||||
for (int i = 0; i < argc; ++i)
|
|
||||||
{
|
|
||||||
arg = argv[i];
|
|
||||||
arg = mrb_funcall(mrb, arg, conv, 0);
|
|
||||||
|
|
||||||
mrb_str_buf_append(mrb, buffer, arg);
|
|
||||||
|
|
||||||
if (i < argc)
|
|
||||||
mrb_str_buf_cat(mrb, buffer, sep, strlen(sep));
|
|
||||||
}
|
|
||||||
|
|
||||||
shState->eThread().showMessageBox(RSTRING_PTR(buffer), SDL_MESSAGEBOX_INFORMATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(kernelP)
|
|
||||||
{
|
|
||||||
printP(mrb, "inspect", "\n");
|
|
||||||
|
|
||||||
return mrb_nil_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(kernelPrint)
|
|
||||||
{
|
|
||||||
printP(mrb, "to_s", "");
|
|
||||||
|
|
||||||
return mrb_nil_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME store this in kernel module
|
|
||||||
static int currentSeed = 1;
|
|
||||||
bool srandCalled = false;
|
|
||||||
|
|
||||||
static void
|
|
||||||
srandCurrentTime(int *currentSeed)
|
|
||||||
{
|
|
||||||
timeval tv;
|
|
||||||
gettimeofday(&tv, 0);
|
|
||||||
|
|
||||||
// FIXME could check how MRI does this
|
|
||||||
*currentSeed = tv.tv_sec * tv.tv_usec;
|
|
||||||
|
|
||||||
srand(*currentSeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(kernelRand)
|
|
||||||
{
|
|
||||||
if (!srandCalled)
|
|
||||||
{
|
|
||||||
srandCurrentTime(¤tSeed);
|
|
||||||
srandCalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
mrb_value arg;
|
|
||||||
|
|
||||||
mrb_get_args(mrb, "o", &arg);
|
|
||||||
|
|
||||||
if (mrb_fixnum_p(arg) && mrb_fixnum(arg) != 0)
|
|
||||||
{
|
|
||||||
return mrb_fixnum_value(rand() % mrb_fixnum(arg));
|
|
||||||
}
|
|
||||||
else if ((mrb_fixnum_p(arg) && mrb_fixnum(arg) == 0) || mrb_nil_p(arg))
|
|
||||||
{
|
|
||||||
return mrb_float_value(mrb, (float) rand() / RAND_MAX);
|
|
||||||
}
|
|
||||||
else if (mrb_float_p(arg))
|
|
||||||
{
|
|
||||||
return mrb_float_value(mrb, (float) rand() / RAND_MAX);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mrb_raisef(mrb, E_TYPE_ERROR, "Expected Fixnum or Float, got %S",
|
|
||||||
mrb_str_new_cstr(mrb, mrb_class_name(mrb, mrb_class(mrb, arg))));
|
|
||||||
return mrb_nil_value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(kernelSrand)
|
|
||||||
{
|
|
||||||
srandCalled = true;
|
|
||||||
|
|
||||||
mrb_int seed;
|
|
||||||
int argc = mrb_get_args(mrb, "|i", &seed);
|
|
||||||
|
|
||||||
if (argc == 1)
|
|
||||||
{
|
|
||||||
srand(seed);
|
|
||||||
|
|
||||||
int oldSeed = currentSeed;
|
|
||||||
currentSeed = seed;
|
|
||||||
|
|
||||||
return mrb_fixnum_value(oldSeed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int oldSeed = currentSeed;
|
|
||||||
srandCurrentTime(¤tSeed);
|
|
||||||
|
|
||||||
return mrb_fixnum_value(oldSeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(kernelExit)
|
|
||||||
{
|
|
||||||
MRB_FUN_UNUSED_PARAM;
|
|
||||||
|
|
||||||
scriptBinding->terminate();
|
|
||||||
|
|
||||||
return mrb_nil_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(kernelLoadData)
|
MRB_FUNCTION(kernelLoadData)
|
||||||
{
|
{
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
@ -211,26 +91,11 @@ MRB_FUNCTION(kernelSaveData)
|
||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
MRB_FUNCTION(kernelInteger)
|
|
||||||
{
|
|
||||||
mrb_value obj;
|
|
||||||
mrb_get_args(mrb, "o", &obj);
|
|
||||||
|
|
||||||
return mrb_to_int(mrb, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernelBindingInit(mrb_state *mrb)
|
void kernelBindingInit(mrb_state *mrb)
|
||||||
{
|
{
|
||||||
RClass *module = mrb->kernel_module;
|
RClass *module = mrb->kernel_module;
|
||||||
|
|
||||||
mrb_define_module_function(mrb, module, "eval", kernelEval, MRB_ARGS_REQ(1));
|
mrb_define_module_function(mrb, module, "eval", kernelEval, MRB_ARGS_REQ(1));
|
||||||
mrb_define_module_function(mrb, module, "p", kernelP, MRB_ARGS_REQ(1) | MRB_ARGS_REST());
|
|
||||||
mrb_define_module_function(mrb, module, "print", kernelPrint, MRB_ARGS_REQ(1) | MRB_ARGS_REST());
|
|
||||||
mrb_define_module_function(mrb, module, "rand", kernelRand, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_module_function(mrb, module, "srand", kernelSrand, MRB_ARGS_OPT(1));
|
|
||||||
mrb_define_module_function(mrb, module, "exit", kernelExit, MRB_ARGS_NONE());
|
|
||||||
mrb_define_module_function(mrb, module, "load_data", kernelLoadData, MRB_ARGS_REQ(1));
|
mrb_define_module_function(mrb, module, "load_data", kernelLoadData, MRB_ARGS_REQ(1));
|
||||||
mrb_define_module_function(mrb, module, "save_data", kernelSaveData, MRB_ARGS_REQ(2));
|
mrb_define_module_function(mrb, module, "save_data", kernelSaveData, MRB_ARGS_REQ(2));
|
||||||
mrb_define_module_function(mrb, module, "exit", kernelExit, MRB_ARGS_NONE());
|
|
||||||
mrb_define_module_function(mrb, module, "Integer", kernelInteger, MRB_ARGS_REQ(1));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,218 +0,0 @@
|
||||||
/*
|
|
||||||
** time.cpp
|
|
||||||
**
|
|
||||||
** This file is part of mkxp.
|
|
||||||
**
|
|
||||||
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
|
|
||||||
**
|
|
||||||
** mkxp is free software: you can redistribute it and/or modify
|
|
||||||
** it under the terms of the GNU General Public License as published by
|
|
||||||
** the Free Software Foundation, either version 2 of the License, or
|
|
||||||
** (at your option) any later version.
|
|
||||||
**
|
|
||||||
** mkxp is distributed in the hope that it will be useful,
|
|
||||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
** GNU General Public License for more details.
|
|
||||||
**
|
|
||||||
** You should have received a copy of the GNU General Public License
|
|
||||||
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../binding-util.h"
|
|
||||||
|
|
||||||
#include <mruby/string.h>
|
|
||||||
#include <mruby/array.h>
|
|
||||||
#include <mruby/class.h>
|
|
||||||
|
|
||||||
#include "time.h"
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct TimeImpl
|
|
||||||
{
|
|
||||||
struct tm _tm;
|
|
||||||
struct timeval _tv;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const mrb_data_type TimeType =
|
|
||||||
{
|
|
||||||
"Time",
|
|
||||||
freeInstance<TimeImpl>
|
|
||||||
};
|
|
||||||
|
|
||||||
extern mrb_value
|
|
||||||
timeFromSecondsInt(mrb_state *mrb, time_t seconds)
|
|
||||||
{
|
|
||||||
TimeImpl *p = new TimeImpl;
|
|
||||||
|
|
||||||
p->_tv.tv_sec = seconds;
|
|
||||||
p->_tm = *localtime(&p->_tv.tv_sec);
|
|
||||||
|
|
||||||
mrb_value obj = wrapObject(mrb, p, TimeType);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(timeAt)
|
|
||||||
{
|
|
||||||
mrb_int seconds;
|
|
||||||
mrb_get_args(mrb, "i", &seconds);
|
|
||||||
|
|
||||||
return timeFromSecondsInt(mrb, seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_FUNCTION(timeNow)
|
|
||||||
{
|
|
||||||
TimeImpl *p = new TimeImpl;
|
|
||||||
|
|
||||||
gettimeofday(&p->_tv, 0);
|
|
||||||
p->_tm = *localtime(&p->_tv.tv_sec);
|
|
||||||
|
|
||||||
mrb_value obj = wrapObject(mrb, p, TimeType);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
static mrb_value
|
|
||||||
secondsAdded(mrb_state *mrb, TimeImpl *p, mrb_int seconds)
|
|
||||||
{
|
|
||||||
TimeImpl *newP = new TimeImpl;
|
|
||||||
*newP = *p;
|
|
||||||
|
|
||||||
newP->_tv.tv_sec += seconds;
|
|
||||||
p->_tm = *localtime(&p->_tv.tv_sec);
|
|
||||||
|
|
||||||
return wrapObject(mrb, newP, TimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(timePlus)
|
|
||||||
{
|
|
||||||
mrb_int seconds;
|
|
||||||
mrb_get_args(mrb, "i", &seconds);
|
|
||||||
|
|
||||||
TimeImpl *p = getPrivateData<TimeImpl>(mrb, self);
|
|
||||||
|
|
||||||
TimeImpl *newP = new TimeImpl;
|
|
||||||
*newP = *p;
|
|
||||||
|
|
||||||
newP->_tv.tv_sec += seconds;
|
|
||||||
p->_tm = *localtime(&p->_tv.tv_sec);
|
|
||||||
|
|
||||||
return wrapObject(mrb, newP, TimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(timeMinus)
|
|
||||||
{
|
|
||||||
mrb_value minuent;
|
|
||||||
mrb_get_args(mrb, "o", &minuent);
|
|
||||||
|
|
||||||
TimeImpl *p = getPrivateData<TimeImpl>(mrb, self);
|
|
||||||
|
|
||||||
if (mrb_fixnum_p(minuent))
|
|
||||||
{
|
|
||||||
mrb_int seconds = mrb_fixnum(minuent);
|
|
||||||
|
|
||||||
return secondsAdded(mrb, p, -seconds);
|
|
||||||
}
|
|
||||||
else if (mrb_type(minuent) == MRB_TT_OBJECT)
|
|
||||||
{
|
|
||||||
TimeImpl *o = getPrivateDataCheck<TimeImpl>(mrb, minuent, TimeType);
|
|
||||||
|
|
||||||
return mrb_float_value(mrb, p->_tv.tv_sec - o->_tv.tv_sec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mrb_raisef(mrb, E_TYPE_ERROR, "Expected Fixnum or Time, got %S",
|
|
||||||
mrb_str_new_cstr(mrb, mrb_class_name(mrb, mrb_class(mrb, minuent))));
|
|
||||||
}
|
|
||||||
|
|
||||||
return mrb_nil_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(timeCompare)
|
|
||||||
{
|
|
||||||
mrb_value cmpTo;
|
|
||||||
mrb_get_args(mrb, "o", &cmpTo);
|
|
||||||
|
|
||||||
mrb_int cmpToS = 0;
|
|
||||||
|
|
||||||
if (mrb_fixnum_p(cmpTo))
|
|
||||||
{
|
|
||||||
cmpToS = mrb_fixnum(cmpTo);
|
|
||||||
}
|
|
||||||
else if (mrb_type(cmpTo) == MRB_TT_OBJECT)
|
|
||||||
{
|
|
||||||
TimeImpl *cmpToP = getPrivateDataCheck<TimeImpl>(mrb, cmpTo, TimeType);
|
|
||||||
cmpToS = cmpToP->_tv.tv_sec;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mrb_raisef(mrb, E_TYPE_ERROR, "Expected Fixnum or Time, got %S",
|
|
||||||
mrb_str_new_cstr(mrb, mrb_class_name(mrb, mrb_class(mrb, cmpTo))));
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeImpl *p = getPrivateData<TimeImpl>(mrb, self);
|
|
||||||
mrb_int selfS = p->_tv.tv_sec;
|
|
||||||
|
|
||||||
if (selfS < cmpToS)
|
|
||||||
return mrb_fixnum_value(-1);
|
|
||||||
else if (selfS == cmpToS)
|
|
||||||
return mrb_fixnum_value(0);
|
|
||||||
else
|
|
||||||
return mrb_fixnum_value(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
MRB_METHOD(timeStrftime)
|
|
||||||
{
|
|
||||||
const char *format;
|
|
||||||
mrb_get_args(mrb, "z", &format);
|
|
||||||
|
|
||||||
TimeImpl *p = getPrivateData<TimeImpl>(mrb, self);
|
|
||||||
|
|
||||||
static char buffer[512];
|
|
||||||
strftime(buffer, sizeof(buffer), format, &p->_tm);
|
|
||||||
|
|
||||||
return mrb_str_new_cstr(mrb, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TIME_ATTR(attr) \
|
|
||||||
MRB_METHOD(timeGet_##attr) \
|
|
||||||
{ \
|
|
||||||
TimeImpl *p = getPrivateData<TimeImpl>(mrb, self); \
|
|
||||||
return mrb_fixnum_value(p->_tm.tm_##attr); \
|
|
||||||
}
|
|
||||||
|
|
||||||
TIME_ATTR(sec)
|
|
||||||
TIME_ATTR(min)
|
|
||||||
TIME_ATTR(hour)
|
|
||||||
TIME_ATTR(mday)
|
|
||||||
TIME_ATTR(mon)
|
|
||||||
TIME_ATTR(year)
|
|
||||||
TIME_ATTR(wday)
|
|
||||||
|
|
||||||
#define TIME_BIND_ATTR(attr) \
|
|
||||||
{ mrb_define_method(mrb, klass, #attr, timeGet_##attr, MRB_ARGS_NONE()); }
|
|
||||||
|
|
||||||
void
|
|
||||||
timeBindingInit(mrb_state *mrb)
|
|
||||||
{
|
|
||||||
RClass *klass = defineClass(mrb, "Time");
|
|
||||||
mrb_include_module(mrb, klass, mrb_module_get(mrb, "Comparable"));
|
|
||||||
|
|
||||||
mrb_define_class_method(mrb, klass, "now", timeNow, MRB_ARGS_NONE());
|
|
||||||
mrb_define_class_method(mrb, klass, "at", timeAt, MRB_ARGS_REQ(1));
|
|
||||||
|
|
||||||
mrb_define_method(mrb, klass, "+", timePlus, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_method(mrb, klass, "-", timeMinus, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_method(mrb, klass, "<=>", timeCompare, MRB_ARGS_REQ(1));
|
|
||||||
mrb_define_method(mrb, klass, "strftime", timeStrftime, MRB_ARGS_REQ(1));
|
|
||||||
|
|
||||||
TIME_BIND_ATTR(sec);
|
|
||||||
TIME_BIND_ATTR(min);
|
|
||||||
TIME_BIND_ATTR(hour);
|
|
||||||
TIME_BIND_ATTR(mday);
|
|
||||||
TIME_BIND_ATTR(mon);
|
|
||||||
TIME_BIND_ATTR(year);
|
|
||||||
TIME_BIND_ATTR(wday);
|
|
||||||
}
|
|
Loading…
Reference in New Issue