Пример #1
0
Файл: tok.c Проект: 8l/myrddin
static uint32_t readutf(char c, char **buf, size_t *buflen, size_t *sz) {
    size_t i, len;
    uint32_t val;

    if ((c & 0x80) == 0)
        len = 1;
    else if ((c & 0xe0) == 0xc0)
        len = 2;
    else if ((c & 0xf0) == 0xe0)
        len = 3;
    else if ((c & 0xf8) == 0xf0)
        len = 4;
    else
        lfatal(curloc, "Invalid utf8 encoded character constant");

    val = c & ((1 << (8 - len)) - 1);
    append(buf, buflen, sz, c);
    for (i = 1; i < len; i++) {
        c = next();
        if ((c & 0xc0) != 0x80)
            lfatal(curloc, "Invalid utf8 codepoint in character literal");
        val = (val << 6) | (c & 0x3f);
        append(buf, buflen, sz, c);
    }
    return val;
}
Пример #2
0
Файл: tok.c Проект: 8l/myrddin
static Tok *charlit(void)
{
    Tok *t;
    int c;
    uint32_t val;
    size_t len, sz;
    char *buf;


    assert(next() == '\'');

    buf = NULL;
    len = 0;
    sz = 0;
    val = 0;
    c = next();
    if (c == End)
        lfatal(curloc, "Unexpected EOF within char lit");
    else if (c == '\n')
        lfatal(curloc, "Newlines not allowed in char lit");
    else if (c == '\\')
        val = decode(&buf, &len, &sz);
    else
        val = readutf(c, &buf, &len, &sz);
    append(&buf, &len, &sz, '\0');
    if (next() != '\'')
        lfatal(curloc, "Character constant with multiple characters");

    t = mktok(Tchrlit);
    t->chrval = val;
    t->id = buf;
    return t;
}
Пример #3
0
Файл: tok.c Проект: 8l/myrddin
/*
 * decodes an escape code. These are
 * shared between strings and characters.
 * Unknown escape codes are ignored.
 */
