| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 |
#include "config.h" |
|---|
| 35 |
#include <vlc_common.h> |
|---|
| 36 |
#include <vlc_input.h> |
|---|
| 37 |
#include <vlc_demux.h> |
|---|
| 38 |
|
|---|
| 39 |
#include <limits.h> |
|---|
| 40 |
#include <string.h> |
|---|
| 41 |
|
|---|
| 42 |
#include "asademux.h" |
|---|
| 43 |
|
|---|
| 44 |
#define MAXDELTA 4 |
|---|
| 45 |
#define MAXGROUP 24 |
|---|
| 46 |
|
|---|
| 47 |
#define xmalloc malloc |
|---|
| 48 |
#define xrealloc realloc |
|---|
| 49 |
#define xfree free |
|---|
| 50 |
#define xstrdup strdup |
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
struct asa_import_state { |
|---|
| 54 |
demux_t *demux; |
|---|
| 55 |
const char *line; |
|---|
| 56 |
size_t remain; |
|---|
| 57 |
|
|---|
| 58 |
char **matches; |
|---|
| 59 |
unsigned nmatches; |
|---|
| 60 |
char *selstr; |
|---|
| 61 |
size_t sellen; |
|---|
| 62 |
char *out; |
|---|
| 63 |
size_t outlen; |
|---|
| 64 |
|
|---|
| 65 |
int64_t usecperf, |
|---|
| 66 |
origusecperf, |
|---|
| 67 |
start, |
|---|
| 68 |
end; |
|---|
| 69 |
int64_t delta[MAXDELTA]; |
|---|
| 70 |
|
|---|
| 71 |
asa_import_callback *cb; |
|---|
| 72 |
void *cb_arg; |
|---|
| 73 |
}; |
|---|
| 74 |
|
|---|
| 75 |
#define iargs struct asa_import_state *state, struct asa_import_insn *insn |
|---|
| 76 |
|
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
|
|---|
| 84 |
typedef int (*asa_import_func)(iargs); |
|---|
| 85 |
|
|---|
| 86 |
static int asai_commit (iargs); |
|---|
| 87 |
static int asai_discard(iargs); |
|---|
| 88 |
static int asai_break (iargs); |
|---|
| 89 |
static int asai_select (iargs); |
|---|
| 90 |
static int asai_sg (iargs); |
|---|
| 91 |
static int asai_sgu (iargs); |
|---|
| 92 |
static int asai_append (iargs); |
|---|
| 93 |
static int asai_fps (iargs); |
|---|
| 94 |
static int asai_show (iargs); |
|---|
| 95 |
static int asai_hide (iargs); |
|---|
| 96 |
static int asai_child (iargs); |
|---|
| 97 |
#undef iargs |
|---|
| 98 |
|
|---|
| 99 |
|
|---|
| 100 |
static const asa_import_func importfuncs[] = { |
|---|
| 101 |
asai_commit, |
|---|
| 102 |
asai_discard, |
|---|
| 103 |
asai_break, |
|---|
| 104 |
asai_select, |
|---|
| 105 |
asai_sg, |
|---|
| 106 |
asai_sgu, |
|---|
| 107 |
asai_append, |
|---|
| 108 |
asai_fps, |
|---|
| 109 |
asai_show, |
|---|
| 110 |
asai_hide, |
|---|
| 111 |
asai_child |
|---|
| 112 |
}; |
|---|
| 113 |
#define ASAI_MAX (unsigned)(sizeof(importfuncs) / sizeof(importfuncs[0])) |
|---|
| 114 |
|
|---|
| 115 |
struct asa_import_detect *asa_det_first = NULL, |
|---|
| 116 |
**asa_det_last = &asa_det_first; |
|---|
| 117 |
struct asa_import_format *asa_fmt_first = NULL, |
|---|
| 118 |
**asa_fmt_last = &asa_fmt_first; |
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 |
static void asa_imports_crosslink(void) |
|---|
| 125 |
{ |
|---|
| 126 |
struct asa_import_format *fmt, *fmt2; |
|---|
| 127 |
struct asa_import_detect *det; |
|---|
| 128 |
|
|---|
| 129 |
for (fmt = asa_fmt_first; fmt; fmt = fmt->next) { |
|---|
| 130 |
for (fmt2 = fmt->next; fmt2; fmt2 = fmt2->next) |
|---|
| 131 |
if (!strcmp(fmt->name, fmt2->name)) { |
|---|
| 132 |
fmt->nexttgt = fmt2; |
|---|
| 133 |
fmt2->prevtgt = fmt; |
|---|
| 134 |
break; |
|---|
| 135 |
} |
|---|
| 136 |
} |
|---|
| 137 |
|
|---|
| 138 |
for (det = asa_det_first; det; det = det->next) { |
|---|
| 139 |
det->fmt = NULL; |
|---|
| 140 |
for (fmt = asa_fmt_first; fmt; fmt = fmt->next) |
|---|
| 141 |
if (!strcmp(det->name, fmt->name)) { |
|---|
| 142 |
det->fmt = fmt; |
|---|
| 143 |
break; |
|---|
| 144 |
} |
|---|
| 145 |
} |
|---|
| 146 |
} |
|---|
| 147 |
|
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 |
|
|---|
| 151 |
|
|---|
| 152 |
|
|---|
| 153 |
struct asa_import_detect *asa_imports_detect(const void *data, size_t dlen) |
|---|
| 154 |
{ |
|---|
| 155 |
struct asa_import_detect *det; |
|---|
| 156 |
const char *d = (const char *)data; |
|---|
| 157 |
int v[64]; |
|---|
| 158 |
|
|---|
| 159 |
if (dlen > 2048) |
|---|
| 160 |
dlen = 2048; |
|---|
| 161 |
for (det = asa_det_first; det; det = det->next) |
|---|
| 162 |
if (pcre_exec(det->re.pcre, NULL, d, dlen, 0, 0, v, 64) >= 0) |
|---|
| 163 |
return det; |
|---|
| 164 |
return NULL; |
|---|
| 165 |
} |
|---|
| 166 |
|
|---|
| 167 |
|
|---|
| 168 |
|
|---|
| 169 |
static int asai_run_insns(struct asa_import_state *state, |
|---|
| 170 |
struct asa_import_insn *insn) |
|---|
| 171 |
{ |
|---|
| 172 |
struct asa_import_insn *inow = insn, preload; |
|---|
| 173 |
int rv, repeating = 0; |
|---|
| 174 |
|
|---|
| 175 |
preload.next = insn; |
|---|
| 176 |
for (; inow; inow = inow->next) { |
|---|
| 177 |
if (repeating && inow->insn != ASAI_CHILD) |
|---|
| 178 |
continue; |
|---|
| 179 |
if (inow->insn >= ASAI_MAX) |
|---|
| 180 |
continue; |
|---|
| 181 |
rv = importfuncs[inow->insn](state, inow); |
|---|
| 182 |
if (rv == -1) { |
|---|
| 183 |
inow = &preload; |
|---|
| 184 |
continue; |
|---|
| 185 |
} |
|---|
| 186 |
if (rv > 0) |
|---|
| 187 |
return rv - 1; |
|---|
| 188 |
} |
|---|
| 189 |
|
|---|
| 190 |
return -1; |
|---|
| 191 |
} |
|---|
| 192 |
|
|---|
| 193 |
|
|---|
| 194 |
|
|---|
| 195 |
static int asai_commit(struct asa_import_state *state, |
|---|
| 196 |
struct asa_import_insn *insn) |
|---|
| 197 |
{ |
|---|
| 198 |
int rv = 0; |
|---|
| 199 |
|
|---|
| 200 |
if (!state->out) |
|---|
| 201 |
return 0; |
|---|
| 202 |
if (state->outlen > 0) |
|---|
| 203 |
rv = state->cb(state->demux, state->cb_arg, |
|---|
| 204 |
state->start, state->end, |
|---|
| 205 |
state->out, state->outlen); |
|---|
| 206 |
xfree(state->out); |
|---|
| 207 |
state->out = NULL; |
|---|
| 208 |
state->outlen = 0; |
|---|
| 209 |
if (rv) |
|---|
| 210 |
return INT_MAX; |
|---|
| 211 |
return 0; |
|---|
| 212 |
} |
|---|
| 213 |
|
|---|
| 214 |
|
|---|
| 215 |
|
|---|
| 216 |
static int asai_discard(struct asa_import_state *state, |
|---|
| 217 |
struct asa_import_insn *insn) |
|---|
| 218 |
{ |
|---|
| 219 |
if (!state->out) |
|---|
| 220 |
return 0; |
|---|
| 221 |
xfree(state->out); |
|---|
| 222 |
state->out = NULL; |
|---|
| 223 |
state->outlen = 0; |
|---|
| 224 |
return 0; |
|---|
| 225 |
} |
|---|
| 226 |
|
|---|
| 227 |
|
|---|
| 228 |
|
|---|
| 229 |
static int asai_break(struct asa_import_state *state, |
|---|
| 230 |
struct asa_import_insn *insn) |
|---|
| 231 |
{ |
|---|
| 232 |
return insn->v.break_depth; |
|---|
| 233 |
} |
|---|
| 234 |
|
|---|
| 235 |
|
|---|
| 236 |
|
|---|
| 237 |
static int asai_select (struct asa_import_state *state, |
|---|
| 238 |
struct asa_import_insn *insn) |
|---|
| 239 |
{ |
|---|
| 240 |
if (insn->v.select < 0 |
|---|
| 241 |
|| (unsigned)insn->v.select >= state->nmatches) { |
|---|
| 242 |
msg_Err(state->demux, "import script trying to " |
|---|
| 243 |
"reference group %d, maximum is %d", |
|---|
| 244 |
insn->v.select, state->nmatches); |
|---|
| 245 |
return 0; |
|---|
| 246 |
} |
|---|
| 247 |
if (state->selstr) |
|---|
| 248 |
xfree(state->selstr); |
|---|
| 249 |
state->selstr = xstrdup(state->matches[insn->v.select]); |
|---|
| 250 |
state->sellen = strlen(state->selstr); |
|---|
| 251 |
return 0; |
|---|
| 252 |
} |
|---|
| 253 |
|
|---|
| 254 |
#include <stddef.h> |
|---|
| 255 |
static ptrdiff_t asai_process_replace(struct asa_import_state *state, |
|---|
| 256 |
struct asa_import_insn *insn, int *v, int rv) |
|---|
| 257 |
{ |
|---|
| 258 |
struct asa_repl *r; |
|---|
| 259 |
char *newstr; |
|---|
| 260 |
ptrdiff_t newpos, firstold; |
|---|
| 261 |
size_t newstr_size; |
|---|
| 262 |
|
|---|
| 263 |
newstr_size = v[0] * 2; |
|---|
| 264 |
newstr = (char *)xmalloc(newstr_size); |
|---|
| 265 |
memcpy(newstr, state->selstr, v[0]); |
|---|
| 266 |
newpos = v[0]; |
|---|
| 267 |
|
|---|
| 268 |
for (r = insn->v.sg.repl; r; r = r->next) { |
|---|
| 269 |
size_t avail = newstr_size - newpos, need; |
|---|
| 270 |
const char *src; |
|---|
| 271 |
|
|---|
| 272 |
if (r->group >= rv) { |
|---|
| 273 |
msg_Err(state->demux, |
|---|
| 274 |
"import script trying to replace by " |
|---|
| 275 |
"reference group %d, maximum is %d", |
|---|
| 276 |
r->group, rv); |
|---|
| 277 |
continue; |
|---|
| 278 |
} |
|---|
| 279 |
if (r->group >= 0) { |
|---|
| 280 |
need = v[r->group * 2 + 1] - v[r->group * 2]; |
|---|
| 281 |
src = state->selstr + v[r->group * 2]; |
|---|
| 282 |
} else { |
|---|
| 283 |
need = strlen(r->text); |
|---|
| 284 |
src = r->text; |
|---|
| 285 |
} |
|---|
| 286 |
if (need > avail) { |
|---|
| 287 |
newstr_size += need - avail + 256; |
|---|
| 288 |
newstr = (char *)xrealloc(newstr, newstr_size); |
|---|
| 289 |
} |
|---|
| 290 |
memcpy(newstr + newpos, src, need); |
|---|
| 291 |
newpos += need; |
|---|
| 292 |
} |
|---|
| 293 |
firstold = newpos; |
|---|
| 294 |
newstr_size = newpos + state->sellen - v[1]; |
|---|
| 295 |
newstr = (char *)xrealloc(newstr, newstr_size + 1); |
|---|
| 296 |
memcpy(newstr + newpos, state->selstr + v[1], |
|---|
| 297 |
state->sellen - v[1] + 1); |
|---|
| 298 |
state->selstr = newstr; |
|---|
| 299 |
state->sellen = newstr_size; |
|---|
| 300 |
return firstold; |
|---|
| 301 |
} |
|---|
| 302 |
|
|---|
| 303 |
|
|---|
| 304 |
|
|---|
| 305 |
static int asai_sg(struct asa_import_state *state, |
|---|
| 306 |
struct asa_import_insn *insn) |
|---|
| 307 |
{ |
|---|
| 308 |
int rv, v[MAXGROUP * 2]; |
|---|
| 309 |
char *oldstr; |
|---|
| 310 |
ptrdiff_t s = 0; |
|---|
| 311 |
|
|---|
| 312 |
if (!state->selstr) |
|---|
| 313 |
return 0; |
|---|
| 314 |
while ((unsigned)s < state->sellen && |
|---|
| 315 |
(rv = pcre_exec(insn->v.sg.regex.pcre, NULL, state->selstr, |
|---|
| 316 |
state->sellen, s, 0, v, MAXGROUP * 2)) >= 0) { |
|---|
| 317 |
oldstr = state->selstr; |
|---|
| 318 |
s = asai_process_replace(state, insn, v, rv); |
|---|
| 319 |
xfree(oldstr); |
|---|
| 320 |
} |
|---|
| 321 |
return 0; |
|---|
| 322 |
} |
|---|
| 323 |
|
|---|
| 324 |
|
|---|
| 325 |
|
|---|
| 326 |
static inline char **asai_chunk_alloc(char **old, int *v, int rv) |
|---|
| 327 |
{ |
|---|
| 328 |
size_t s = rv * sizeof(char *); |
|---|
| 329 |
int i; |
|---|
| 330 |
for (i = 0; i < rv; i++) |
|---|
| 331 |
s += v[i * 2 + 1] - v[i * 2] + 1; |
|---|
| 332 |
return (char **)xrealloc(old, s); |
|---|
| 333 |
} |
|---|
| 334 |
|
|---|
| 335 |
|
|---|
| 336 |
static void asai_set_matches(struct asa_import_state *state, |
|---|
| 337 |
const char *src, int *v, int rv) |
|---|
| 338 |
{ |
|---|
| 339 |
unsigned i; |
|---|
| 340 |
char *dst; |
|---|
| 341 |
|
|---|
| 342 |
state->matches = asai_chunk_alloc(state->matches, v, rv); |
|---|
| 343 |
state->nmatches = rv; |
|---|
| 344 |
dst = (char *)(state->matches + rv); |
|---|
| 345 |
for (i = 0; i < state->nmatches; i++) { |
|---|
| 346 |
size_t len = v[2 * i + 1] - v[2 * i]; |
|---|
| 347 |
state->matches[i] = dst; |
|---|
| 348 |
memcpy(dst, src + v[2 * i], len); |
|---|
| 349 |
dst[len] = '\0'; |
|---|
| 350 |
dst += len + 1; |
|---|
| 351 |
} |
|---|
| 352 |
if (state->selstr) |
|---|
| 353 |
xfree(state->selstr); |
|---|
| 354 |
state->selstr = xstrdup(state->matches[0]); |
|---|
| 355 |
state->sellen = strlen(state->selstr); |
|---|
| 356 |
} |
|---|
| 357 |
|
|---|
| 358 |
|
|---|
| 359 |
|
|---|
| 360 |
static int asai_sgu(struct asa_import_state *state, |
|---|
| 361 |
struct asa_import_insn *insn) |
|---|
| 362 |
{ |
|---|
| 363 |
int rv, v[MAXGROUP * 2]; |
|---|
| 364 |
char *oldstr; |
|---|
| 365 |
|
|---|
| 366 |
if (!state->selstr) |
|---|
| 367 |
return 0; |
|---|
| 368 |
if ((rv = pcre_exec(insn->v.sg.regex.pcre, NULL, state->selstr, |
|---|
| 369 |
state->sellen, 0, 0, v, MAXGROUP * 2)) >= 0) { |
|---|
| 370 |
oldstr = state->selstr; |
|---|
| 371 |
asai_process_replace(state, insn, v, rv); |
|---|
| 372 |
|
|---|
| 373 |
asai_set_matches(state, oldstr, v, rv); |
|---|
| 374 |
xfree(oldstr); |
|---|
| 375 |
} |
|---|
| 376 |
return 0; |
|---|
| 377 |
} |
|---|
| 378 |
|
|---|
| 379 |
|
|---|
| 380 |
|
|---|
| 381 |
static int asai_append (struct asa_import_state *state, |
|---|
| 382 |
struct asa_import_insn *insn) |
|---|
| 383 |
{ |
|---|
| 384 |
state->out = (char *)xrealloc(state->out, |
|---|
| 385 |
state->outlen + state->sellen + 1); |
|---|
| 386 |
memcpy(state->out + state->outlen, state->selstr, state->sellen); |
|---|
| 387 |
state->outlen += state->sellen; |
|---|
| 388 |
state->out[state->outlen] = '\0'; |
|---|
| 389 |
return 0; |
|---|
| 390 |
} |
|---|
| 391 |
|
|---|
| 392 |
|
|---|
| 393 |
|
|---|
| 394 |
static int asai_fps(struct asa_import_state *state, |
|---|
| 395 |
struct asa_import_insn *insn) |
|---|
| 396 |
{ |
|---|
| 397 |
if (insn->v.fps_value == 0) |
|---|
| 398 |
state->usecperf = state->origusecperf; |
|---|
| 399 |
else |
|---|
| 400 |
state->usecperf = (int64_t)(1000000. / insn->v.fps_value); |
|---|
| 401 |
return 0; |
|---|
| 402 |
} |
|---|
| 403 |
|
|---|
| 404 |
|
|---|
| 405 |
|
|---|
| 406 |
|
|---|
| 407 |
|
|---|
| 408 |
|
|---|
| 409 |
static int64_t asai_gettime(struct asa_import_state *state, |
|---|
| 410 |
struct asa_import_insn *insn) |
|---|
| 411 |
{ |
|---|
| 412 |
struct asa_tspec *tsp; |
|---|
| 413 |
int64_t t = 0; |
|---|
| 414 |
if (insn->v.tspec.delta_select != -1) { |
|---|
| 415 |
if (insn->v.tspec.delta_select < MAXDELTA) |
|---|
| 416 |
t += state->delta[insn->v.tspec.delta_select]; |
|---|
| 417 |
else |
|---|
| 418 |
msg_Err(state->demux, "imports: tspec " |
|---|
| 419 |
"delta %d exceeds compiled-in maximum of %d", |
|---|
| 420 |
insn->v.tspec.delta_select, MAXDELTA); |
|---|
| 421 |
} |
|---|
| 422 |
for (tsp = insn->v.tspec.tsp; tsp; tsp = tsp->next) { |
|---|
| 423 |
char *errptr; |
|---|
| 424 |
double src; |
|---|
| 425 |
|
|---|
| 426 |
if ((unsigned)tsp->group >= state->nmatches) { |
|---|
| 427 |
msg_Err(state->demux, "imports: tspec " |
|---|
| 428 |
"tries to access group %d, but only " |
|---|
| 429 |
"%d groups exist", |
|---|
| 430 |
tsp->group, state->nmatches); |
|---|
| 431 |
continue; |
|---|
| 432 |
} |
|---|
| 433 |
if (!*state->matches[tsp->group]) |
|---|
| 434 |
continue; |
|---|
| 435 |
src = strtod(state->matches[tsp->group], &errptr); |
|---|
| 436 |
if (*errptr) |
|---|
| 437 |
msg_Warn(state->demux, "imports: invalid tspec '%s'", |
|---|
| 438 |
state->matches[tsp->group]); |
|---|
| 439 |
t += (src * tsp->mult * 1000000) |
|---|
| 440 |
+ src * tsp->fps_mult * state->usecperf; |
|---|
| 441 |
} |
|---|
| 442 |
memmove(state->delta + 1, state->delta, |
|---|
| 443 |
sizeof(state->delta[0]) * (MAXDELTA - 1)); |
|---|
| 444 |
state->delta[0] = t; |
|---|
| 445 |
return t; |
|---|
| 446 |
} |
|---|
| 447 |
|
|---|
| 448 |
|
|---|
| 449 |
|
|---|
| 450 |
static int asai_show(struct asa_import_state *state, |
|---|
| 451 |
struct asa_import_insn *insn) |
|---|
| 452 |
{ |
|---|
| 453 |
state->start = asai_gettime(state, insn); |
|---|
| 454 |
return 0; |
|---|
| 455 |
} |
|---|
| 456 |
|
|---|
| 457 |
|
|---|
| 458 |
|
|---|
| 459 |
static int asai_hide(struct asa_import_state *state, |
|---|
| 460 |
struct asa_import_insn *insn) |
|---|
| 461 |
{ |
|---|
| 462 |
state->end = asai_gettime(state, insn); |
|---|
| 463 |
return 0; |
|---|
| 464 |
} |
|---|
| 465 |
|
|---|
| 466 |
|
|---|
| 467 |
|
|---|
| 468 |
static int asai_child(struct asa_import_state *state, |
|---|
| 469 |
struct asa_import_insn *insn) |
|---|
| 470 |
{ |
|---|
| 471 |
int rv, v[MAXGROUP * 2]; |
|---|
| 472 |
if ((rv = pcre_exec(insn->v.child.regex.pcre, NULL, state->line, |
|---|
| 473 |
state->remain, 0, 0, v, MAXGROUP * 2)) >= 0) { |
|---|
| 474 |
asai_set_matches(state, state->line, v, rv); |
|---|
| 475 |
state->line += v[1]; |
|---|
| 476 |
state->remain -= v[1]; |
|---|
| 477 |
rv = asai_run_insns(state, insn->v.child.insns); |
|---|
| 478 |
return rv; |
|---|
| 479 |
} |
|---|
| 480 |
return 0; |
|---|
| 481 |
} |
|---|
| 482 |
|
|---|
| 483 |
int asa_import(demux_t *d, const void *data, size_t dlen, |
|---|
| 484 |
int64_t usecperframe, struct asa_import_detect *det, |
|---|
| 485 |
asa_import_callback *callback, void *arg) |
|---|
| 486 |
{ |
|---|
| 487 |
struct asa_import_format *fmt = det->fmt; |
|---|
| 488 |
struct asa_import_state state; |
|---|
| 489 |
int rv; |
|---|
| 490 |
|
|---|
| 491 |
memset(&state, 0, sizeof(state)); |
|---|
| 492 |
state.demux = d; |
|---|
| 493 |
state.usecperf = state.origusecperf = usecperframe; |
|---|
| 494 |
state.line = (const char *)data; |
|---|
| 495 |
state.remain = dlen; |
|---|
| 496 |
state.cb = callback; |
|---|
| 497 |
state.cb_arg = arg; |
|---|
| 498 |
|
|---|
| 499 |
rv = asai_run_insns(&state, fmt->insns); |
|---|
| 500 |
if (state.matches) |
|---|
| 501 |
xfree(state.matches); |
|---|
| 502 |
if (state.out) { |
|---|
| 503 |
callback(d, arg, state.start, state.end, |
|---|
| 504 |
state.out, state.outlen); |
|---|
| 505 |
xfree(state.out); |
|---|
| 506 |
} |
|---|
| 507 |
if (state.selstr) |
|---|
| 508 |
xfree(state.selstr); |
|---|
| 509 |
return rv; |
|---|
| 510 |
} |
|---|
| 511 |
|
|---|
| 512 |
int asa_pcre_compile(asa_pcre *out, const char *str) |
|---|
| 513 |
{ |
|---|
| 514 |
const char *err; |
|---|
| 515 |
int ec, eo; |
|---|
| 516 |
|
|---|
| 517 |
out->pcre = pcre_compile2(str, 0, &ec, &err, &eo, NULL); |
|---|
| 518 |
if (out->pcre) |
|---|
| 519 |
return 0; |
|---|
| 520 |
return 1; |
|---|
| 521 |
} |
|---|
| 522 |
|
|---|
| 523 |
#include "asademux_defs.h" |
|---|
| 524 |
|
|---|
| 525 |
void asa_init_import() |
|---|
| 526 |
{ |
|---|
| 527 |
static int setup = 0; |
|---|
| 528 |
if (setup) |
|---|
| 529 |
return; |
|---|
| 530 |
|
|---|
| 531 |
preparse_add(); |
|---|
| 532 |
asa_imports_crosslink(); |
|---|
| 533 |
setup = 1; |
|---|
| 534 |
} |
|---|