massively improve rectangle render time
This commit is contained in:
@@ -795,7 +795,7 @@ Object.defineProperty(Array.prototype, "forTo", {
|
||||
});
|
||||
|
||||
Object.defineProperty(Array.prototype, "dofilter", {
|
||||
value: function (fn) {
|
||||
value: function array_dofilter(fn) {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
if (!fn.call(this, this[i], i, this)) {
|
||||
this.splice(i, 1);
|
||||
@@ -807,19 +807,19 @@ Object.defineProperty(Array.prototype, "dofilter", {
|
||||
});
|
||||
|
||||
Object.defineProperty(Array.prototype, "reversed", {
|
||||
value: function () {
|
||||
value: function array_reversed() {
|
||||
var c = this.slice();
|
||||
return c.reverse();
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(Array.prototype, "rotate", {
|
||||
value: function (a) {
|
||||
value: function array_rotate(a) {
|
||||
return Vector.rotate(this, a);
|
||||
},
|
||||
});
|
||||
|
||||
Array.random = function(arr) {
|
||||
Array.random = function random(arr) {
|
||||
if (!Array.isArray(arr)) return;
|
||||
return arr[Math.floor(Math.random()*arr.length)];
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ Resources.replstrs = function replstrs(path) {
|
||||
var stem = path.dir();
|
||||
|
||||
if (!console.enabled) script = Resources.rm_fn(/console\.(spam|info|warn|error)/, script);
|
||||
|
||||
if (!profile.enabled) script = Resources.rm_fn(/profile\.(cache|frame|endcache|endframe)/, script);
|
||||
|
||||
if (!debug.enabled) {
|
||||
@@ -340,7 +339,7 @@ io.slurp = function slurp(path)
|
||||
var findpath = Resources.replpath(path);
|
||||
var ret = tmpslurp(findpath, true); //|| core_db.slurp(findpath, true);
|
||||
return ret;
|
||||
}.hashify();
|
||||
}
|
||||
|
||||
io.slurpbytes = function(path)
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ clay.draw = function draw(size, fn)
|
||||
function create_view_fn(base_config)
|
||||
{
|
||||
var base = Object.assign(Object.create(clay_base), base_config);
|
||||
return function(config = {}, fn) {
|
||||
return function view(config = {}, fn) {
|
||||
config.__proto__ = base;
|
||||
var item = add_item(config);
|
||||
|
||||
@@ -223,12 +223,11 @@ layout.draw_commands = function draw_commands(cmds, pos = [0,0])
|
||||
{
|
||||
var mousepos = prosperon.camera.screen2hud(input.mouse.screenpos());
|
||||
for (var cmd of cmds) {
|
||||
cmd.boundingbox.x += pos.x;
|
||||
cmd.boundingbox.y += pos.y;
|
||||
cmd.content.x += pos.x;
|
||||
cmd.content.y += pos.y;
|
||||
var boundingbox = geometry.rect_move(cmd.boundingbox,pos);
|
||||
var content = geometry.rect_move(cmd.content,pos);
|
||||
var config = cmd.config;
|
||||
if (config.hovered && geometry.rect_point_inside(cmd.boundingbox, mousepos)) {
|
||||
|
||||
if (config.hovered && geometry.rect_point_inside(boundingbox, mousepos)) {
|
||||
config.hovered.__proto__ = config;
|
||||
config = config.hovered;
|
||||
hovered = config;
|
||||
@@ -236,25 +235,31 @@ layout.draw_commands = function draw_commands(cmds, pos = [0,0])
|
||||
|
||||
if (config.background_image)
|
||||
if (config.slice)
|
||||
render.slice9(config.background_image, cmd.boundingbox, config.slice, config.background_color);
|
||||
render.slice9(config.background_image, boundingbox, config.slice, config.background_color);
|
||||
else
|
||||
render.image(config.background_image, cmd.boundingbox, 0, config.color);
|
||||
render.image(config.background_image, boundingbox, 0, config.color);
|
||||
else if (config.background_color)
|
||||
render.rectangle(cmd.boundingbox, config.background_color);
|
||||
render.rectangle(boundingbox, config.background_color);
|
||||
|
||||
if (config.text)
|
||||
render.text(config.text, cmd.content, config.font, config.font_size, config.color);
|
||||
render.text(config.text, content, config.font, config.font_size, config.color);
|
||||
if (config.image)
|
||||
render.image(config.image, cmd.content, 0, config.color);
|
||||
render.image(config.image, content, 0, config.color);
|
||||
}
|
||||
}
|
||||
|
||||
var dbg_colors = {};
|
||||
layout.debug_colors = dbg_colors;
|
||||
dbg_colors.content = [1,0,0,0.1];
|
||||
dbg_colors.boundingbox = [0,1,0,0,0.1];
|
||||
dbg_colors.margin = [0,0,1,0.1];
|
||||
layout.draw_debug = function draw_debug(cmds, pos = [0,0])
|
||||
{
|
||||
for (var cmd of cmds) {
|
||||
render.rectangle(cmd.content, [1,0,0,0.1]);
|
||||
render.rectangle(cmd.boundingbox, [0,1,0,0.1]);
|
||||
render.rectangle(cmd.marginbox, [0,0,1,0.1]);
|
||||
for (var i = 0; i < cmds.length; i++) {
|
||||
var cmd = cmds[i];
|
||||
render.rectangle(geometry.rect_move(cmd.content,pos), dbg_colors.content);
|
||||
render.rectangle(geometry.rect_move(cmd.boundingbox,pos), dbg_colors.boundingbox);
|
||||
// render.rectangle(geometry.rect_move(cmd.marginbox,pos), dbg_colors.margin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ global.check_registers = function check_registers(obj) {
|
||||
fn.layer = obj[reg].layer;
|
||||
var name = obj.ur ? obj.ur.name : obj.toString();
|
||||
obj.timers.push(Register.registries[reg].register(fn, name));
|
||||
if (!obj[reg].name) Object.defineProperty(obj[reg], 'name', {value:`${obj._file}_${reg}`});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,6 +551,7 @@ var Register = {
|
||||
var dofn = function (...args) {
|
||||
fn(...args);
|
||||
};
|
||||
Object.defineProperty(dofn, 'name', {value:`do_${oname}`});
|
||||
|
||||
var left = 0;
|
||||
var right = fns.length - 1;
|
||||
@@ -579,7 +581,7 @@ var Register = {
|
||||
// tracy.fiber_leave(vector.fib);
|
||||
};
|
||||
} else
|
||||
prosperon[name] = function name(...args) {
|
||||
prosperon[name] = function (...args) {
|
||||
var layer = undefined;
|
||||
for (var fn of fns) {
|
||||
if (layer !== fn.layer) {
|
||||
@@ -590,6 +592,7 @@ var Register = {
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(prosperon[name], 'name', {value:name});
|
||||
prosperon[name].fns = fns;
|
||||
n.clear = function () {
|
||||
fns = [];
|
||||
|
||||
@@ -732,8 +732,9 @@ render.sprites = function render_sprites() {
|
||||
}
|
||||
*/
|
||||
|
||||
render.use_shader(spritessboshader);
|
||||
var buckets = component.sprite_buckets();
|
||||
if (buckets.length === 0) return;
|
||||
render.use_shader(spritessboshader);
|
||||
for (var l in buckets) {
|
||||
var layer = buckets[l];
|
||||
for (var img in layer) {
|
||||
@@ -790,7 +791,7 @@ function check_flush(flush_fn) {
|
||||
}
|
||||
|
||||
render.flush = check_flush;
|
||||
render.forceflush = function()
|
||||
render.forceflush = function forceflush()
|
||||
{
|
||||
if (nextflush) nextflush();
|
||||
nextflush = undefined;
|
||||
@@ -871,20 +872,15 @@ render.coordinate = function render_coordinate(pos, size, color) {
|
||||
var queued_shader;
|
||||
var queued_pipe;
|
||||
render.rectangle = function render_rectangle(rect, color = Color.white, shader = polyssboshader, pipe = base_pipeline) {
|
||||
var wh = [rect.width, rect.height];
|
||||
var poly = poly_e();
|
||||
var pos = [rect.x,rect.y].add([rect.width,rect.height].scale(0.5));
|
||||
pos = pos.sub([rect.width,rect.height].scale([rect.anchor_x,rect.anchor_y]));
|
||||
poly.transform.move(pos);
|
||||
poly.transform.scale = [wh.x, wh.y, 1];
|
||||
poly.transform.rect(rect);
|
||||
poly.color = color;
|
||||
|
||||
queued_shader = shader;
|
||||
queued_pipe = pipe;
|
||||
check_flush(flush_poly);
|
||||
};
|
||||
|
||||
render.text = function (str, rect, font = cur_font, size = 0, color = Color.white, wrap = -1, ) {
|
||||
render.text = function text(str, rect, font = cur_font, size = 0, color = Color.white, wrap = -1, ) {
|
||||
if (typeof font === 'string')
|
||||
font = render.get_font(font);
|
||||
|
||||
@@ -961,7 +957,7 @@ var stencil_writer = function stencil_writer(ref)
|
||||
render.stencil_writer = stencil_writer;
|
||||
|
||||
// objects by default draw where the stencil buffer is 0
|
||||
render.fillmask = function(ref)
|
||||
render.fillmask = function fillmask(ref)
|
||||
{
|
||||
render.forceflush();
|
||||
var pipe = stencil_writer(ref);
|
||||
@@ -1415,7 +1411,7 @@ try{
|
||||
if (render.draw_sprites) render.sprites();
|
||||
prosperon.draw();
|
||||
if (render.draw_particles) draw_emitters();
|
||||
render.fillmask(0);
|
||||
// render.fillmask(0);
|
||||
render.forceflush();
|
||||
render.set_projection_ortho({
|
||||
l:0,
|
||||
@@ -1468,7 +1464,7 @@ try{
|
||||
}
|
||||
};
|
||||
|
||||
//if (dmon) dmon.watch('.');
|
||||
if (dmon) dmon.watch('.');
|
||||
|
||||
function dmon_cb(e)
|
||||
{
|
||||
@@ -1485,7 +1481,7 @@ function dmon_cb(e)
|
||||
prosperon.process = function process() {
|
||||
layout.newframe();
|
||||
// check for hot reloading
|
||||
// if (dmon) dmon.poll(dmon_cb);
|
||||
if (dmon) dmon.poll(dmon_cb);
|
||||
var dt = profile.secs(profile.now()) - frame_t;
|
||||
frame_t = profile.secs(profile.now());
|
||||
|
||||
|
||||
@@ -2034,6 +2034,14 @@ JSC_CCALL(transform_trs,
|
||||
t->scale = JS_IsUndefined(argv[2]) ? v3one : js2vec3(js,argv[2]);
|
||||
)
|
||||
|
||||
JSC_CCALL(transform_rect,
|
||||
transform *t = js2transform(js,self);
|
||||
rect r = js2rect(js,argv[0]);
|
||||
t->pos = (HMM_Vec3){r.x,r.y,0};
|
||||
t->scale = (HMM_Vec3){r.w,r.h,1};
|
||||
t->rotation = QUAT1;
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_transform_funcs[] = {
|
||||
CGETSET_ADD(transform, pos),
|
||||
CGETSET_ADD(transform, scale),
|
||||
@@ -2046,9 +2054,9 @@ static const JSCFunctionListEntry js_transform_funcs[] = {
|
||||
MIST_FUNC_DEF(transform, lookat, 1),
|
||||
MIST_FUNC_DEF(transform, direction, 1),
|
||||
MIST_FUNC_DEF(transform, unit, 0),
|
||||
MIST_FUNC_DEF(transform, rect, 1),
|
||||
};
|
||||
|
||||
|
||||
JSC_CCALL(datastream_time, return number2js(js,plm_get_time(js2datastream(js,self)->plm)); )
|
||||
|
||||
JSC_CCALL(datastream_advance_frames, ds_advanceframes(js2datastream(js,self), js2number(js,argv[0])))
|
||||
@@ -2232,12 +2240,30 @@ JSC_CCALL(geometry_cwh2rect,
|
||||
return rect2js(js,r);
|
||||
)
|
||||
|
||||
JSC_CCALL(geometry_rect_pos,
|
||||
rect r = js2rect(js,argv[0]);
|
||||
return vec22js(js,(HMM_Vec2){
|
||||
.x = r.x,
|
||||
.y = r.y
|
||||
});
|
||||
)
|
||||
|
||||
JSC_CCALL(geometry_rect_move,
|
||||
rect r = js2rect(js,argv[0]);
|
||||
HMM_Vec2 move = js2vec2(js,argv[1]);
|
||||
r.x += move.x;
|
||||
r.y += move.y;
|
||||
return rect2js(js,r);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_geometry_funcs[] = {
|
||||
MIST_FUNC_DEF(geometry, rect_intersect, 2),
|
||||
MIST_FUNC_DEF(geometry, rect_inside, 2),
|
||||
MIST_FUNC_DEF(geometry, rect_random, 1),
|
||||
MIST_FUNC_DEF(geometry, cwh2rect, 2),
|
||||
MIST_FUNC_DEF(geometry, rect_point_inside, 2),
|
||||
MIST_FUNC_DEF(geometry, rect_pos, 1),
|
||||
MIST_FUNC_DEF(geometry, rect_move, 2),
|
||||
};
|
||||
|
||||
JSValue js_os_cwd(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
|
||||
314
source/wildmatch.c
Normal file
314
source/wildmatch.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c), 2016 David Aguilar
|
||||
* Based on the fnmatch implementation from OpenBSD.
|
||||
*
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Guido van Rossum.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wildmatch.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define EOS '\0'
|
||||
#define RANGE_MATCH 1
|
||||
#define RANGE_NOMATCH 0
|
||||
#define RANGE_ERROR -1
|
||||
|
||||
#define check_flag(flags, opts) ((flags) & (opts))
|
||||
|
||||
static int rangematch(const char *, char, int, const char **);
|
||||
|
||||
int wildmatch(const char *pattern, const char *string, int flags)
|
||||
{
|
||||
const char *stringstart;
|
||||
const char *newp;
|
||||
const char *slash;
|
||||
char c, test;
|
||||
char prev;
|
||||
int wild = 0;
|
||||
|
||||
/* WM_WILDSTAR implies WM_PATHNAME. */
|
||||
if (check_flag(flags, WM_WILDSTAR)) {
|
||||
flags |= WM_PATHNAME;
|
||||
}
|
||||
|
||||
for (stringstart = string;;) {
|
||||
switch (c = *pattern++) {
|
||||
case EOS:
|
||||
if (check_flag(flags, WM_LEADING_DIR) && *string == '/')
|
||||
return WM_MATCH;
|
||||
return (*string == EOS) ? WM_MATCH : WM_NOMATCH;
|
||||
case '?':
|
||||
if (*string == EOS)
|
||||
return WM_NOMATCH;
|
||||
if (*string == '/' && check_flag(flags, WM_PATHNAME))
|
||||
return WM_NOMATCH;
|
||||
if (*string == '.' && check_flag(flags, WM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
(check_flag(flags, WM_PATHNAME) && *(string - 1) == '/')))
|
||||
return WM_NOMATCH;
|
||||
++string;
|
||||
break;
|
||||
case '*':
|
||||
c = *pattern;
|
||||
wild = check_flag(flags, WM_WILDSTAR) && c == '*';
|
||||
if (wild) {
|
||||
prev = pattern[-2];
|
||||
/* Collapse multiple stars and slash-** patterns,
|
||||
* e.g. "** / *** / **** / **" (without spaces)
|
||||
* is treated as a single ** wildstar.
|
||||
*/
|
||||
while (c == '*') {
|
||||
c = *++pattern;
|
||||
}
|
||||
|
||||
while (c == '/' && pattern[1] == '*' && pattern[2] == '*') {
|
||||
prev = c;
|
||||
c = *++pattern;
|
||||
while (c == '*') {
|
||||
c = *++pattern;
|
||||
}
|
||||
}
|
||||
if (c == '/' &&
|
||||
wildmatch(pattern+1, string, flags) == WM_MATCH) {
|
||||
return WM_MATCH;
|
||||
}
|
||||
} else {
|
||||
/* Collapse multiple stars. */
|
||||
while (c == '*') {
|
||||
c = *++pattern;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wild && *string == '.' && check_flag(flags, WM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
(check_flag(flags, WM_PATHNAME) && *(string - 1) == '/'))) {
|
||||
return WM_NOMATCH;
|
||||
}
|
||||
/* Optimize for pattern with * or ** at end or before /. */
|
||||
if (c == EOS) {
|
||||
if (wild && prev == '/') {
|
||||
return WM_MATCH;
|
||||
}
|
||||
if (check_flag(flags, WM_PATHNAME)) {
|
||||
return (check_flag(flags, WM_LEADING_DIR) ||
|
||||
strchr(string, '/') == NULL ? WM_MATCH : WM_NOMATCH);
|
||||
} else {
|
||||
return WM_MATCH;
|
||||
}
|
||||
} else if (c == '/') {
|
||||
if (wild) {
|
||||
slash = strchr(stringstart, '/');
|
||||
if (!slash) {
|
||||
return WM_NOMATCH;
|
||||
}
|
||||
while (slash) {
|
||||
if (wildmatch(pattern+1, slash+1, flags) == 0) {
|
||||
return WM_MATCH;
|
||||
}
|
||||
slash = strchr(slash+1, '/');
|
||||
}
|
||||
} else {
|
||||
if (check_flag(flags, WM_PATHNAME)) {
|
||||
if ((string = strchr(string, '/')) == NULL) {
|
||||
return WM_NOMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (wild) {
|
||||
return WM_NOMATCH;
|
||||
}
|
||||
/* General case, use recursion. */
|
||||
while ((test = *string) != EOS) {
|
||||
if (!wildmatch(pattern, string, flags & ~WM_PERIOD))
|
||||
return WM_MATCH;
|
||||
if (test == '/' && check_flag(flags, WM_PATHNAME))
|
||||
break;
|
||||
++string;
|
||||
}
|
||||
return WM_NOMATCH;
|
||||
case '[':
|
||||
if (*string == EOS)
|
||||
return WM_NOMATCH;
|
||||
if (*string == '/' && check_flag(flags, WM_PATHNAME))
|
||||
return WM_NOMATCH;
|
||||
if (*string == '.' && check_flag(flags, WM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
(check_flag(flags, WM_PATHNAME) && *(string - 1) == '/')))
|
||||
return WM_NOMATCH;
|
||||
|
||||
switch (rangematch(pattern, *string, flags, &newp)) {
|
||||
case RANGE_ERROR:
|
||||
/* not a good range, treat as normal text */
|
||||
++string;
|
||||
goto normal;
|
||||
case RANGE_MATCH:
|
||||
pattern = newp;
|
||||
break;
|
||||
case RANGE_NOMATCH:
|
||||
return (WM_NOMATCH);
|
||||
}
|
||||
++string;
|
||||
break;
|
||||
case '\\':
|
||||
if (!check_flag(flags, WM_NOESCAPE)) {
|
||||
if ((c = *pattern++) == EOS) {
|
||||
c = '\\';
|
||||
--pattern;
|
||||
if (*(string+1) == EOS) {
|
||||
return WM_NOMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
normal:
|
||||
if (c != *string && !(check_flag(flags, WM_CASEFOLD) &&
|
||||
(tolower((unsigned char)c) ==
|
||||
tolower((unsigned char)*string))))
|
||||
return WM_NOMATCH;
|
||||
++string;
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
rangematch(const char *pattern, char test, int flags, const char **newp)
|
||||
{
|
||||
int negate, ok;
|
||||
char c, c2;
|
||||
char tmp;
|
||||
|
||||
/*
|
||||
* A bracket expression starting with an unquoted circumflex
|
||||
* character produces unspecified results (IEEE 1003.2-1992,
|
||||
* 3.13.2). This implementation treats it like '!', for
|
||||
* consistency with the regular expression syntax.
|
||||
* J.T. Conklin (conklin@ngai.kaleida.com)
|
||||
*/
|
||||
if ((negate = (*pattern == '!' || *pattern == '^')))
|
||||
++pattern;
|
||||
|
||||
if (check_flag(flags, WM_CASEFOLD))
|
||||
test = tolower((unsigned char)test);
|
||||
|
||||
/*
|
||||
* A right bracket shall lose its special meaning and represent
|
||||
* itself in a bracket expression if it occurs first in the list.
|
||||
* -- POSIX.2 2.8.3.2
|
||||
*/
|
||||
ok = 0;
|
||||
c = *pattern++;
|
||||
do {
|
||||
if (c == '\\' && !check_flag(flags, WM_NOESCAPE))
|
||||
c = *pattern++;
|
||||
|
||||
if (c == EOS)
|
||||
return RANGE_ERROR;
|
||||
|
||||
if (c == '/' && check_flag(flags, WM_PATHNAME))
|
||||
return RANGE_NOMATCH;
|
||||
|
||||
if (*pattern == '-'
|
||||
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
|
||||
pattern += 2;
|
||||
if (c2 == '\\' && !check_flag(flags, WM_NOESCAPE))
|
||||
c2 = *pattern++;
|
||||
if (c2 == EOS)
|
||||
return RANGE_ERROR;
|
||||
|
||||
if (check_flag(flags, WM_CASEFOLD)) {
|
||||
c = tolower((unsigned char)c);
|
||||
c2 = tolower((unsigned char)c2);
|
||||
}
|
||||
if (c > c2) {
|
||||
tmp = c2;
|
||||
c2 = c;
|
||||
c = tmp;
|
||||
}
|
||||
if (c <= test && test <= c2) {
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '[' && *pattern == ':' && *(pattern+1) != EOS) {
|
||||
|
||||
#define match_pattern(name) \
|
||||
!strncmp(pattern+1, name, sizeof(name)-1)
|
||||
|
||||
#define check_pattern(name, predicate, value) {{ \
|
||||
if (match_pattern(name ":]")) { \
|
||||
if (predicate(value)) { \
|
||||
ok = 1; \
|
||||
} \
|
||||
pattern += sizeof(name ":]"); \
|
||||
continue; \
|
||||
} \
|
||||
}}
|
||||
|
||||
if (match_pattern(":]")) {
|
||||
continue;
|
||||
}
|
||||
check_pattern("alnum", isalnum, test);
|
||||
check_pattern("alpha", isalpha, test);
|
||||
check_pattern("blank", isblank, test);
|
||||
check_pattern("cntrl", iscntrl, test);
|
||||
check_pattern("digit", isdigit, test);
|
||||
check_pattern("graph", isgraph, test);
|
||||
check_pattern("lower", islower, test);
|
||||
check_pattern("print", isprint, test);
|
||||
check_pattern("punct", ispunct, test);
|
||||
check_pattern("space", isspace, test);
|
||||
check_pattern("xdigit", isxdigit, test);
|
||||
c2 = check_flag(flags, WM_CASEFOLD) ? toupper(test) : test;
|
||||
check_pattern("upper", isupper, c2);
|
||||
/* fallthrough means match like a normal character */
|
||||
}
|
||||
if (c == test) {
|
||||
ok = 1;
|
||||
}
|
||||
} while ((c = *pattern++) != ']');
|
||||
|
||||
*newp = (const char *)pattern;
|
||||
return (ok == negate) ? RANGE_NOMATCH : RANGE_MATCH;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
80
source/wildmatch.h
Normal file
80
source/wildmatch.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c), 2016 David Aguilar
|
||||
* Based on the fnmatch implementation from OpenBSD.
|
||||
*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
|
||||
* $OpenBSD: fnmatch.h,v 1.4 1997/09/22 05:25:32 millert Exp $
|
||||
*/
|
||||
#ifndef _WILDMATCH_H_
|
||||
#define _WILDMATCH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WM_MATCH 0 /* Match. */
|
||||
#define WM_NOMATCH 1 /* Match failed. */
|
||||
|
||||
#define WM_NOESCAPE 0x01 /* Disable backslash escaping. */
|
||||
#define WM_PATHNAME 0x02 /* Slash must be matched by slash. */
|
||||
#define WM_PERIOD 0x04 /* Period must be matched by period. */
|
||||
#define WM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
|
||||
#define WM_CASEFOLD 0x10 /* Case insensitive search. */
|
||||
#define WM_PREFIX_DIRS 0x20 /* Unused */
|
||||
#define WM_WILDSTAR 0x40 /* Double-asterisks ** matches slash too. */
|
||||
|
||||
#define WM_IGNORECASE WM_CASEFOLD
|
||||
#define WM_FILE_NAME WM_PATHNAME
|
||||
|
||||
/*
|
||||
* wildmatch is an extension of function fnmatch(3) as specified in
|
||||
* POSIX 1003.2-1992, section B.6.
|
||||
*
|
||||
* Compares a filename or pathname to a pattern.
|
||||
*
|
||||
* wildmatch is fnmatch-compatible by default. Its new features are enabled
|
||||
* by passing WM_WILDSTAR in flags, which makes ** match across path
|
||||
* boundaries. WM_WILDSTAR implies WM_PATHNAME and WM_PERIOD.
|
||||
*
|
||||
* The WM_ flags are the named the same as their FNM_ fnmatch counterparts
|
||||
* and are compatible in behavior to fnmatch(3) in the absence of WM_WILDSTAR.
|
||||
*/
|
||||
|
||||
int wildmatch(const char *pattern, const char *string, int flags);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user