static int decode(char **buf, size_t *len, size_t *sz)
{
    char c, c1, c2;
    int32_t v;

    c = next();
    /* we've already seen the '\' */
    switch (c) {
        case 'u':
            v = unichar();
            appendc(buf, len, sz, v);
            return v;
        case 'x': /* arbitrary hex */
            c1 = next();
            if (!isxdigit(c1))
                lfatal(curloc, "expected hex digit, got %c", c1);
            c2 = next();
            if (!isxdigit(c2))
                lfatal(curloc, "expected hex digit, got %c", c1);
            v = 16*hexval(c1) + hexval(c2);
            break;
        case 'n': v = '\n'; break;
        case 'r': v = '\r'; break;
        case 't': v = '\t'; break;
        case 'b': v = '\b'; break;
        case '"': v = '\"'; break;
        case '\'': v = '\''; break;
        case 'v': v = '\v'; break;
        case '\\': v = '\\'; break;
        case '0': v = '\0'; break;
        default: lfatal(curloc, "unknown escape code \\%c", c);
    }
    append(buf, len, sz, v);
    return v;
}
Пример #4
0
Файл: tok.c Проект: 8l/myrddin
static Tok *strlit(void)
{
    Tok *t;
    int c;
    size_t len, sz;
    char *buf;

    assert(next() == '"');

    buf = NULL;
    len = 0;
    sz = 0;
    while (1) {
        c = next();
        /* we don't unescape here, but on output */
        if (c == '"')
            break;
        else if (c == End)
            lfatal(curloc, "Unexpected EOF within string");
        else if (c == '\n')
            lfatal(curloc, "Newlines not allowed in strings");
        else if (c == '\\')
            decode(&buf, &len, &sz);
        else
            append(&buf, &len, &sz, c);
    };
    t = mktok(Tstrlit);
    t->strval.len = len;

    /* null terminator should not count towards length */
    append(&buf, &len, &sz, '\0');
    t->strval.buf = buf;
    t->id = buf;
    return t;
}
// ######################################################################
void env_stdio_write_gray(const struct env_image* iimage,
                          const char* outstem, const char* name, int c)
{
        if (!env_img_initialized(iimage))
                return;

        // if outstem is the empty string, then the user wanted us to
        // suppress output:
        if (outstem[0] == '\0')
                return;

        char fname[256];
        snprintf(fname, sizeof(fname),
                 "%s-%s%06d.pnm", outstem, name, c);

        FILE* const f = fopen(fname, "wb");
        if (f == 0)
                lfatal("%s: couldn't open PNM file for writing (errno=%d, %s)",
                       fname, errno, strerror(errno));

        //REV: so they are P5 (binary, greyscale), dim * dim images, with max value 255.
        if (fprintf(f, "P5\n%d %d\n255\n",
                    (int) iimage->dims.w, (int) iimage->dims.h) < 0)
                lfatal("%s: fprintf() failed (errno=%d, %s)",
                       fname, errno, strerror(errno));

        const intg32* const src = env_img_pixels(iimage);
        const env_size_t sz = env_img_size(iimage);
        byte* bimage =
                (byte*) env_allocate(sz * sizeof(byte));

        for (env_size_t i = 0; i < sz; ++i)
        {
                // the caller is supposed to have already ensured that
                // the intg32 image has been downsampled to a [0,255]
                // range, so let's verify that:
                ENV_ASSERT(src[i] >= 0 && src[i] <= 255);
                bimage[i] = (byte) src[i];
        }
        
        //REV: they aren't using any newlines!
        if (fwrite(bimage, 1, sz, f) != sz)
        {
                env_deallocate(bimage);
                lfatal("%s: fwrite() failed (errno=%d, %s)",
                       fname, errno, strerror(errno));
        }

        env_deallocate(bimage);

        if (fclose(f) != 0)
                lfatal("%s: fclose() failed (errno=%d, %s)",
                       fname, errno, strerror(errno));
}
Пример #6
0
Файл: tok.c Проект: 8l/myrddin
static void eatcomment(void)
{
    int depth;
    int startln;
    int c;

    depth = 0;
    startln = curloc.line;
    while (1) {
        c = next();
        switch (c) {
            /* enter level of nesting */
            case '/':
                if (match('*'))
                    depth++;
                break;
            /* leave level of nesting */
            case '*':
                if (match('/'))
                    depth--;
                break;
            /* have to keep line numbers synced */
            case '\n':
                curloc.line++;
                break;
            case End:
                lfatal(curloc, "File ended within comment starting at line %d", startln);
                break;
        }
        if (depth == 0)
            break;
    }
}
Пример #7
0
Файл: tok.c Проект: 8l/myrddin
static Tok *toknext()
{
    Tok *t;
    int c;

    eatspace();
    c = peek();
    if (c == End) {
        t =  mktok(0);
    } else if (c == '\n') {
        curloc.line++;
        next();
        t =  mktok(Tendln);
    } else if (isalpha(c) || c == '_' || c == '$') {
        t =  kwident();
    } else if (c == '"') {
        t =  strlit();
    } else if (c == '\'') {
        t = charlit();
    } else if (isdigit(c)) {
        t =  numlit();
    } else if (c == '@') {
        t = typaram();
    } else {
        t = oper();
    }

    if (!t || t->type == Terror)
        lfatal(curloc, "Unable to parse token starting with %c", c);
    return t;
}
Пример #8
0
Файл: tok.c Проект: 8l/myrddin
/* \u{abc} */
static int32_t unichar(void)
{
    uint32_t v;
    int c;

    /* we've already seen the \u */
    if (next() != '{')
        lfatal(curloc, "\\u escape sequence without initial '{'");
    v = 0;
    while (ishexval(peek())) {
        c = next();
        v = 16*v + hexval(c);
        if (v > 0x10FFFF)
            lfatal(curloc, "invalid codepoint for \\u escape sequence");
    }
    if (next() != '}')
        lfatal(curloc, "\\u escape sequence without ending '}'");
    return v;
}
Пример #9
0
Файл: tok.c Проект: 8l/myrddin
/*
 * Converts a character to its hex value.
 */
static int hexval(char c)
{
    if (c >= 'a' && c <= 'f')
        return c - 'a' + 10;
    else if (c >= 'A' && c <= 'F')
        return c - 'A' + 10;
    else if (c >= '0' && c <= '9')
        return c - '0';
    lfatal(curloc, "passed non-hex value '%c' to where hex was expected", c);
    return -1;
}
Пример #10
0
Файл: use.c Проект: 8l/myrddin
static void fixtypemappings(Stab *st)
{
    size_t i;
    Type *t, *old;


    /*
     * merge duplicate definitions.
     * This allows us to compare named types by id, instead
     * of doing a deep walk through the type. This ability is
     * depended on when we do type inference.
     */
    for (i = 0; i < ntypefixdest; i++) {
        t = htget(tidmap, itop(typefixid[i]));
        if (!t)
            die("Unable to find type for id %zd\n", typefixid[i]);
        *typefixdest[i] = t;
    }
    for (i = 0; i < ntypefixdest; i++) {
        old = *typefixdest[i];
        if (old->type == Tyname || old->type == Tygeneric) {
            t = htget(tydedup, old);
            if (!t) {
                t = old;
                htput(tydedup, old, old);
            }
            *typefixdest[i] = t;
        }
    }

    /* check for duplicate type definitions */
    for (i = 0; i < ntypefixdest; i++) {
        t = htget(tidmap, itop(typefixid[i]));
        if ((t->type != Tyname && t->type != Tygeneric) || t->issynth)
            continue;
        old = htget(tydedup, t);
        if (old && !tyeq(t, old) && !isspecialization(t, old))
            lfatal(t->loc, "Duplicate definition of type %s on %s:%d", tystr(old), file->file.files[old->loc.file], old->loc.line);
    }
    for (i = 0; i < ntypefixdest; i++) 
    lfree(&typefixdest, &ntypefixdest);
    lfree(&typefixid, &ntypefixid);
}
Пример #11
0
Файл: tok.c Проект: 8l/myrddin
/*
 * Appends a unicode codepoint 'c' to a growable buffer 'buf',
 * resizing if needed.
 */
