Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <stdint.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include <libcss/libcss.h>
  6.  
  7. #include "utils/utils.h"
  8.  
  9. #include "testutils.h"
  10.  
  11. typedef struct line_ctx {
  12.         size_t buflen;
  13.         size_t bufused;
  14.         uint8_t *buf;
  15.  
  16.         size_t explen;
  17.         char exp[256];
  18.  
  19.         bool indata;
  20.         bool inexp;
  21. } line_ctx;
  22.  
  23. static bool handle_line(const char *data, size_t datalen, void *pw);
  24. static void run_test(const uint8_t *data, size_t len,
  25.                 const char *exp, size_t explen);
  26. static void print_css_fixed(char *buf, size_t len, css_fixed f);
  27.  
  28. int main(int argc, char **argv)
  29. {
  30.         line_ctx ctx;
  31.  
  32.         if (argc != 2) {
  33.                 printf("Usage: %s <filename>\n", argv[0]);
  34.                 return 1;
  35.         }
  36.  
  37.         ctx.buflen = css__parse_filesize(argv[1]);
  38.         if (ctx.buflen == 0)
  39.                 return 1;
  40.  
  41.         ctx.buf = malloc(ctx.buflen);
  42.         if (ctx.buf == NULL) {
  43.                 printf("Failed allocating %u bytes\n",
  44.                                 (unsigned int) ctx.buflen);
  45.                 return 1;
  46.         }
  47.  
  48.         ctx.buf[0] = '\0';
  49.         ctx.bufused = 0;
  50.         ctx.explen = 0;
  51.         ctx.indata = false;
  52.         ctx.inexp = false;
  53.  
  54.         assert(css__parse_testfile(argv[1], handle_line, &ctx) == true);
  55.  
  56.         /* and run final test */
  57.         if (ctx.bufused > 0)
  58.                 run_test(ctx.buf, ctx.bufused - 1, ctx.exp, ctx.explen);
  59.  
  60.         free(ctx.buf);
  61.  
  62.         printf("PASS\n");
  63.  
  64.         return 0;
  65. }
  66.  
  67. bool handle_line(const char *data, size_t datalen, void *pw)
  68. {
  69.         line_ctx *ctx = (line_ctx *) pw;
  70.  
  71.         if (data[0] == '#') {
  72.                 if (ctx->inexp) {
  73.                         /* This marks end of testcase, so run it */
  74.  
  75.                         run_test(ctx->buf, ctx->bufused - 1,
  76.                                         ctx->exp, ctx->explen);
  77.  
  78.                         ctx->buf[0] = '\0';
  79.                         ctx->bufused = 0;
  80.  
  81.                         ctx->explen = 0;
  82.                 }
  83.  
  84.                 if (ctx->indata && strncasecmp(data+1, "expected", 8) == 0) {
  85.                         ctx->indata = false;
  86.                         ctx->inexp = true;
  87.                 } else if (!ctx->indata) {
  88.                         ctx->indata = (strncasecmp(data+1, "data", 4) == 0);
  89.                         ctx->inexp  = (strncasecmp(data+1, "expected", 8) == 0);
  90.                 } else {
  91.                         memcpy(ctx->buf + ctx->bufused, data, datalen);
  92.                         ctx->bufused += datalen;
  93.                 }
  94.         } else {
  95.                 if (ctx->indata) {
  96.                         memcpy(ctx->buf + ctx->bufused, data, datalen);
  97.                         ctx->bufused += datalen;
  98.                 }
  99.                 if (ctx->inexp) {
  100.                         if (data[datalen - 1] == '\n')
  101.                                 datalen -= 1;
  102.  
  103.                         memcpy(ctx->exp, data, datalen);
  104.                         ctx->explen = datalen;
  105.                 }
  106.         }
  107.  
  108.         return true;
  109. }
  110.  
  111. void run_test(const uint8_t *data, size_t len, const char *exp, size_t explen)
  112. {
  113.         lwc_string *in;
  114.         size_t consumed;
  115.         css_fixed result;
  116.         char buf[256];
  117.  
  118.         UNUSED(exp);
  119.         UNUSED(explen);
  120.        
  121.         assert(lwc_intern_string((const char *)data, len, &in) == lwc_error_ok);
  122.        
  123.         result = css__number_from_lwc_string(in, false, &consumed);
  124.  
  125.         print_css_fixed(buf, sizeof(buf), result);
  126.  
  127.         printf("got: %s expected: %.*s\n", buf, (int) explen, exp);
  128.  
  129.         assert(strncmp(buf, exp, explen) == 0);
  130.  
  131.         lwc_string_unref(in);
  132. }
  133.  
  134. void print_css_fixed(char *buf, size_t len, css_fixed f)
  135. {
  136. #define ABS(x) (uint32_t)((x) < 0 ? -(x) : (x))
  137.         uint32_t uintpart = FIXTOINT(ABS(f));
  138.         /* + 500 to ensure round to nearest (division will truncate) */
  139.         uint32_t fracpart = ((ABS(f) & 0x3ff) * 1000 + 500) / (1 << 10);
  140. #undef ABS
  141.         size_t flen = 0;
  142.         char tmp[20];
  143.         size_t tlen = 0;
  144.  
  145.         if (len == 0)
  146.                 return;
  147.  
  148.         if (f < 0) {
  149.                 buf[0] = '-';
  150.                 buf++;
  151.                 len--;
  152.         }
  153.  
  154.         do {
  155.                 tmp[tlen] = "0123456789"[uintpart % 10];
  156.                 tlen++;
  157.  
  158.                 uintpart /= 10;
  159.         } while (tlen < 20 && uintpart != 0);
  160.  
  161.         while (len > 0 && tlen > 0) {
  162.                 buf[0] = tmp[--tlen];
  163.                 buf++;
  164.                 len--;
  165.         }
  166.  
  167.         if (len > 0) {
  168.                 buf[0] = '.';
  169.                 buf++;
  170.                 len--;
  171.         }
  172.  
  173.         do {
  174.                 tmp[tlen] = "0123456789"[fracpart % 10];
  175.                 tlen++;
  176.  
  177.                 fracpart /= 10;
  178.         } while (tlen < 20 && fracpart != 0);
  179.  
  180.         while (len > 0 && tlen > 0) {
  181.                 buf[0] = tmp[--tlen];
  182.                 buf++;
  183.                 len--;
  184.                 flen++;
  185.         }
  186.  
  187.         while (len > 0 && flen < 3) {
  188.                 buf[0] = '0';
  189.                 buf++;
  190.                 len--;
  191.                 flen++;
  192.         }
  193.  
  194.         if (len > 0) {
  195.                 buf[0] = '\0';
  196.                 buf++;
  197.                 len--;
  198.         }
  199. }
  200.  
  201.