Beispiel #1
0
Color SvgParser::GetColor(const String& text_) {
    String text = ToLower(text_);
    if(text == "none" || text.IsEmpty())
        return Null;
    else if(*text == '#') {
        const char *b = ~text + 1;
        while(*b && !IsXDigit(*b))
            b++;
        const char *s = b;
        while(IsXDigit(*s))
            s++;
        int col = ScanInt(b, NULL, 16);
        if(s - b <= 3) {
            col = (col & 0xf) | ((col & 0xf0) << 4) | ((col & 0xf00) << 8);
            col |= col << 4;
        }
        return Color((col >> 16) & 255, (col >> 8) & 255, col & 255);
    }
    else {
        try {
Beispiel #2
0
unsigned HexVal (int C)
/* Convert a hex digit into a value. The function will emit an error for
 * invalid hex digits.
 */
{
    if (!IsXDigit (C)) {
        Error ("Invalid hexadecimal digit: `%c'", C);
    }
    if (IsDigit (C)) {
        return C - '0';
    } else {
        return toupper (C) - 'A' + 10;
    }
}
Beispiel #3
0
static int GetEncodedChar (char* Buf, unsigned* IPtr, unsigned Size)
{
    char Decoded = 0;
    int Count;

    if (C == EOF) {
        return -1;
    } else if (C != '\\') {
        Decoded = C;
        NextChar ();
        goto Store;
    }
    NextChar (); /* consume '\\' */
    if (C == EOF) {
        return -1;
    } else if (IsODigit (C)) {
        Count = 3;
        do {
            Decoded = Decoded * 8 + DigitVal (C);
            NextChar ();
            --Count;
        } while (Count > 0 && C != EOF && IsODigit (C));
    } else if (C == 'x') {
        NextChar (); /* consume 'x' */
        Count = 2;
        while (Count > 0 && C != EOF && IsXDigit (C)) {
            Decoded = Decoded * 16 + DigitVal (C);
            NextChar ();
            --Count;
        }
    } else {
        switch (C) {
            case '"': case '\'': case '\\':
                        Decoded = C;        break;
            case 't':   Decoded = '\t';     break;
            case 'r':   Decoded = '\r';     break;
            case 'n':   Decoded = '\n';     break;
            default:    return -1;
        }
        NextChar ();
    }
Store:
    if (*IPtr < Size - 1) {
        Buf [(*IPtr)++] = Decoded;
    }
    Buf [*IPtr] = 0;
    return 0;
}
Beispiel #4
0
static int
try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
{
  const char *p;
  char c;
  int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  int dp = 0;
  int nyble = 4;
  int finsert = -1;
  int bits = 128;
  int deficit = 0;
  short dc[8];
  struct sockaddr_in6 *v6 = (struct sockaddr_in6*) addr;

  for (p = text; (c = *p); p++)
    if (IsXDigit(c))
    {
      if (nyble == 0)
        return HM_HOST;
      DigitParse(c);
      d[dp] |= c << (4 * --nyble);
    }
    else if (c == ':')
    {
      if (p > text && *(p - 1) == ':')
      {
        if (finsert >= 0)
          return HM_HOST;
        finsert = dp;
      }
      else
      {
        /* If there were less than 4 hex digits, e.g. :ABC: shift right
         * so we don't interpret it as ABC0 -A1kmm */
        d[dp] = d[dp] >> 4 * nyble;
        nyble = 4;
        if (++dp >= 8)
          return HM_HOST;
      }
    }
    else if (c == '*')
Beispiel #5
0
static int exec(FILE* fp, ENC_INFO* einfo)
{
#define NCOL  8

  int c, val, enc;

  enc = einfo->num;

  fprintf(fp, "static const unsigned short Enc%s_CtypeTable[256] = {\n",
	  einfo->name);

  for (c = 0; c < 256; c++) {
    val = 0;
    if (IsNewline(enc, c))  val |= BIT_CTYPE_NEWLINE;
    if (IsAlpha (enc, c))   val |= (BIT_CTYPE_ALPHA | BIT_CTYPE_ALNUM);
    if (IsBlank (enc, c))   val |= BIT_CTYPE_BLANK;
    if (IsCntrl (enc, c))   val |= BIT_CTYPE_CNTRL;
    if (IsDigit (enc, c))   val |= (BIT_CTYPE_DIGIT | BIT_CTYPE_ALNUM);
    if (IsGraph (enc, c))   val |= BIT_CTYPE_GRAPH;
    if (IsLower (enc, c))   val |= BIT_CTYPE_LOWER;
    if (IsPrint (enc, c))   val |= BIT_CTYPE_PRINT;
    if (IsPunct (enc, c))   val |= BIT_CTYPE_PUNCT;
    if (IsSpace (enc, c))   val |= BIT_CTYPE_SPACE;
    if (IsUpper (enc, c))   val |= BIT_CTYPE_UPPER;
    if (IsXDigit(enc, c))   val |= BIT_CTYPE_XDIGIT;
    if (IsWord  (enc, c))   val |= BIT_CTYPE_WORD;
    if (IsAscii (enc, c))   val |= BIT_CTYPE_ASCII;

    if (c % NCOL == 0) fputs("  ", fp);
    fprintf(fp, "0x%04x", val);
    if (c != 255) fputs(",", fp);
    if (c != 0 && c % NCOL == (NCOL-1))
      fputs("\n", fp);
    else
      fputs(" ", fp);
  }
  fprintf(fp, "};\n");
  return 0;
}
Beispiel #6
0
static int ValidateType (StrBuf* Type)
/* Check if the given type is valid and if so, return a string id for it. If
** the type isn't valid, return -1. Type is overwritten when checking.
*/
{
    unsigned        I;
    const char*     A;
    char*           B;


    /* The length must not be zero and divideable by two */
    unsigned Length = SB_GetLen (Type);
    if (Length < 2 || (Length & 0x01) != 0) {
        ErrorSkip ("Type value has invalid length");
        return -1;
    }

    /* The string must consist completely of hex digit chars */
    A = SB_GetConstBuf (Type);
    for (I = 0; I < Length; ++I) {
        if (!IsXDigit (A[I])) {
            ErrorSkip ("Type value contains invalid characters");
            return -1;
        }
    }

    /* Convert the type to binary */
    B = SB_GetBuf (Type);
    while (A < SB_GetConstBuf (Type) + Length) {
        /* Since we know, there are only hex digits, there can't be any errors */
        *B++ = (HexValue (A[0]) << 4) | HexValue (A[1]);
        A += 2;
    }
    Type->Len = (Length /= 2);

    /* Allocate the type and return it */
    return GetStrBufId (Type);
}
Beispiel #7
0
void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown)
/* Read an assembler include file */
{
    char        Buf[1024];
    char*       L;
    const char* Comment;
    unsigned    Line;
    unsigned	Len;
    long        Val;
    unsigned    DVal;
    int         Sign;
    unsigned    Base;
    unsigned    Digits;
    StrBuf      Ident = STATIC_STRBUF_INITIALIZER;

    /* Try to open the file for reading */
    FILE* F = fopen (Filename, "r");
    if (F == 0) {
        Error ("Cannot open asm include file \"%s\": %s",
               Filename, strerror (errno));
    }

    /* Read line by line, check for NAME = VALUE lines */
    Line = 0;
    while ((L = fgets (Buf, sizeof (Buf), F)) != 0) {

        /* One more line read */
        ++Line;

        /* Ignore leading white space */
        while (IsBlank (*L)) {
            ++L;
        }

	/* Remove trailing whitespace */
	Len = strlen (L);
	while (Len > 0 && IsSpace (L[Len-1])) {
	    --Len;
	}
	L[Len] = '\0';

        /* If the line is empty or starts with a comment char, ignore it */
        if (*L == '\0' || *L == CommentStart) {
            continue;
        }

        /* Read an identifier */
        SB_Clear (&Ident);
        if (IsAlpha (*L) || *L == '_') {
            SB_AppendChar (&Ident, *L++);
            while (IsAlNum (*L) || *L == '_') {
                SB_AppendChar (&Ident, *L++);
            }
            SB_Terminate (&Ident);
        } else {
            if (!IgnoreUnknown) {
                Error ("%s(%u): Syntax error", Filename, Line);
            }
            continue;
        }

        /* Ignore white space */
        L = SkipWhitespace (L);

        /* Check for := or = */
        if (*L == '=') {
            ++L;
        } else if (*L == ':' && *++L == '=') {
            ++L;
        } else {
	    if (!IgnoreUnknown) {
	       	Error ("%s(%u): Missing `='", Filename, Line);
	    }
	    continue;
	}

        /* Allow white space once again */
        L = SkipWhitespace (L);

        /* A number follows. Read the sign. */
        if (*L == '-') {
            Sign = -1;
            ++L;
        } else {
            Sign = 1;
            if (*L == '+') {
                ++L;
            }
        }

        /* Determine the base of the number. Allow $ and % as prefixes for
         * hex and binary numbers respectively.
         */
        if (*L == '$') {
            Base = 16;
            ++L;
        } else if (*L == '%') {
            Base = 2;
            ++L;
        } else {
            Base = 10;
        }

        /* Decode the number */
        Digits = 0;
        Val = 0;
        while (IsXDigit (*L) && (DVal = DigitVal (*L)) < Base) {
            Val = (Val * Base) + DVal;
            ++Digits;
            ++L;
        }

        /* Must have at least one digit */
        if (Digits == 0) {
            if (!IgnoreUnknown) {
                Error ("%s(%u): Error in number format", Filename, Line);
            }
            continue;
        }

        /* Skip whitespace again */
        L = SkipWhitespace (L);

        /* Check for a comment */
        if (*L == CommentStart) {
            Comment = SkipWhitespace (L+1);
            if (*Comment == '\0') {
                Comment = 0;
            }
        } else {
            Comment = 0;
        }

        /* Check for a comment character or end of line */
        if (*L != CommentStart && *L != '\0') {
            if (!IgnoreUnknown) {
                Error ("%s(%u): Trailing garbage", Filename, Line);
            }
            continue;
        }

        /* Apply the sign */
        Val *= Sign;

        /* Define the symbol and the comment */
        AddExtLabel (Val, SB_GetConstBuf (&Ident));
        SetComment (Val, Comment);

    }

    /* Delete the string buffer contents */
    SB_Done (&Ident);

    /* Close the include file ignoring errors (we were just reading). */
    (void) fclose (F);
}
Beispiel #8
0
/* Fixed so ::/0 (any IPv6 address) is valid
   Also a bug in DigitParse above.
   -Gozem 2002-07-19 [email protected]
*/
static int
try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
{
  char c;
  int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  int dp = 0;
  int nyble = 4;
  int finsert = -1;
  int bits = 128;
  int deficit = 0;
  short dc[8];
  struct sockaddr_in6 *const v6 = (struct sockaddr_in6 *)addr;

  for (const char *p = text; (c = *p); ++p)
  {
    if (IsXDigit(c))
    {
      if (nyble == 0)
        return HM_HOST;
      DigitParse(c);
      d[dp] |= c << (4 * --nyble);
    }
    else if (c == ':')
    {
      if (p > text && *(p - 1) == ':')
      {
        if (finsert >= 0)
          return HM_HOST;
        finsert = dp;
      }
      else
      {
        /* If there were less than 4 hex digits, e.g. :ABC: shift right
         * so we don't interpret it as ABC0 -A1kmm */
        d[dp] = d[dp] >> 4 * nyble;
        nyble = 4;
        if (++dp >= 8)
          return HM_HOST;
      }
    }
    else if (c == '*')
    {
      /* * must be last, and * is ambiguous if there is a ::... -A1kmm */
      if (finsert >= 0 || *(p + 1) || dp == 0 || *(p - 1) != ':')
        return HM_HOST;
      bits = dp * 16;
    }
    else if (c == '/')
    {
      char *after;

      d[dp] = d[dp] >> 4 * nyble;
      ++dp;
      bits = strtoul(p + 1, &after, 10);

      if (bits < 0 || *after)
        return HM_HOST;
      if (bits > dp * 4 && !(finsert >= 0 && bits <= 128))
        return HM_HOST;
      break;
    }
Beispiel #9
0
void NextRawTok (void)
/* Read the next raw token from the input stream */
{
    Macro* M;

    /* If we've a forced end of assembly, don't read further */
    if (ForcedEnd) {
        CurTok.Tok = TOK_EOF;
        return;
    }

Restart:
    /* Check if we have tokens from another input source */
    if (InputFromStack ()) {
        if (CurTok.Tok == TOK_IDENT && (M = FindDefine (&CurTok.SVal)) != 0) {
            /* This is a define style macro - expand it */
            MacExpandStart (M);
            goto Restart;
        }
        return;
    }

Again:
    /* Skip whitespace, remember if we had some */
    if ((CurTok.WS = IsBlank (C)) != 0) {
        do {
            NextChar ();
        } while (IsBlank (C));
    }

    /* Mark the file position of the next token */
    Source->Func->MarkStart (Source);

    /* Clear the string attribute */
    SB_Clear (&CurTok.SVal);

    /* Generate line info for the current token */
    NewAsmLine ();

    /* Hex number or PC symbol? */
    if (C == '$') {
        NextChar ();

        /* Hex digit must follow or DollarIsPC must be enabled */
        if (!IsXDigit (C)) {
            if (DollarIsPC) {
                CurTok.Tok = TOK_PC;
                return;
            } else {
                Error ("Hexadecimal digit expected");
            }
        }

        /* Read the number */
        CurTok.IVal = 0;
        while (1) {
            if (UnderlineInNumbers && C == '_') {
                while (C == '_') {
                    NextChar ();
                }
                if (!IsXDigit (C)) {
                    Error ("Number may not end with underline");
                }
            }
            if (IsXDigit (C)) {
                if (CurTok.IVal & 0xF0000000) {
                    Error ("Overflow in hexadecimal number");
                    CurTok.IVal = 0;
                }
                CurTok.IVal = (CurTok.IVal << 4) + DigitVal (C);
                NextChar ();
            } else {
                break;
            }
        }

        /* This is an integer constant */
        CurTok.Tok = TOK_INTCON;
        return;
    }

    /* Binary number? */
    if (C == '%') {
        NextChar ();

        /* 0 or 1 must follow */
        if (!IsBDigit (C)) {
            Error ("Binary digit expected");
        }

        /* Read the number */
        CurTok.IVal = 0;
        while (1) {
            if (UnderlineInNumbers && C == '_') {
                while (C == '_') {
                    NextChar ();
                }
                if (!IsBDigit (C)) {
                    Error ("Number may not end with underline");
                }
            }
            if (IsBDigit (C)) {
                if (CurTok.IVal & 0x80000000) {
                    Error ("Overflow in binary number");
                    CurTok.IVal = 0;
                }
                CurTok.IVal = (CurTok.IVal << 1) + DigitVal (C);
                NextChar ();
            } else {
                break;
            }
        }

        /* This is an integer constant */
        CurTok.Tok = TOK_INTCON;
        return;
    }

    /* Number? */
    if (IsDigit (C)) {

        char Buf[16];
        unsigned Digits;
        unsigned Base;
        unsigned I;
        long     Max;
        unsigned DVal;

        /* Ignore leading zeros */
        while (C == '0') {
            NextChar ();
        }

        /* Read the number into Buf counting the digits */
        Digits = 0;
        while (1) {
            if (UnderlineInNumbers && C == '_') {
                while (C == '_') {
                    NextChar ();
                }
                if (!IsXDigit (C)) {
                    Error ("Number may not end with underline");
                }
            }
            if (IsXDigit (C)) {
                /* Buf is big enough to allow any decimal and hex number to
                ** overflow, so ignore excess digits here, they will be detected
                ** when we convert the value.
                */
                if (Digits < sizeof (Buf)) {
                    Buf[Digits++] = C;
                }
                NextChar ();
            } else {
                break;
            }
        }

        /* Allow zilog/intel style hex numbers with a 'h' suffix */
        if (C == 'h' || C == 'H') {
            NextChar ();
            Base = 16;
            Max  = 0xFFFFFFFFUL / 16;
        } else {
            Base = 10;
            Max  = 0xFFFFFFFFUL / 10;
        }

        /* Convert the number using the given base */
        CurTok.IVal = 0;
        for (I = 0; I < Digits; ++I) {
            if (CurTok.IVal > Max) {
                Error ("Number out of range");
                CurTok.IVal = 0;
                break;
            }
            DVal = DigitVal (Buf[I]);
            if (DVal >= Base) {
                Error ("Invalid digits in number");
                CurTok.IVal = 0;
                break;
            }
            CurTok.IVal = (CurTok.IVal * Base) + DVal;
        }

        /* This is an integer constant */
        CurTok.Tok = TOK_INTCON;
        return;
    }

    /* Control command? */
    if (C == '.') {

        /* Remember and skip the dot */
        NextChar ();

        /* Check if it's just a dot */
        if (!IsIdStart (C)) {

            /* Just a dot */
            CurTok.Tok = TOK_DOT;

        } else {

            /* Read the remainder of the identifier */
            SB_AppendChar (&CurTok.SVal, '.');
            ReadIdent ();

            /* Dot keyword, search for it */
            CurTok.Tok = FindDotKeyword ();
            if (CurTok.Tok == TOK_NONE) {

                /* Not found */
                if (!LeadingDotInIdents) {
                    /* Invalid pseudo instruction */
                    Error ("'%m%p' is not a recognized control command", &CurTok.SVal);
                    goto Again;
                }

                /* An identifier with a dot. Check if it's a define style
                ** macro.
                */
                if ((M = FindDefine (&CurTok.SVal)) != 0) {
                    /* This is a define style macro - expand it */
                    MacExpandStart (M);
                    goto Restart;
                }

                /* Just an identifier with a dot */
                CurTok.Tok = TOK_IDENT;
            }

        }
        return;
    }

    /* Indirect op for sweet16 cpu. Must check this before checking for local
    ** symbols, because these may also use the '@' symbol.
    */
    if (CPU == CPU_SWEET16 && C == '@') {
        NextChar ();
        CurTok.Tok = TOK_AT;
        return;
    }

    /* Local symbol? */
    if (C == LocalStart) {

        /* Read the identifier. */
        ReadIdent ();

        /* Start character alone is not enough */
        if (SB_GetLen (&CurTok.SVal) == 1) {
            Error ("Invalid cheap local symbol");
            goto Again;
        }

        /* A local identifier */
        CurTok.Tok = TOK_LOCAL_IDENT;
        return;
    }


    /* Identifier or keyword? */
    if (IsIdStart (C)) {

        /* Read the identifier */
        ReadIdent ();

        /* Check for special names. Bail out if we have identified the type of
        ** the token. Go on if the token is an identifier.
        */
        switch (SB_GetLen (&CurTok.SVal)) {
            case 1:
                switch (toupper (SB_AtUnchecked (&CurTok.SVal, 0))) {

                    case 'A':
                        if (C == ':') {
                            NextChar ();
                            CurTok.Tok = TOK_OVERRIDE_ABS;
                        } else {
                            CurTok.Tok = TOK_A;
                        }
                        return;

                    case 'F':
                        if (C == ':') {
                            NextChar ();
                            CurTok.Tok = TOK_OVERRIDE_FAR;
                            return;
                        }
                        break;

                    case 'S':
                        if ((CPU == CPU_4510) || (CPU == CPU_65816)) {
                            CurTok.Tok = TOK_S;
                            return;
                        }
                        break;

                    case 'X':
                        CurTok.Tok = TOK_X;
                        return;

                    case 'Y':
                        CurTok.Tok = TOK_Y;
                        return;

                    case 'Z':
                        if (C == ':') {
                            NextChar ();
                            CurTok.Tok = TOK_OVERRIDE_ZP;
                           return;
                        } else {
                            if (CPU == CPU_4510) {
                                CurTok.Tok = TOK_Z;
                                return;
                            }
                        }
                        break;

                    default:
                        break;
                }
                break;
            case 2:
                if ((CPU == CPU_4510) &&
                    (toupper (SB_AtUnchecked (&CurTok.SVal, 0)) == 'S') &&
                    (toupper (SB_AtUnchecked (&CurTok.SVal, 1)) == 'P')) {

                    CurTok.Tok = TOK_S;
                    return;
                }
                /* FALL THROUGH */
            default:
                if (CPU == CPU_SWEET16 &&
                   (CurTok.IVal = Sweet16Reg (&CurTok.SVal)) >= 0) {

                    /* A sweet16 register number in sweet16 mode */
                    CurTok.Tok = TOK_REG;
                    return;
                }
        }

        /* Check for define style macro */
        if ((M = FindDefine (&CurTok.SVal)) != 0) {
            /* Macro - expand it */
            MacExpandStart (M);
            goto Restart;
        } else {
            /* An identifier */
            CurTok.Tok = TOK_IDENT;
        }
        return;
    }

    /* Ok, let's do the switch */
CharAgain:
    switch (C) {

        case '+':
            NextChar ();
            CurTok.Tok = TOK_PLUS;
            return;

        case '-':
            NextChar ();
            CurTok.Tok = TOK_MINUS;
            return;

        case '/':
            NextChar ();
            if (C != '*') {
                CurTok.Tok = TOK_DIV;
            } else if (CComments) {
                /* Remember the position, then skip the '*' */
                Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
                GetFullLineInfo (&LineInfos);
                NextChar ();
                do {
                    while (C !=  '*') {
                        if (C == EOF) {
                            LIError (&LineInfos, "Unterminated comment");
                            ReleaseFullLineInfo (&LineInfos);
                            DoneCollection (&LineInfos);
                            goto CharAgain;
                        }
                        NextChar ();
                    }
                    NextChar ();
                } while (C != '/');
                NextChar ();
                ReleaseFullLineInfo (&LineInfos);
                DoneCollection (&LineInfos);
                goto Again;
            }
            return;

        case '*':
            NextChar ();
            CurTok.Tok = TOK_MUL;
            return;

        case '^':
            NextChar ();
            CurTok.Tok = TOK_XOR;
            return;

        case '&':
            NextChar ();
            if (C == '&') {
                NextChar ();
                CurTok.Tok = TOK_BOOLAND;
            } else {
                CurTok.Tok = TOK_AND;
            }
            return;

        case '|':
            NextChar ();
            if (C == '|') {
                NextChar ();
                CurTok.Tok = TOK_BOOLOR;
            } else {
                CurTok.Tok = TOK_OR;
            }
            return;

        case ':':
            NextChar ();
            switch (C) {

                case ':':
                    NextChar ();
                    CurTok.Tok = TOK_NAMESPACE;
                    break;

                case '-':
                    CurTok.IVal = 0;
                    do {
                        --CurTok.IVal;
                        NextChar ();
                    } while (C == '-');
                    CurTok.Tok = TOK_ULABEL;
                    break;

                case '+':
                    CurTok.IVal = 0;
                    do {
                        ++CurTok.IVal;
                        NextChar ();
                    } while (C == '+');
                    CurTok.Tok = TOK_ULABEL;
                    break;

                case '=':
                    NextChar ();
                    CurTok.Tok = TOK_ASSIGN;
                    break;

                default:
                    CurTok.Tok = TOK_COLON;
                    break;
            }
            return;

        case ',':
            NextChar ();
            CurTok.Tok = TOK_COMMA;
            return;

        case ';':
            NextChar ();
            while (C != '\n' && C != EOF) {
                NextChar ();
            }
            goto CharAgain;

        case '#':
            NextChar ();
            CurTok.Tok = TOK_HASH;
            return;

        case '(':
            NextChar ();
            CurTok.Tok = TOK_LPAREN;
            return;

        case ')':
            NextChar ();
            CurTok.Tok = TOK_RPAREN;
            return;

        case '[':
            NextChar ();
            CurTok.Tok = TOK_LBRACK;
            return;

        case ']':
            NextChar ();
            CurTok.Tok = TOK_RBRACK;
            return;

        case '{':
            NextChar ();
            CurTok.Tok = TOK_LCURLY;
            return;

        case '}':
            NextChar ();
            CurTok.Tok = TOK_RCURLY;
            return;

        case '<':
            NextChar ();
            if (C == '=') {
                NextChar ();
                CurTok.Tok = TOK_LE;
            } else if (C == '<') {
                NextChar ();
                CurTok.Tok = TOK_SHL;
            } else if (C == '>') {
                NextChar ();
                CurTok.Tok = TOK_NE;
            } else {
                CurTok.Tok = TOK_LT;
            }
            return;

        case '=':
            NextChar ();
            CurTok.Tok = TOK_EQ;
            return;

        case '!':
            NextChar ();
            CurTok.Tok = TOK_BOOLNOT;
            return;

        case '>':
            NextChar ();
            if (C == '=') {
                NextChar ();
                CurTok.Tok = TOK_GE;
            } else if (C == '>') {
                NextChar ();
                CurTok.Tok = TOK_SHR;
            } else {
                CurTok.Tok = TOK_GT;
            }
            return;

        case '~':
            NextChar ();
            CurTok.Tok = TOK_NOT;
            return;

        case '\'':
            /* Hack: If we allow ' as terminating character for strings, read
            ** the following stuff as a string, and check for a one character
            ** string later.
            */
            if (LooseStringTerm) {
                ReadStringConst ('\'');
                if (SB_GetLen (&CurTok.SVal) == 1) {
                    CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0);
                    CurTok.Tok = TOK_CHARCON;
                } else {
                    CurTok.Tok = TOK_STRCON;
                }
            } else {
                /* Always a character constant */
                NextChar ();
                if (C == EOF || IsControl (C)) {
                    Error ("Illegal character constant");
                    goto CharAgain;
                }
                CurTok.IVal = C;
                CurTok.Tok = TOK_CHARCON;
                NextChar ();
                if (C != '\'') {
                    if (!MissingCharTerm) {
                        Error ("Illegal character constant");
                    }
                } else {
                    NextChar ();
                }
            }
            return;

        case '\"':
            ReadStringConst ('\"');
            CurTok.Tok = TOK_STRCON;
            return;

        case '\\':
            /* Line continuation? */
            if (LineCont) {
                NextChar ();
                /* Next char should be a LF, if not, will result in an error later */
                if (C == '\n') {
                    /* Ignore the '\n' */
                    NextChar ();
                    goto Again;
                } else {
                    /* Make it clear what the problem is: */
                    Error ("EOL expected.");
                }
            }
            break;

        case '\n':
            NextChar ();
            CurTok.Tok = TOK_SEP;
            return;

        case EOF:
            CheckInputStack ();
            /* In case of the main file, do not close it, but return EOF. */
            if (Source && Source->Next) {
                DoneCharSource ();
                goto Again;
            } else {
                CurTok.Tok = TOK_EOF;
            }
            return;
    }

    /* If we go here, we could not identify the current character. Skip it
    ** and try again.
    */
    Error ("Invalid input character: 0x%02X", C & 0xFF);
    NextChar ();
    goto Again;
}
Beispiel #10
0
static void ReadStringConst (int StringTerm)
/* Read a string constant into SVal. */
{
    /* Skip the leading string terminator */
    NextChar ();

    /* Read the string */
    while (1) {
        if (C == StringTerm) {
            break;
        }
        if (C == '\n' || C == EOF) {
            Error ("Newline in string constant");
            break;
        }

        if (C == '\\' && StringEscapes) {
            NextChar ();

            switch (C) {
                case EOF:
                    Error ("Unterminated escape sequence in string constant");
                    break;
                case '\\':
                case '\'':
                case '"':
                    break;
                case 't':
                    C = '\x09';
                    break;
                case 'r':
                    C = '\x0D';
                    break;
                case 'n':
                    C = '\x0A';
                    break;
                case 'x':
                    NextChar ();
                    if (IsXDigit (C)) {
                        char high_nibble = DigitVal (C) << 4;
                        NextChar ();
                        if (IsXDigit (C)) {
                            C = high_nibble | DigitVal (C);
                            break;
                        }
                    }
                    /* otherwise, fall through */
                default:
                    Error ("Unsupported escape sequence in string constant");
                    break;
            }
        }

        /* Append the char to the string */
        SB_AppendChar (&CurTok.SVal, C);

        /* Skip the character */
        NextChar ();
    }

    /* Skip the trailing terminator */
    NextChar ();

    /* Terminate the string */
    SB_Terminate (&CurTok.SVal);
}
Beispiel #11
0
static void NumericConst (void)
/* Parse a numeric constant */
{
    unsigned Base;              /* Temporary number base */
    unsigned Prefix;            /* Base according to prefix */
    StrBuf   S = STATIC_STRBUF_INITIALIZER;
    int      IsFloat;
    char     C;
    unsigned DigitVal;
    unsigned long IVal;         /* Value */

    /* Check for a leading hex or octal prefix and determine the possible
    ** integer types.
    */
    if (CurC == '0') {
        /* Gobble 0 and examine next char */
        NextChar ();
        if (toupper (CurC) == 'X') {
            Base = Prefix = 16;
            NextChar ();        /* gobble "x" */
        } else {
            Base = 10;          /* Assume 10 for now - see below */
            Prefix = 8;         /* Actual prefix says octal */
        }
    } else {
        Base  = Prefix = 10;
    }

    /* Because floating point numbers don't have octal prefixes (a number
    ** with a leading zero is decimal), we first have to read the number
    ** before converting it, so we can determine if it's a float or an
    ** integer.
    */
    while (IsXDigit (CurC) && HexVal (CurC) < Base) {
        SB_AppendChar (&S, CurC);
        NextChar ();
    }
    SB_Terminate (&S);

    /* The following character tells us if we have an integer or floating
    ** point constant. Note: Hexadecimal floating point constants aren't
    ** supported in C89.
    */
    IsFloat = (CurC == '.' ||
               (Base == 10 && toupper (CurC) == 'E') ||
               (Base == 16 && toupper (CurC) == 'P' && IS_Get (&Standard) >= STD_C99));

    /* If we don't have a floating point type, an octal prefix results in an
    ** octal base.
    */
    if (!IsFloat && Prefix == 8) {
        Base = 8;
    }

    /* Since we do now know the correct base, convert the remembered input
    ** into a number.
    */
    SB_Reset (&S);
    IVal = 0;
    while ((C = SB_Get (&S)) != '\0') {
        DigitVal = HexVal (C);
        if (DigitVal >= Base) {
            Error ("Numeric constant contains digits beyond the radix");
        }
        IVal = (IVal * Base) + DigitVal;
    }

    /* We don't need the string buffer any longer */
    SB_Done (&S);

    /* Distinguish between integer and floating point constants */
    if (!IsFloat) {

        unsigned Types;
        int      HaveSuffix;

        /* Check for a suffix and determine the possible types */
        HaveSuffix = 1;
        if (toupper (CurC) == 'U') {
            /* Unsigned type */
            NextChar ();
            if (toupper (CurC) != 'L') {
                Types = IT_UINT | IT_ULONG;
            } else {
                NextChar ();
                Types = IT_ULONG;
            }
        } else if (toupper (CurC) == 'L') {
            /* Long type */
            NextChar ();
            if (toupper (CurC) != 'U') {
                Types = IT_LONG | IT_ULONG;
            } else {
                NextChar ();
                Types = IT_ULONG;
            }
        } else {
            HaveSuffix = 0;
            if (Prefix == 10) {
                /* Decimal constants are of any type but uint */
                Types = IT_INT | IT_LONG | IT_ULONG;
            } else {
                /* Octal or hex constants are of any type */
                Types = IT_INT | IT_UINT | IT_LONG | IT_ULONG;
            }
        }

        /* Check the range to determine the type */
        if (IVal > 0x7FFF) {
            /* Out of range for int */
            Types &= ~IT_INT;
            /* If the value is in the range 0x8000..0xFFFF, unsigned int is not
            ** allowed, and we don't have a type specifying suffix, emit a
            ** warning, because the constant is of type long.
            */
            if (IVal <= 0xFFFF && (Types & IT_UINT) == 0 && !HaveSuffix) {
                Warning ("Constant is long");
            }
        }
        if (IVal > 0xFFFF) {
            /* Out of range for unsigned int */
            Types &= ~IT_UINT;
        }
        if (IVal > 0x7FFFFFFF) {
            /* Out of range for long int */
            Types &= ~IT_LONG;
        }

        /* Now set the type string to the smallest type in types */
        if (Types & IT_INT) {
            NextTok.Type = type_int;
        } else if (Types & IT_UINT) {
            NextTok.Type = type_uint;
        } else if (Types & IT_LONG) {
            NextTok.Type = type_long;
        } else {
            NextTok.Type = type_ulong;
        }

        /* Set the value and the token */
        NextTok.IVal = IVal;
        NextTok.Tok  = TOK_ICONST;

    } else {

        /* Float constant */
        Double FVal = FP_D_FromInt (IVal);      /* Convert to double */

        /* Check for a fractional part and read it */
        if (CurC == '.') {

            Double Scale;

            /* Skip the dot */
            NextChar ();

            /* Read fractional digits */
            Scale  = FP_D_Make (1.0);
            while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
                /* Get the value of this digit */
                Double FracVal = FP_D_Div (FP_D_FromInt (DigitVal * Base), Scale);
                /* Add it to the float value */
                FVal = FP_D_Add (FVal, FracVal);
                /* Scale base */
                Scale = FP_D_Mul (Scale, FP_D_FromInt (DigitVal));
                /* Skip the digit */
                NextChar ();
            }
        }

        /* Check for an exponent and read it */
        if ((Base == 16 && toupper (CurC) == 'F') ||
            (Base == 10 && toupper (CurC) == 'E')) {

            unsigned Digits;
            unsigned Exp;

            /* Skip the exponent notifier */
            NextChar ();

            /* Read an optional sign */
            if (CurC == '-') {
                NextChar ();
            } else if (CurC == '+') {
                NextChar ();
            }

            /* Read exponent digits. Since we support only 32 bit floats
            ** with a maximum exponent of +-/127, we read the exponent
            ** part as integer with up to 3 digits and drop the remainder.
            ** This avoids an overflow of Exp. The exponent is always
            ** decimal, even for hex float consts.
            */
            Digits = 0;
            Exp    = 0;
            while (IsDigit (CurC)) {
                if (++Digits <= 3) {
                    Exp = Exp * 10 + HexVal (CurC);
                }
                NextChar ();
            }

            /* Check for errors: We must have exponent digits, and not more
            ** than three.
            */
            if (Digits == 0) {
                Error ("Floating constant exponent has no digits");
            } else if (Digits > 3) {
                Warning ("Floating constant exponent is too large");
            }

            /* Scale the exponent and adjust the value accordingly */
            if (Exp) {
                FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp)));
            }
        }

        /* Check for a suffix and determine the type of the constant */
        if (toupper (CurC) == 'F') {
            NextChar ();
            NextTok.Type = type_float;
        } else {
            NextTok.Type = type_double;
        }

        /* Set the value and the token */
        NextTok.FVal = FVal;
        NextTok.Tok  = TOK_FCONST;

    }
}
Beispiel #12
0
static int ParseChar (void)
/* Parse a character. Converts escape chars into character codes. */
{
    int C;
    int HadError;
    int Count;

    /* Check for escape chars */
    if (CurC == '\\') {
        NextChar ();
        switch (CurC) {
            case '?':
                C = '\?';
                break;
            case 'a':
                C = '\a';
                break;
            case 'b':
                C = '\b';
                break;
            case 'f':
                C = '\f';
                break;
            case 'r':
                C = '\r';
                break;
            case 'n':
                C = '\n';
                break;
            case 't':
                C = '\t';
                break;
            case 'v':
                C = '\v';
                break;
            case '\"':
                C = '\"';
                break;
            case '\'':
                C = '\'';
                break;
            case '\\':
                C = '\\';
                break;
            case 'x':
            case 'X':
                /* Hex character constant */
                if (!IsXDigit (NextC)) {
                    Error ("\\x used with no following hex digits");
                    C = ' ';
                } else {
                    HadError = 0;
                    C = 0;
                    while (IsXDigit (NextC)) {
                        if ((C << 4) >= 256) {
                            if (!HadError) {
                                Error ("Hex character constant out of range");
                                HadError = 1;
                            }
                        } else {
                            C = (C << 4) | HexVal (NextC);
                        }
                        NextChar ();
                    }
                }
                break;
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
                /* Octal constant */
                Count = 1;
                C = HexVal (CurC);
                while (IsODigit (NextC) && Count++ < 3) {
                    C = (C << 3) | HexVal (NextC);
                    NextChar ();
                }
                if (C >= 256)
                    Error ("Octal character constant out of range");
                break;
            default:
                C = CurC;
                Error ("Illegal escaped character: 0x%02X", CurC);
                break;
        }
    } else {
        C = CurC;
    }

    /* Skip the character read */
    NextChar ();

    /* Do correct sign extension */
    return SignExtendChar (C);
}
Beispiel #13
0
void InfoNextTok (void)
/* Read the next token from the input stream */
{
    unsigned I;
    char DecodeBuf [2];

Again:
    /* Skip whitespace */
    SkipBlanks (0);

    /* Remember the current position */
    InfoErrorLine = InputLine;
    InfoErrorCol  = InputCol;

    /* Identifier? */
    if (C == '_' || IsAlpha (C)) {

        /* Read the identifier */
        I = 0;
        while (C == '_' || IsAlNum (C)) {
            if (I < CFG_MAX_IDENT_LEN) {
                InfoSVal [I++] = C;
            }
            NextChar ();
        }
        InfoSVal [I] = '\0';
        InfoTok = INFOTOK_IDENT;
        return;
    }

    /* Hex number? */
    if (C == '$') {
        NextChar ();
        if (!IsXDigit (C)) {
            InfoError ("Hex digit expected");
        }
        InfoIVal = 0;
        while (IsXDigit (C)) {
            InfoIVal = InfoIVal * 16 + DigitVal (C);
            NextChar ();
        }
        InfoTok = INFOTOK_INTCON;
        return;
    }

    /* Decimal number? */
    if (IsDigit (C)) {
        InfoIVal = GetDecimalToken ();
        InfoTok = INFOTOK_INTCON;
        return;
    }

    /* Other characters */
    switch (C) {

        case '{':
            NextChar ();
            InfoTok = INFOTOK_LCURLY;
            break;

        case '}':
            NextChar ();
            InfoTok = INFOTOK_RCURLY;
            break;

        case ';':
            NextChar ();
            InfoTok = INFOTOK_SEMI;
            break;

        case '.':
            NextChar ();
            InfoTok = INFOTOK_DOT;
            break;

        case ',':
            NextChar ();
            InfoTok = INFOTOK_COMMA;
            break;

        case '=':
            NextChar ();
            InfoTok = INFOTOK_EQ;
            break;

        case ':':
            NextChar ();
            InfoTok = INFOTOK_COLON;
            break;

        case '\"':
            NextChar ();
            I = 0;
            InfoSVal[0] = '\0';
            while (C != EOF && C != '\"') {
                if (GetEncodedChar (InfoSVal, &I, sizeof InfoSVal) < 0) {
                    if (C == EOF) {
                        InfoError ("Unterminated string");
                    } else  {
                        InfoError ("Invalid escape char: %c", C);
                    }
                }
            }
            if (C != '\"') {
                InfoError ("Unterminated string");
            }
            NextChar ();
            InfoTok = INFOTOK_STRCON;
            break;

        case '\'':
            NextChar ();
            if (C == EOF || IsControl (C) || C == '\'') {
                InfoError ("Invalid character constant");
            }
            if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0 || I != 1) {
                InfoError ("Invalid character constant");
            }
            InfoIVal = DecodeBuf [0];
            if (C != '\'') {
                InfoError ("Unterminated character constant");
            }
            NextChar ();
            InfoTok = INFOTOK_CHARCON;
            break;

        case '#':
            /* # lineno "sourcefile" or # comment */
            if (SyncLines && InputCol == 1) {
                LineMarkerOrComment ();
            } else {
                do {
                    NextChar ();
                } while (C != EOF && C != '\n');
                NextChar ();
            }
            if (C != EOF) {
                goto Again;
            }
            InfoTok = INFOTOK_EOF;
            break;

        case '/':
            /* C++ style comment */
            NextChar ();
            if (C != '/') {
                InfoError ("Invalid token '/'");
            }
            do {
                NextChar ();
            } while (C != '\n' && C != EOF);
            if (C != EOF) {
                goto Again;
            }
            InfoTok = INFOTOK_EOF;
            break;

        case EOF:
            InfoTok = INFOTOK_EOF;
            break;

        default:
            InfoError ("Invalid character '%c'", C);

    }
}
Beispiel #14
0
int SB_GetNumber (StrBuf* B, long* Val)
/* Get a number from the string buffer. Accepted formats are decimal, octal,
** hex and character constants. Numeric constants may be preceeded by a
** minus or plus sign. The function returns 1 if a number was found and
** zero otherwise. Errors are only output for invalid numbers.
*/
{
    int      Sign;
    char     C;
    unsigned Base;
    unsigned DigitVal;


    /* Initialize Val */
    *Val = 0;

    /* Handle character constants */
    if (SB_Peek (B) == '\'') {

        /* Character constant */
        SB_Skip (B);
        *Val = SignExtendChar (TgtTranslateChar (ParseChar (B)));
        if (SB_Peek (B) != '\'') {
            Error ("`\'' expected");
            return 0;
        } else {
            /* Skip the quote */
            SB_Skip (B);
            return 1;
        }
    }

    /* Check for a sign. A sign must be followed by a digit, otherwise it's
    ** not a number
    */
    Sign = 1;
    switch (SB_Peek (B)) {
        case '-':
            Sign = -1;
            /* FALLTHROUGH */
        case '+':
            if (!IsDigit (SB_LookAt (B, SB_GetIndex (B) + 1))) {
                return 0;
            }
            SB_Skip (B);
            break;
    }

    /* We must have a digit now, otherwise its not a number */
    C = SB_Peek (B);
    if (!IsDigit (C)) {
        return 0;
    }

    /* Determine the base */
    if (C == '0') {
        /* Hex or octal */
        SB_Skip (B);
        if (tolower (SB_Peek (B)) == 'x') {
            SB_Skip (B);
            Base = 16;
            if (!IsXDigit (SB_Peek (B))) {
                Error ("Invalid hexadecimal number");
                return 0;
            }
        } else {
            Base = 8;
        }
    } else {
        Base = 10;
    }

    /* Read the number */
    while (IsXDigit (C = SB_Peek (B)) && (DigitVal = HexVal (C)) < Base) {
        *Val = (*Val * Base) + DigitVal;
        SB_Skip (B);
    }

    /* Allow optional 'U' and 'L' modifiers */
    C = SB_Peek (B);
    if (C == 'u' || C == 'U') {
        SB_Skip (B);
        C = SB_Peek (B);
        if (C == 'l' || C == 'L') {
            SB_Skip (B);
        }
    } else if (C == 'l' || C == 'L') {
        SB_Skip (B);
        C = SB_Peek (B);
        if (C == 'u' || C == 'U') {
            SB_Skip (B);
        }
    }

    /* Success, value read is in Val */
    *Val *= Sign;
    return 1;
}