static void appendc(char **buf, size_t *len, size_t *sz, uint32_t c)
{
    size_t i, charlen;
    char charbuf[5] = {0};

    if (c < 0x80)
        charlen = 1;
    else if (c < 0x800)
        charlen = 2;
    else if (c < 0x10000)
        charlen = 3;
    else if (c < 0x200000)
        charlen = 4;
    else
        lfatal(curloc, "invalid utf character '\\u{%x}'", c);

    encode(charbuf, charlen, c);
    for (i = 0; i < charlen; i++)
         append(buf, len, sz, charbuf[i]);
}
Пример #12
0
Файл: tok.c Проект: 8l/myrddin
static Tok *number(int base)
{
    Tok *t;
    int start;
    int c;
    int isfloat;
    int unsignedval;
    /* because we allow '_' in numbers, and strtod/stroull don't, we
     * need a buffer that holds the number without '_'.
     */
    char buf[2048];
    size_t nbuf;

    t = NULL;
    isfloat = 0;
    start = fidx;
    nbuf = 0;
    for (c = peek(); isxdigit(c) || c == '.' || c == '_'; c = peek()) {
        next();
        if (c == '_')
            continue;
        if (c == '.')
            isfloat = 1;
        else if (hexval(c) < 0 || hexval(c) > base)
            lfatal(curloc, "Integer digit '%c' outside of base %d", c, base);
        if (nbuf >= sizeof buf - 1) {
            buf[nbuf-1] = '\0';
            lfatal(curloc, "number %s... too long to represent", buf);
        }
        buf[nbuf++] = c;
    }
    buf[nbuf] = '\0';

    /* we only support base 10 floats */
    if (isfloat && base == 10) {
        t = mktok(Tfloatlit);
        t->id = strdupn(&fbuf[start], fidx - start);
        t->fltval = strtod(buf, NULL);
    } else {
        t = mktok(Tintlit);
        t->id = strdupn(&fbuf[start], fidx - start);
        t->intval = strtoull(buf, NULL, base);
        /* check suffixes:
         *   u -> unsigned
         *   l -> 64 bit
         *   i -> 32 bit
         *   w -> 16 bit
         *   b -> 8 bit
         */
        unsignedval = 0;
nextsuffix:
        switch (peek()) {
            case 'u':
                if (unsignedval == 1)
                    lfatal(curloc, "Duplicate 'u' integer specifier");
                next();
                unsignedval = 1;
                goto nextsuffix;
            case 'l':
                next();
                if (unsignedval)
                    t->inttype = Tyuint64;
                else
                    t->inttype = Tyint64;
                break;
            case 'i':
                next();
                if (unsignedval)
                    t->inttype = Tyuint32;
                else
                    t->inttype = Tyint32;
                break;
            case 's':
                next();
                if (unsignedval)
                    t->inttype = Tyuint16;
                else
                    t->inttype = Tyint16;
                break;
            case 'b':
                next();
                if (unsignedval)
                    t->inttype = Tyuint8;
                else
                    t->inttype = Tyint8;
                break;
            default:
                if (unsignedval)
                    lfatal(curloc, "Unrecognized character int type specifier after 'u'");
                break;
        }
    }

    return t;
}
Пример #13
0
Файл: tok.c Проект: 8l/myrddin
static Tok *oper(void)
{
    int tt;
    char c;

    c = next();
    switch (c) {
        case '{': tt = Tobrace; break;
        case '}': tt = Tcbrace; break;
        case '(': tt = Toparen; break;
        case ')': tt = Tcparen; break;
        case '[': tt = Tosqbrac; break;
        case ']': tt = Tcsqbrac; break;
        case ',': tt = Tcomma; break;
        case '`': tt = Ttick; break;
        case '#': tt = Tderef; break;
        case ':':
                  if (match(':'))
                      tt = Twith;
                  else
                      tt = Tcolon;
                  break;
        case '~': tt = Tbnot; break;
        case ';':
                  if (match(';'))
                      tt = Tendblk;
                  else
                      tt = Tendln;
                  break;
        case '.':
                  if (match('.')) {
                      if (match('.')) {
                          tt = Tellipsis;
                      } else {
                          unget();
                          tt = Tdot;
                      }
                  } else {
                      tt = Tdot;
                  }
                  break;
        case '+':
                  if (match('='))
                      tt = Taddeq;
                  else if (match('+'))
                      tt = Tinc;
                  else
                      tt = Tplus;
                  break;
        case '-':
                  if (match('='))
                      tt = Tsubeq;
                  else if (match('-'))
                      tt = Tdec;
                  else if (match('>'))
                      tt = Tret;
                  else
                      tt = Tminus;
                  break;
        case '*':
                  if (match('='))
                      tt = Tmuleq;
                  else
                      tt = Tmul;
                  break;
        case '/':
                  if (match('='))
                      tt = Tdiveq;
                  else
                      tt = Tdiv;
                  break;
        case '%':
                  if (match('='))
                      tt = Tmodeq;
                  else
                      tt = Tmod;
                  break;
        case '=':
                  if (match('='))
                      tt = Teq;
                  else
                      tt = Tasn;
                  break;
        case '|':
                  if (match('='))
                      tt = Tboreq;
                  else if (match('|'))
                      tt = Tlor;
                  else
                      tt = Tbor;
                  break;
        case '&':
                  if (match('='))
                      tt = Tbandeq;
                  else if (match('&'))
                      tt = Tland;
                  else
                      tt = Tband;
                  break;
        case '^':
                  if (match('='))
                      tt = Tbxoreq;
                  else
                      tt = Tbxor;
                  break;
        case '<':
                  if (match('=')) {
                      tt = Tle;
                  } else if (match('<')) {
                      if (match('='))
                          tt = Tbsleq;
                      else
                          tt = Tbsl;
                  } else {
                      tt = Tlt;
                  }
                  break;
        case '>':
                  if (match('=')) {
                      tt = Tge;
                  } else if (match('>')) {
                      if (match('='))
                          tt = Tbsreq;
                      else
                          tt = Tbsr;
                  } else {
                      tt = Tgt;
                  }
                  break;

        case '!':
                  if (match('='))
                      tt = Tne;
                  else
                      tt = Tlnot;
                  break;
        default:
                  tt = Terror;
                  lfatal(curloc, "Junk character %c", c);
                  break;
    }
    return mktok(tt);
}
// ######################################################################
struct env_rgb_pixel* env_stdio_parse_rgb(const char* fname,
                                          struct env_dims* outdims)
{
        FILE* f = fopen(fname, "rb");

