/* * Read an octal value in a field of the specified width, with optional * spaces on both sides of the number and with an optional null character * at the end. Returns -1 on an illegal format. */ static long getOctal(const char * cp, int len) { long val; while ((len > 0) && (*cp == ' ')) { cp++; len--; } if ((len == 0) || !isOctal(*cp)) return -1; val = 0; while ((len > 0) && isOctal(*cp)) { val = val * 8 + *cp++ - '0'; len--; } while ((len > 0) && (*cp == ' ')) { cp++; len--; } if ((len > 0) && *cp) return -1; return val; }
static int readChar(FILE *fp) { int c= getc(fp); if ('\\' == c) { c= getc(fp); switch (c) { case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; case '\'': return '\''; case '"': return '"'; case '\\': return '\\'; case 'u': { int a= getc(fp), b= getc(fp), c= getc(fp), d= getc(fp); return (digitValue(a) << 24) + (digitValue(b) << 16) + (digitValue(c) << 8) + digitValue(d); } case 'x': { int x= 0; while (isHexadecimal(c= getc(fp))) x= x * 16 + digitValue(c); ungetc(c, fp); return x; } case '0' ... '7': { int x= 0; if (isOctal(c= getc(fp))) { x= x * 8 + digitValue(c); if (isOctal(c= getc(fp))) { x= x * 8 + digitValue(c); if (isOctal(c= getc(fp))) { x= x * 8 + digitValue(c); c= getc(fp); } } } ungetc(c, fp); return x; } default: fprintf(stderr, "illegal character escape: \\%c", c); exit(1); break; } }
parsing_result_type_t getInt(xmlNode * node, char * name, int * value, int required) { char * text = (char *)xmlGetProp(node, (unsigned char *)name); if(text != NULL) { if(isOctal(text)) { printf("error: constants with leading zeros are disallowed as they are parsed as octal\n"); return PARSING_ERROR; } errno = 0; *value = strtol(text, NULL, 0); return !errno; } else { if(required) { printf("can't find %s\n", name); } else { *value = 0; return PARSING_OKAY; } } return PARSING_ERROR; }
TokenT *_octal(TokenizerT *tk) { nextChar(tk); if(isOctal(tk->inputIter[0])) { return _octal(tk); } else { return makeToken(tk, "octal integer"); } }
//Checks for further octal numbers enum FSMState FSMState_3 (TokenizerT *tok) { if (isOctal(*tok->current) == 1) return State_3; else { tok->tokType = Octal; return EndState; } }
/* * Handle being given a zero as the first char in a new token. */ TokenT *_zero(TokenizerT *tk) { nextChar(tk); if(isOctal(tk->inputIter[0])) { return _octal(tk); } else if(tk->inputIter[0] == 'x' || (tk->inputIter[0]) == 'X') { return _hex(tk, 1); } else if(tk->inputIter[0] == '.') { return _float(tk, 1); } else { return makeToken(tk, "zero integer"); } }
//Checks next character following a 0 character and sets state accordingly enum FSMState FSMState_1 (TokenizerT *tok) { if(isOctal(*tok->current) == 1) return State_3; else if (*tok->current == 'x' || *tok->current == 'X') return State_4; else if (*tok->current == '.') return State_5; else { tok->tokType = Zero; return EndState; } }
/* Will take in both numbers to validate that the numbers are entered correctly. * Will run the numbers to other functions based on the type specified by user. * Returns a 1 if number entered is found to be an invalid format.*/ int validateToken(char* num) { char tempType; char* tempNum; if (num[0] == '-' && strlen(num) <= 2) { //to have a negative sign means you must have at least a '-', a type (b,o,x,d) return 1; // and at least one digit. } else if (num[0] == '-') { tempType = num[1]; tempNum = strdup(&num[2]); } else if (strlen(num) <= 1) { //string must contain a type and at least one digit return 1; } else { tempType = num[0]; tempNum = strdup(&num[1]); } if (tempType == 'b' || tempType == 'B') //determination of type and whether number entered is valid. { return isBinary(tempNum); } else if (tempType == 'o'|| tempType == 'O') { return isOctal(tempNum); } else if (tempType == 'x' || tempType == 'X') { return isHex(tempNum); } else if (tempType == 'd' || tempType == 'D') { curr_State = mightBeDecFirstNum; return isDecimal(tempNum); } curr_State = undetermined; free(tempNum); return 1; }
parsing_result_type_t parseDevice(xmlNode * node, CONTEXT * ctx) { char * position_str; int dev_name_okay; int dev_revid_okay; int dev_type_name_okay; int joinOkay; ctx->device = calloc(1, sizeof(EC_DEVICE)); EC_DEVICE * ctdev = ctx->device; ctdev->position = -1; getStr(node, "position", &position_str); // if position string starts with DCS then lookup its actual position on the bus if (position_str[0] == 'D' && position_str[1] == 'C' && position_str[2] == 'S') { int dcs; if (sscanf(position_str, "DCS%08d", &dcs) != 1) { fprintf(stderr, "Can't parse DCS number '%s'\n", position_str); exit(1); } ELLNODE * lnode = ellFirst(&ctx->config->dcs_lookups); int found_slave = 0; for(; lnode && !found_slave; lnode = ellNext(lnode)) { EC_DCS_LOOKUP * dcs_lookup = (EC_DCS_LOOKUP *)lnode; if (dcs == dcs_lookup->dcs) { found_slave = 1; ctdev->position = dcs_lookup->position; char *temp_position = format("%d", ctdev->position); xmlSetProp(node, (unsigned char *) "position", (unsigned char *) temp_position); free(temp_position); dcs_lookup->device = ctdev; } } } else { if(isOctal(position_str)) { fprintf(stderr, "error: constants with leading zeros are disallowed as they are parsed as octal\n"); exit(1); } ctdev->position = strtol(position_str, NULL, 0); ELLNODE * lnode = ellFirst(&ctx->config->dcs_lookups); int found_slave = 0; for(; lnode && !found_slave; lnode = ellNext(lnode)) { int found_slave = 0; EC_DCS_LOOKUP * dcs_lookup = (EC_DCS_LOOKUP *)lnode; if (ctdev->position == dcs_lookup->position) { found_slave = 1; dcs_lookup->device = ctdev; } } } if (ctdev->position == -1) { fprintf(stderr, "can't find '%s' on bus\n", position_str); exit(1); } dev_name_okay = getStr(node, "name", &ctdev->name); dev_type_name_okay = getStr(node, "type_name", &ctdev->type_name); dev_revid_okay = getInt(node, "revision", &ctdev->type_revid, 1); joinOkay = joinDevice(ctx->config, ctdev); printf("parseDevice: name %s type_name %s rev 0x%x\n", ctdev->name, ctdev->type_name, ctdev->type_revid); return dev_name_okay && dev_type_name_okay && dev_revid_okay && getInt(node, "oversample", &ctdev->oversampling_rate, 0) && joinOkay && parseSimspec(node, ctx) && ellAddOK(&ctx->config->devices, &ctdev->node); }
/****************************************************************************** purpose: code = 0, handles \char'35 or \char"35 or \char35 or \char`b code = 1, handles \symbol{\'22} or \symbol{\"22} ******************************************************************************/ void CmdSymbol(int code) { char c, *s, *t; int n, base; if (code == 0) { char num[4]; int i; c = getNonSpace(); base = identifyBase(c); if (base == 0) { diagnostics(1,"malformed \\char construction"); fprintRTF("%c",c); return; } if (base == -1) { c = getTexChar(); /* \char`b case */ CmdChar((int) c); return; } if (base == 10) ungetTexChar(c); /* read sequence of digits */ for (i=0; i<4; i++) { num[i] = getTexChar(); if (base == 10 && ! isdigit(num[i]) ) break; if (base == 8 && ! isOctal(num[i]) ) break; if (base == 16 && ! isHex (num[i]) ) break; } ungetTexChar(num[i]); num[i] = '\0'; n = (int) strtol(num,&s,base); CmdChar(n); } else { s = getBraceParam(); t = strdup_noendblanks(s); free(s); base = identifyBase(*t); if (base == 0) return; if (base == -1) { CmdChar((int) *(t+1)); /* \char`b case */ return; } n = (int) strtol(t+1,&s,base); CmdChar(n); free(t); } }