/* * Copy URI string */ static int copy_uri_string(const rchar **source_, rchar **target_, rcssmin_ctx_t *ctx) { const rchar *source = *source_; rchar *target = *target_; rchar c, quote = source[-1]; *target++ = quote; *target_ = target; while (source < ctx->sentinel && target < ctx->tsentinel) { c = *source++; if (RCSSMIN_IS_SPACE(c)) continue; *target++ = c; if (RCSSMIN_IS_STRING_DULL(c)) continue; switch (c) { case U('\''): case U('"'): if (c == quote) { *target_ = target; *source_ = source; return 0; } continue; case U('\\'): if (source < ctx->sentinel && target < ctx->tsentinel) { c = *source; switch (c) { case U('\r'): if ((source + 1) < ctx->sentinel && source[1] == U('\n')) ++source; /* fall through */ case U('\n'): case U('\f'): --target; ++source; break; default: --target; copy_escape(&source, &target, ctx); } } continue; } break; /* forbidden characters */ } RABORT(-1); }
/* * Main function * * The return value determines the result length (kept in the target buffer). * However, if the target buffer is too small, the return value is greater * than tlength. The difference to tlength is the number of unconsumed source * characters at the time the buffer was full. In this case you should resize * the target buffer to the return value and call rcssmin again. Repeat as * often as needed. */ static Py_ssize_t rcssmin(const rchar *source, rchar *target, Py_ssize_t slength, Py_ssize_t tlength, int keep_bang_comments) { rcssmin_ctx_t ctx_, *ctx = &ctx_; const rchar *tstart = target; rchar c; ctx->start = source; ctx->sentinel = source + slength; ctx->tsentinel = target + tlength; ctx->at_group = 0; ctx->in_macie5 = 0; ctx->in_rule = 0; ctx->keep_bang_comments = keep_bang_comments; while (source < ctx->sentinel && target < ctx->tsentinel) { c = *source++; if (RCSSMIN_IS_DULL(c)) { *target++ = c; continue; } else if (RCSSMIN_IS_SPACE(c)) { copy_space(&source, &target, ctx, NEED_SPACE_MAYBE); continue; } switch (c) { /* Escape */ case U('\\'): copy_escape(&source, &target, ctx); continue; /* String */ case U('"'): case U('\''): copy_string(&source, &target, ctx); continue; /* URL */ case U('u'): copy_url(&source, &target, ctx); continue; /* IE7hack */ case U('>'): copy_ie7hack(&source, &target, ctx); continue; /* @-group */ case U('@'): copy_at_group(&source, &target, ctx); continue; /* ; */ case U(';'): copy_semicolon(&source, &target, ctx); continue; /* :first-line|letter followed by [{,] */ /* (apparently needed for IE6) */ case U(':'): copy_first(&source, &target, ctx); continue; /* { */ case U('{'): if (ctx->at_group) --ctx->at_group; else ++ctx->in_rule; *target++ = c; continue; /* } */ case U('}'): if (ctx->in_rule) --ctx->in_rule; *target++ = c; continue; /* space starting with comment */ case U('/'): (void)copy_space_comment(&source, &target, ctx, NEED_SPACE_MAYBE); continue; /* Fallback: copy character. Better safe than sorry. Should not be * reached, though */ default: *target++ = c; continue; } } return (Py_ssize_t)(target - tstart) + (Py_ssize_t)(ctx->sentinel - source); }
int main(void) { copy_escape(); }