summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-pack
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-06-12 16:14:01 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-06-12 16:18:45 +0900
commit96ad60b9aad6284695101e3578f8c326a564fcbd (patch)
tree0d0d7be43d4fb6d0c9f7a16893c395fb8034231b /mrbgems/mruby-pack
parent952e7efdd7b07a83e99ec4a680684020a7adabc8 (diff)
downloadmruby-96ad60b9aad6284695101e3578f8c326a564fcbd.tar.gz
mruby-96ad60b9aad6284695101e3578f8c326a564fcbd.zip
pack.c: support `@' directive (absolute position).
Diffstat (limited to 'mrbgems/mruby-pack')
-rw-r--r--mrbgems/mruby-pack/src/pack.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c
index 094844eb7..3e73a7181 100644
--- a/mrbgems/mruby-pack/src/pack.c
+++ b/mrbgems/mruby-pack/src/pack.c
@@ -40,6 +40,7 @@ enum pack_dir {
PACK_DIR_QENC, /* M */
PACK_DIR_NUL, /* x */
PACK_DIR_BACK, /* X */
+ PACK_DIR_ABS, /* @ */
PACK_DIR_INVALID
};
@@ -1218,13 +1219,17 @@ alias:
dir = PACK_DIR_BACK;
type = PACK_TYPE_NONE;
break;
+ case '@':
+ dir = PACK_DIR_ABS;
+ type = PACK_TYPE_NONE;
+ break;
case 'Z':
dir = PACK_DIR_STR;
type = PACK_TYPE_STRING;
flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_Z;
break;
case 'p': case 'P':
- case '%': case '@':
+ case '%':
mrb_raisef(mrb, E_ARGUMENT_ERROR, "%c is not supported", (char)t);
break;
default:
@@ -1309,6 +1314,14 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
ridx -= count;
continue;
}
+ else if (dir == PACK_DIR_ABS) {
+ count -= ridx;
+ if (count > 0) goto grow;
+ count = -count;
+ check_x(mrb, ridx, count, '@');
+ ridx -= count;
+ continue;
+ }
if ((flags & PACK_FLAG_WIDTH) && aidx >= RARRAY_LEN(ary)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments");
@@ -1427,6 +1440,11 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single)
srcidx -= count;
continue;
}
+ else if (dir == PACK_DIR_ABS) {
+ check_x(mrb, srclen, count, '@');
+ srcidx = count;
+ continue;
+ }
if (flags & PACK_FLAG_COUNT2) {
sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx;