Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Added cssminc_process_cstr() and friends to simplify processing CSS from/to C-style strings, primarily to help support a basic WASM build. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
e186ee37ae02f309d514e2f56b2683f5 |
User & Date: | stephan 2022-06-04 09:12:55 |
Context
2022-07-10
| ||
13:56 | Renamed Makefile to GNUmakefile. check-in: f22f86859b user: stephan tags: trunk | |
2022-06-04
| ||
09:12 | Added cssminc_process_cstr() and friends to simplify processing CSS from/to C-style strings, primarily to help support a basic WASM build. check-in: e186ee37ae user: stephan tags: trunk | |
2021-09-15
| ||
04:44 | download.html wording fixes. check-in: a9bc35b5c2 user: stephan tags: trunk | |
Changes
Changes to cssminc.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /** A mostly-minifier for Cascading Style Sheet (CSS) content. This file houses both a library and an app. Compile it with CSSMINC_MAIN defined (a value is not required) to build the app, otherwise it builds as a library. */ #include "cssminc.h" #include <assert.h> | > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /** A mostly-minifier for Cascading Style Sheet (CSS) content. This file houses both a library and an app. Compile it with CSSMINC_MAIN defined (a value is not required) to build the app, otherwise it builds as a library. */ #include "cssminc.h" #include <assert.h> #include <stdlib.h> /* realloc() */ #include <string.h> /* strlen() */ const cssminc_state cssminc_state_empty = cssminc_state_empty_m; const cssminc_state_cstr cssminc_state_cstr_empty = {NULL,NULL,NULL,NULL,0U,0U}; #if 1 && !defined(NDEBUG) #include <stdarg.h> /* For debugging only */ static void logit(char const * fmt, ...) { va_list args; fflush(stdout); |
︙ | ︙ | |||
400 401 402 403 404 405 406 407 408 409 410 411 412 413 | cs.outState = out; cs.in = cssminc_input_f_FILE; cs.inState = in; return cssminc_process(&cs); } /************************************************************************ The library code ends here. What follows is a quick-and-dirty main() app for the library.. ************************************************************************/ #if defined(CSSMINC_MAIN) #include "cliapp.h" | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | cs.outState = out; cs.in = cssminc_input_f_FILE; cs.inState = in; return cssminc_process(&cs); } int cssminc_output_f_cstr(void * state, unsigned char const * bytes, unsigned int n){ cssminc_state_cstr * const s = (cssminc_state_cstr *)state; if(n + s->outLen >= s->outAlloced){ unsigned int const i = (s->outLen ? ((s->outLen + n) * 3 / 2) + 1 : (n < 3 ? 3 : n + 1)); char * z; if(i<=n) return CSSMINC_RC_RANGE/*overflow*/; z = realloc(s->zOut, i); if(!z) return CSSMINC_RC_OOM; s->zOut = z; s->outAlloced = i; } memcpy(s->zOut + s->outLen, bytes, n); s->zOut[s->outLen += n] = 0; return 0; } int cssminc_input_f_cstr(void * state, unsigned char * dest, unsigned int * n) { cssminc_state_cstr * const s = (cssminc_state_cstr *)state; if(!s->zCursor) s->zCursor = s->zStart; if(s->zCursor >= s->zEnd){ *n = 0; return 0; }else if(s->zCursor + *n > s->zEnd){ *n = (unsigned int)(s->zEnd - s->zCursor); } memcpy(dest, s->zCursor, *n); s->zCursor += *n; return 0; } int cssminc_process_cstr(char const * zIn, int len, char ** zOut, unsigned int * outLen, cssminc_state * const opt){ cssminc_state cs = cssminc_state_empty; cssminc_state_cstr cstr = cssminc_state_cstr_empty; int rc; if(len<0) len = (int)strlen(zIn); if(0==len){ *zOut = NULL; *outLen = 0; return 0; } cs.out = cssminc_output_f_cstr; cs.outState = &cstr; cs.in = cssminc_input_f_cstr; cs.inState = &cstr; cstr.zStart = zIn; cstr.zEnd = zIn + len; if(opt) cs.options = opt->options; rc = cssminc_process(&cs); if(opt){ opt->metrics = cs.metrics; opt->errInfo = cs.errInfo; } if(rc){ free(cstr.zOut); }else{ if(outLen) *outLen = cstr.outLen; *zOut = cstr.zOut; } return rc; } char * cssminc_process_cstr2(char const * zIn, int inLen, cssminc_state * const opt){ char * zOut = 0; cssminc_process_cstr(zIn, inLen, &zOut, NULL, opt); return zOut; } /************************************************************************ The library code ends here. What follows is a quick-and-dirty main() app for the library.. ************************************************************************/ #if defined(CSSMINC_MAIN) #include "cliapp.h" |
︙ | ︙ | |||
672 673 674 675 676 677 678 679 680 681 682 683 684 685 | goto end; } if(cssmincGotHelpFlag){ cssminc_show_help(); goto end; } { FILE * in = 0, * out = 0; if(!App.inFile || ('-'==App.inFile[0] && !App.inFile[1])){ in = stdin; }else if(App.inFile){ in = fopen(App.inFile, "rb"); | > > > > > > > > > > > > > > > | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 | goto end; } if(cssmincGotHelpFlag){ cssminc_show_help(); goto end; } if(0){ /* Just testing cssminc_process_cstr() and friends. */ char const * zCss = "/* foo */\nx {y : z}\n" "/* comment */ xyz, zyx {one: \"two\"}"; char * zOut = NULL; didSomething = 1; rc = cssminc_process_cstr(zCss, -1, &zOut, NULL, cs); cliapp_warn("rc=%d zOut=%s\n", rc, zOut); free(zOut); zOut = cssminc_process_cstr2(zCss, -1, cs); cliapp_warn("zOut=%s\n", zOut); free(zOut); goto end; } { FILE * in = 0, * out = 0; if(!App.inFile || ('-'==App.inFile[0] && !App.inFile[1])){ in = stdin; }else if(App.inFile){ in = fopen(App.inFile, "rb"); |
︙ | ︙ |
Changes to cssminc.h.
︙ | ︙ | |||
76 77 78 79 80 81 82 | /** The obligatory "not-an-error" code. */ CSSMINC_RC_OK = 0, /** Indicates that cssminc_process() encountered something it couldn't parse. */ CSSMINC_RC_PARSE = 1, /** Used by cssminc_output_f_FILE() and cssminc_input_f_FILE() to indicate I/O errors. */ | | > > > > > | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | /** The obligatory "not-an-error" code. */ CSSMINC_RC_OK = 0, /** Indicates that cssminc_process() encountered something it couldn't parse. */ CSSMINC_RC_PARSE = 1, /** Used by cssminc_output_f_FILE() and cssminc_input_f_FILE() to indicate I/O errors. */ CSSMINC_RC_IO = 2, /** Indicates some form of range error, e.g. overflow. */ CSSMINC_RC_RANGE = 3, /** Used by cssminc_process_cstr() to indicate a memory allocation failure. */ CSSMINC_RC_OOM = 4 }; /** Abstract streaming output interface used by the cssminc library. The first argument is an implementation-specific state type (may be NULL if the implementation allows it). |
︙ | ︙ | |||
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | If passed a NULL state pointer, it uses stdin. Returns 0 on success, CSSMINC_RC_IO on error. */ int cssminc_input_f_FILE(void * state, unsigned char * dest, unsigned int * n); /** A convenience wrapper which is equivalent to initializing a cssminc_state instance using cssminc_input_f_FILE() matched with the given input source, cssminc_output_f_FILE() matched with the given destination file, and passing it to cssminc_process(). */ int cssminc_process_FILE(FILE * src, FILE * dest); /* LICENSE This software's source code, including accompanying documentation and demonstration applications, are licensed under the following conditions... | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | If passed a NULL state pointer, it uses stdin. Returns 0 on success, CSSMINC_RC_IO on error. */ int cssminc_input_f_FILE(void * state, unsigned char * dest, unsigned int * n); /** A convenience wrapper which is equivalent to initializing a cssminc_state instance using cssminc_input_f_FILE() matched with the given input source, cssminc_output_f_FILE() matched with the given destination file, and passing it to cssminc_process(). */ int cssminc_process_FILE(FILE * src, FILE * dest); /** State for managing C-string input and/or output for cssminc_process(). It can be used as state for both cssminc_input_f_cstr() and cssminc_output_f_cstr() to fetch input from a string and/or send output to a dynamically-allocated string. For input processing, it requires that all input be available in memory for the duration of processing. For output processing it must (re)allocate dynamic memory an arbitrary number of times. */ struct cssminc_state_cstr { /** Input: pointer to the start of the input string. Client must set this before processing starts and it must not change during processing. */ char const * zStart; /** Input: pointer to the one-past-the-end of the input string. Client must set this before processing starts and it must not change during processing. */ char const * zEnd; /** Input: must initially be set to zStart or NULL (same effect either way). Client must set this before processing starts, after which it's managed by cssminc_input_f_cstr(). */ char const * zCursor; /** Output: pointer to the dynamically-allocated output. Must normally be set to NULL before processing, after which it is managed by cssminc_output_f_cstr(), which always NUL-terminates it. It is legal for clients to set this to non-NULL before starting if (and only if): 1) The memory is allocated by malloc() or realloc(). 2) The outAlloced member is set to the number of bytes allocated in that block. If output grows beyond that point, this member gets reallocated and that member gets updated with the new allocation size. */ char * zOut; /** Output: the current string length, in bytes, of zOut (as opposed to its reserved-for-use length). Must be set to 0 before processing, after which it is managed by cssminc_output_f_cstr(). */ unsigned int outLen; /** Output: current amount of memory allocated for use by zOut. Must be set to 0 before processing, after which it is managed by cssminc_output_f_cstr(). */ unsigned int outAlloced; }; typedef struct cssminc_state_cstr cssminc_state_cstr; /** An empty-initialized cssminc_state_cstr instance intended for copy initialization. */ extern const cssminc_state_cstr cssminc_state_cstr_empty; /** A cssminc_output_f() impl which requires that its state pointer be a (cssminc_state_cstr*). This function manages the zOut, outLen, and outAlloced members of that object and requires that all have initial values of 0. All memory allocation for the zOut member is performed using realloc() and must eventually be released by passing it to free(). Returns 0 on success, CSSMINC_RC_OOM on allocation error, or CSSMINC_RC_RANGE if calculating the allocation size would overflow. */ int cssminc_output_f_cstr(void * state, unsigned char const * bytes, unsigned int n); /** A cssminc_input_f() impl which requires that its state pointer be a (cssminc_state_cstr*) with its zStart, zEnd, and zCursor pointers set up properly. This function manages the zCursor pointer. Returns 0 on success and has no error conditions which it can detect. */ int cssminc_input_f_cstr(void * state, unsigned char * dest, unsigned int * n); /** A convenience wrapper which uses cssminc_state_cstr and friends to process input from a C-string and output it to a C-string. The final argument may be NULL, in which case default processing options are used. If it is not NULL, its in/out members are ignored but its `options` member is honored and its `metrics` and `errInfo` members will be populated by this function. If inLen is negative then strlen() is used to calculate zIn's length. On success: - 0 is returned. - `*zOut` will be set to the start of the output string. - `*outLen` (if `outLen` is not NULL) will be set to the length of `*zOut`, in bytes. - Ownership of `*zOut` is transfered to the caller, who must eventually pass it to free(). On error non-0 is returned and neither `zOut` nor `outLen` are modified. */ int cssminc_process_cstr(char const * zIn, int inLen, char ** zOut, unsigned int * outLen, cssminc_state * const opt); /** A convenience form of cssminc_process_cstr() intended primarily for use in WASM bindings. zIn is the input CSS, inLen is its length. If inLen is negative, strlen() is used to calculate it. On success it returns the minified output CSS, else returns NULL on error. If it returns non-NULL then ownership of the memory is transfered to the caller, who must eventually relinquish it using free(). The final argument may be NULL and is treated as documented for cssminc_process_cstr(). */ char * cssminc_process_cstr2(char const * zIn, int inLen, cssminc_state * const opt); /* LICENSE This software's source code, including accompanying documentation and demonstration applications, are licensed under the following conditions... |
︙ | ︙ |