        if (f == 0)
                lfatal("Couldn't open file '%s' for reading.", fname);

        int c = getc(f);
        if (c != 'P')
                lfatal("Missing magic number in pnm file '%s'"
                       "(got '%c' [%d], expected '%c' [%d]).",
                       fname, c, c, 'P', 'P');

        int mode = -1;
        int ret = fscanf(f, "%d", &mode);
        if (ret > 0 && mode != 6)
                lfatal("Wrong pnm mode (got 'P%d', expected 'P6')", //REV: so they expect P6, i.e. binary rgb!
                       mode);

        while (1)
        {
                const int c = getc(f); //REV: they're getting one char at a time...removing all spaces...
                if (!isspace(c))
                { ungetc(c, f); break; }
        }

        // copy and concatenate optional comment line(s) starting with '#'
        // into comments string
        //REV: they're removing comments and such...we won't need to worry about this...

        while (1)
        {
                const int c = getc(f);
                if (c != '#')
                { ungetc(c, f); break; }
                else
                {
                        while (getc(f) != '\n')
                        { /* empty loop */ }
                }
        }

        int w = -1;
        int h = -1;
        int maxGrey = -1;
        ret = fscanf(f, "%d %d %d", &w, &h, &maxGrey); //REV: they get the dimensions... and the max grey value (wth?)
        ENV_ASSERT(ret > 0);
        ENV_ASSERT(w > 0);
        ENV_ASSERT(h > 0);
        ENV_ASSERT(maxGrey > 0);

        // read one more character of whitespace from the stream after maxGrey
        c = getc(f);
        if ( !isspace(c) )
                lfatal("Missing whitespace after maxGrey in pbm file '%s'.", fname);

        struct env_rgb_pixel* result = (struct env_rgb_pixel*) //REV: note RGB pixel is byte[3].
                env_allocate(w * h * sizeof(struct env_rgb_pixel));
        if (fread((char*) result, 3, w*h, f) != ((env_size_t)(w*h)))
                lfatal("%s: fread() failed", fname);
        outdims->w = w;
        outdims->h = h;
        return result;
}