tytest: add framework to add special escape codes for tests
This commit is contained in:
parent
4e38d0d2c7
commit
fd8120091d
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
#include <Elementary.h>
|
#include <Elementary.h>
|
||||||
|
|
||||||
#include "tytest.h"
|
|
||||||
#include "termio.h"
|
#include "termio.h"
|
||||||
#include "miniview.h"
|
#include "miniview.h"
|
||||||
#include "termpty.h"
|
#include "termpty.h"
|
||||||
#include "termptyops.h"
|
#include "termptyops.h"
|
||||||
#include "termiointernals.h"
|
#include "termiointernals.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
|
#include "tytest.h"
|
||||||
|
|
||||||
/* {{{ Selection */
|
/* {{{ Selection */
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include <Elementary.h>
|
#include <Elementary.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "col.h"
|
#include "col.h"
|
||||||
#include "termio.h"
|
#include "termio.h"
|
||||||
#include "termpty.h"
|
#include "termpty.h"
|
||||||
|
@ -3750,35 +3751,42 @@ _handle_esc_terminology(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *
|
||||||
Eina_Unicode *cc, *cc_zero = NULL;
|
Eina_Unicode *cc, *cc_zero = NULL;
|
||||||
const Eina_Unicode *buf;
|
const Eina_Unicode *buf;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
int blen = 0;
|
size_t blen = 0;
|
||||||
Config *config;
|
Config *config;
|
||||||
|
|
||||||
if (!ty->buf_have_zero) return 0;
|
if (!ty->buf_have_zero)
|
||||||
|
return 0;
|
||||||
|
|
||||||
config = termio_config_get(ty->obj);
|
config = termio_config_get(ty->obj);
|
||||||
|
|
||||||
cc = (Eina_Unicode *)c;
|
cc = (Eina_Unicode *)c;
|
||||||
if ((cc < ce) && (*cc == 0x0)) cc_zero = cc;
|
if ((cc < ce) && (*cc == 0x0))
|
||||||
|
cc_zero = cc;
|
||||||
while ((cc < ce) && (*cc != 0x0))
|
while ((cc < ce) && (*cc != 0x0))
|
||||||
{
|
{
|
||||||
blen++;
|
blen++;
|
||||||
cc++;
|
cc++;
|
||||||
}
|
}
|
||||||
if ((cc < ce) && (*cc == 0x0)) cc_zero = cc;
|
if ((cc < ce) && (*cc == 0x0))
|
||||||
if (!cc_zero) return 0;
|
cc_zero = cc;
|
||||||
|
if (!cc_zero)
|
||||||
|
return 0;
|
||||||
buf = (Eina_Unicode *)c;
|
buf = (Eina_Unicode *)c;
|
||||||
cc = cc_zero;
|
cc = cc_zero;
|
||||||
|
|
||||||
// commands are stored in the buffer, 0 bytes not allowed (end marker)
|
// commands are stored in the buffer, 0 bytes not allowed (end marker)
|
||||||
cmd = eina_unicode_unicode_to_utf8(buf, NULL);
|
cmd = eina_unicode_unicode_to_utf8(buf, NULL);
|
||||||
ty->cur_cmd = cmd;
|
ty->cur_cmd = cmd;
|
||||||
if ((!config->ty_escapes) || (!_termpty_ext_handle(ty, cmd, buf)))
|
if ((!config->ty_escapes) || (!termpty_ext_handle(ty, buf, blen)))
|
||||||
{
|
{
|
||||||
if (ty->cb.command.func) ty->cb.command.func(ty->cb.command.data);
|
if (ty->cb.command.func)
|
||||||
|
ty->cb.command.func(ty->cb.command.data);
|
||||||
}
|
}
|
||||||
ty->cur_cmd = NULL;
|
ty->cur_cmd = NULL;
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
|
||||||
|
assert((size_t)(cc - c) == blen);
|
||||||
|
|
||||||
return cc - c;
|
return cc - c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include <Elementary.h>
|
#include <Elementary.h>
|
||||||
#include "termpty.h"
|
#include "termpty.h"
|
||||||
#include "termptyops.h"
|
#include "termptyops.h"
|
||||||
|
#include "tytest.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#undef CRITICAL
|
#undef CRITICAL
|
||||||
#undef ERR
|
#undef ERR
|
||||||
|
@ -33,12 +35,12 @@
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_handle_op_a(Termpty *_ty EINA_UNUSED,
|
_handle_op_a(Termpty *_ty EINA_UNUSED,
|
||||||
const char *txt,
|
const Eina_Unicode *buf EINA_UNUSED,
|
||||||
const Eina_Unicode *_utxt EINA_UNUSED)
|
size_t blen)
|
||||||
{
|
{
|
||||||
switch (txt[1])
|
switch (buf[0])
|
||||||
{
|
{
|
||||||
case 'a': // command aa*
|
case 'x': // command ax*
|
||||||
break;
|
break;
|
||||||
// room here for more minor opcode chars like 'b', 'c' etc.
|
// room here for more minor opcode chars like 'b', 'c' etc.
|
||||||
default:
|
default:
|
||||||
|
@ -48,14 +50,22 @@ _handle_op_a(Termpty *_ty EINA_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
_termpty_ext_handle(Termpty *ty, const char *txt, const Eina_Unicode *utxt)
|
termpty_ext_handle(Termpty *ty,
|
||||||
|
const Eina_Unicode *buf,
|
||||||
|
size_t blen)
|
||||||
{
|
{
|
||||||
switch (txt[0]) // major opcode
|
switch (buf[0]) // major opcode
|
||||||
{
|
{
|
||||||
case 'a': // command a*
|
case 'a': // command a*
|
||||||
return _handle_op_a(ty, txt, utxt);
|
return _handle_op_a(ty, buf + 1, blen - 1);
|
||||||
break;
|
break;
|
||||||
// room here for more major opcode chars like 'b', 'c' etc.
|
// room here for more major opcode chars like 'b', 'c' etc.
|
||||||
|
#if defined(ENABLE_TESTS)
|
||||||
|
case 't':
|
||||||
|
tytest_handle_escape_codes(ty, buf + 1, blen - 1);
|
||||||
|
return EINA_FALSE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef _TERMPTY_EXT_H__
|
#ifndef _TERMPTY_EXT_H__
|
||||||
#define _TERMPTY_EXT_H__ 1
|
#define _TERMPTY_EXT_H__ 1
|
||||||
|
|
||||||
Eina_Bool _termpty_ext_handle(Termpty *ty, const char *txt, const Eina_Unicode *utxt);
|
Eina_Bool
|
||||||
|
termpty_ext_handle(Termpty *ty,
|
||||||
|
const Eina_Unicode *buf,
|
||||||
|
size_t blen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
156
src/bin/tyfuzz.c
156
src/bin/tyfuzz.c
|
@ -18,6 +18,9 @@
|
||||||
#include "col.h"
|
#include "col.h"
|
||||||
#include "tytest.h"
|
#include "tytest.h"
|
||||||
#include "md5/md5.h"
|
#include "md5/md5.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
_tytest_checksum(Termpty *ty);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TY_H 25
|
#define TY_H 25
|
||||||
|
@ -192,159 +195,6 @@ termio_set_cursor_shape(Evas_Object *obj EINA_UNUSED,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* }}} */
|
/* }}} */
|
||||||
/* {{{ TYTEST */
|
|
||||||
#ifdef TYTEST
|
|
||||||
const char *_cursor_shape = "undefined";
|
|
||||||
typedef struct _Termpty_Tests
|
|
||||||
{
|
|
||||||
size_t backsize, backpos;
|
|
||||||
Backlog_Beacon backlog_beacon;
|
|
||||||
Term_State termstate;
|
|
||||||
Term_Cursor cursor_state;
|
|
||||||
Term_Cursor cursor_save[2];
|
|
||||||
int w, h;
|
|
||||||
unsigned int altbuf : 1;
|
|
||||||
unsigned int mouse_mode : 3;
|
|
||||||
unsigned int mouse_ext : 2;
|
|
||||||
unsigned int bracketed_paste : 1;
|
|
||||||
} Termpty_Tests;
|
|
||||||
|
|
||||||
Evas_Object *
|
|
||||||
termio_textgrid_get(const Evas_Object *obj EINA_UNUSED)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
test_textgrid_palette_get(const Evas_Object *obj EINA_UNUSED,
|
|
||||||
Evas_Textgrid_Palette pal,
|
|
||||||
int idx,
|
|
||||||
int *r,
|
|
||||||
int *g,
|
|
||||||
int *b,
|
|
||||||
int *a)
|
|
||||||
{
|
|
||||||
if (pal == EVAS_TEXTGRID_PALETTE_EXTENDED)
|
|
||||||
{
|
|
||||||
colors_256_get(idx,
|
|
||||||
(unsigned char *)r,
|
|
||||||
(unsigned char *)g,
|
|
||||||
(unsigned char *)b,
|
|
||||||
(unsigned char *)a);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int set = idx / 12;
|
|
||||||
int col = idx % 12;
|
|
||||||
colors_standard_get(set, col,
|
|
||||||
(unsigned char*)r,
|
|
||||||
(unsigned char*)g,
|
|
||||||
(unsigned char*)b,
|
|
||||||
(unsigned char*)a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
termio_set_cursor_shape(Evas_Object *obj EINA_UNUSED,
|
|
||||||
Cursor_Shape shape EINA_UNUSED)
|
|
||||||
{
|
|
||||||
switch (shape)
|
|
||||||
{
|
|
||||||
case CURSOR_SHAPE_UNDERLINE:
|
|
||||||
_cursor_shape = "underline";
|
|
||||||
break;
|
|
||||||
case CURSOR_SHAPE_BAR:
|
|
||||||
_cursor_shape = "bar";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case CURSOR_SHAPE_BLOCK:
|
|
||||||
_cursor_shape = "block";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_termpty_to_termpty_tests(Termpty *ty, Termpty_Tests *tt)
|
|
||||||
{
|
|
||||||
memset(tt, '\0', sizeof(*tt));
|
|
||||||
tt->backsize = ty->backsize;
|
|
||||||
tt->backpos = ty->backpos;
|
|
||||||
tt->backlog_beacon = ty->backlog_beacon;
|
|
||||||
tt->termstate = ty->termstate;
|
|
||||||
tt->cursor_state = ty->cursor_state;
|
|
||||||
tt->cursor_save[0] = ty->cursor_save[0];
|
|
||||||
tt->cursor_save[1] = ty->cursor_save[1];
|
|
||||||
tt->w = ty->w;
|
|
||||||
tt->h = ty->h;
|
|
||||||
tt->altbuf = ty->altbuf;
|
|
||||||
tt->mouse_mode = ty->mouse_mode;
|
|
||||||
tt->mouse_ext = ty->mouse_ext;
|
|
||||||
tt->bracketed_paste = ty->bracketed_paste;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_tytest_checksum(Termpty *ty)
|
|
||||||
{
|
|
||||||
MD5_CTX ctx;
|
|
||||||
Termpty_Tests tests;
|
|
||||||
char md5out[(2 * MD5_HASHBYTES) + 1];
|
|
||||||
unsigned char hash[MD5_HASHBYTES];
|
|
||||||
static const char hex[] = "0123456789abcdef";
|
|
||||||
int n;
|
|
||||||
|
|
||||||
_termpty_to_termpty_tests(ty, &tests);
|
|
||||||
|
|
||||||
MD5Init(&ctx);
|
|
||||||
/* Termpty */
|
|
||||||
MD5Update(&ctx,
|
|
||||||
(unsigned char const*)&tests,
|
|
||||||
sizeof(tests));
|
|
||||||
/* The screens */
|
|
||||||
MD5Update(&ctx,
|
|
||||||
(unsigned char const*)ty->screen,
|
|
||||||
sizeof(Termcell) * ty->w * ty->h);
|
|
||||||
MD5Update(&ctx,
|
|
||||||
(unsigned char const*)ty->screen2,
|
|
||||||
sizeof(Termcell) * ty->w * ty->h);
|
|
||||||
/* Icon/Title */
|
|
||||||
if (ty->prop.icon)
|
|
||||||
{
|
|
||||||
MD5Update(&ctx,
|
|
||||||
(unsigned char const*)ty->prop.icon,
|
|
||||||
strlen(ty->prop.icon));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MD5Update(&ctx, (unsigned char const*)"(NULL)", 6);
|
|
||||||
}
|
|
||||||
if (ty->prop.title)
|
|
||||||
{
|
|
||||||
MD5Update(&ctx,
|
|
||||||
(unsigned char const*)ty->prop.title,
|
|
||||||
strlen(ty->prop.title));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MD5Update(&ctx, (unsigned char const*)"(NULL)", 6);
|
|
||||||
}
|
|
||||||
/* Cursor shape */
|
|
||||||
MD5Update(&ctx, (unsigned char const*)_cursor_shape,
|
|
||||||
strlen(_cursor_shape));
|
|
||||||
/* Write buffer */
|
|
||||||
MD5Update(&ctx, (unsigned char const*)ty->write_buffer.buf,
|
|
||||||
ty->write_buffer.len);
|
|
||||||
|
|
||||||
MD5Final(hash, &ctx);
|
|
||||||
|
|
||||||
for (n = 0; n < MD5_HASHBYTES; n++)
|
|
||||||
{
|
|
||||||
md5out[2 * n] = hex[hash[n] >> 4];
|
|
||||||
md5out[2 * n + 1] = hex[hash[n] & 0x0f];
|
|
||||||
}
|
|
||||||
md5out[2 * MD5_HASHBYTES] = '\0';
|
|
||||||
printf("%s", md5out);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
177
src/bin/tytest.c
177
src/bin/tytest.c
|
@ -1,2 +1,179 @@
|
||||||
#define TYTEST 1
|
#define TYTEST 1
|
||||||
#include "tyfuzz.c"
|
#include "tyfuzz.c"
|
||||||
|
|
||||||
|
const char *_cursor_shape = "undefined";
|
||||||
|
|
||||||
|
typedef struct _Termpty_Tests
|
||||||
|
{
|
||||||
|
size_t backsize, backpos;
|
||||||
|
Backlog_Beacon backlog_beacon;
|
||||||
|
Term_State termstate;
|
||||||
|
Term_Cursor cursor_state;
|
||||||
|
Term_Cursor cursor_save[2];
|
||||||
|
int w, h;
|
||||||
|
unsigned int altbuf : 1;
|
||||||
|
unsigned int mouse_mode : 3;
|
||||||
|
unsigned int mouse_ext : 2;
|
||||||
|
unsigned int bracketed_paste : 1;
|
||||||
|
} Termpty_Tests;
|
||||||
|
|
||||||
|
Evas_Object *
|
||||||
|
termio_textgrid_get(const Evas_Object *obj EINA_UNUSED)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_textgrid_palette_get(const Evas_Object *obj EINA_UNUSED,
|
||||||
|
Evas_Textgrid_Palette pal,
|
||||||
|
int idx,
|
||||||
|
int *r,
|
||||||
|
int *g,
|
||||||
|
int *b,
|
||||||
|
int *a)
|
||||||
|
{
|
||||||
|
if (pal == EVAS_TEXTGRID_PALETTE_EXTENDED)
|
||||||
|
{
|
||||||
|
colors_256_get(idx,
|
||||||
|
(unsigned char *)r,
|
||||||
|
(unsigned char *)g,
|
||||||
|
(unsigned char *)b,
|
||||||
|
(unsigned char *)a);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int set = idx / 12;
|
||||||
|
int col = idx % 12;
|
||||||
|
colors_standard_get(set, col,
|
||||||
|
(unsigned char*)r,
|
||||||
|
(unsigned char*)g,
|
||||||
|
(unsigned char*)b,
|
||||||
|
(unsigned char*)a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
termio_set_cursor_shape(Evas_Object *obj EINA_UNUSED,
|
||||||
|
Cursor_Shape shape EINA_UNUSED)
|
||||||
|
{
|
||||||
|
switch (shape)
|
||||||
|
{
|
||||||
|
case CURSOR_SHAPE_UNDERLINE:
|
||||||
|
_cursor_shape = "underline";
|
||||||
|
break;
|
||||||
|
case CURSOR_SHAPE_BAR:
|
||||||
|
_cursor_shape = "bar";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case CURSOR_SHAPE_BLOCK:
|
||||||
|
_cursor_shape = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_termpty_to_termpty_tests(Termpty *ty, Termpty_Tests *tt)
|
||||||
|
{
|
||||||
|
memset(tt, '\0', sizeof(*tt));
|
||||||
|
tt->backsize = ty->backsize;
|
||||||
|
tt->backpos = ty->backpos;
|
||||||
|
tt->backlog_beacon = ty->backlog_beacon;
|
||||||
|
tt->termstate = ty->termstate;
|
||||||
|
tt->cursor_state = ty->cursor_state;
|
||||||
|
tt->cursor_save[0] = ty->cursor_save[0];
|
||||||
|
tt->cursor_save[1] = ty->cursor_save[1];
|
||||||
|
tt->w = ty->w;
|
||||||
|
tt->h = ty->h;
|
||||||
|
tt->altbuf = ty->altbuf;
|
||||||
|
tt->mouse_mode = ty->mouse_mode;
|
||||||
|
tt->mouse_ext = ty->mouse_ext;
|
||||||
|
tt->bracketed_paste = ty->bracketed_paste;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_tytest_checksum(Termpty *ty)
|
||||||
|
{
|
||||||
|
MD5_CTX ctx;
|
||||||
|
Termpty_Tests tests;
|
||||||
|
char md5out[(2 * MD5_HASHBYTES) + 1];
|
||||||
|
unsigned char hash[MD5_HASHBYTES];
|
||||||
|
static const char hex[] = "0123456789abcdef";
|
||||||
|
int n;
|
||||||
|
|
||||||
|
_termpty_to_termpty_tests(ty, &tests);
|
||||||
|
|
||||||
|
MD5Init(&ctx);
|
||||||
|
/* Termpty */
|
||||||
|
MD5Update(&ctx,
|
||||||
|
(unsigned char const*)&tests,
|
||||||
|
sizeof(tests));
|
||||||
|
/* The screens */
|
||||||
|
MD5Update(&ctx,
|
||||||
|
(unsigned char const*)ty->screen,
|
||||||
|
sizeof(Termcell) * ty->w * ty->h);
|
||||||
|
MD5Update(&ctx,
|
||||||
|
(unsigned char const*)ty->screen2,
|
||||||
|
sizeof(Termcell) * ty->w * ty->h);
|
||||||
|
/* Icon/Title */
|
||||||
|
if (ty->prop.icon)
|
||||||
|
{
|
||||||
|
MD5Update(&ctx,
|
||||||
|
(unsigned char const*)ty->prop.icon,
|
||||||
|
strlen(ty->prop.icon));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MD5Update(&ctx, (unsigned char const*)"(NULL)", 6);
|
||||||
|
}
|
||||||
|
if (ty->prop.title)
|
||||||
|
{
|
||||||
|
MD5Update(&ctx,
|
||||||
|
(unsigned char const*)ty->prop.title,
|
||||||
|
strlen(ty->prop.title));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MD5Update(&ctx, (unsigned char const*)"(NULL)", 6);
|
||||||
|
}
|
||||||
|
/* Cursor shape */
|
||||||
|
MD5Update(&ctx, (unsigned char const*)_cursor_shape,
|
||||||
|
strlen(_cursor_shape));
|
||||||
|
/* Write buffer */
|
||||||
|
MD5Update(&ctx, (unsigned char const*)ty->write_buffer.buf,
|
||||||
|
ty->write_buffer.len);
|
||||||
|
|
||||||
|
MD5Final(hash, &ctx);
|
||||||
|
|
||||||
|
for (n = 0; n < MD5_HASHBYTES; n++)
|
||||||
|
{
|
||||||
|
md5out[2 * n] = hex[hash[n] >> 4];
|
||||||
|
md5out[2 * n + 1] = hex[hash[n] & 0x0f];
|
||||||
|
}
|
||||||
|
md5out[2 * MD5_HASHBYTES] = '\0';
|
||||||
|
printf("%s", md5out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_handle_mouse_down(Termpty *ty EINA_UNUSED,
|
||||||
|
const Eina_Unicode *buf EINA_UNUSED,
|
||||||
|
size_t blen EINA_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Testing escape codes that start with '\033}t' and end with '\0'
|
||||||
|
* Then,
|
||||||
|
* - 'd': mouse down:
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tytest_handle_escape_codes(Termpty *ty,
|
||||||
|
const Eina_Unicode *buf,
|
||||||
|
size_t blen)
|
||||||
|
{
|
||||||
|
switch (buf[0])
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
return _handle_mouse_down(ty, buf + 1, blen - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,5 +11,9 @@ test_textgrid_palette_get(const Evas_Object *obj,
|
||||||
int *g,
|
int *g,
|
||||||
int *b,
|
int *b,
|
||||||
int *a);
|
int *a);
|
||||||
|
void
|
||||||
|
tytest_handle_escape_codes(Termpty *ty,
|
||||||
|
const Eina_Unicode *buf,
|
||||||
|
size_t blen);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue