/* Reads typing data from allChars.txt and allDigraphs.txt. * * Produces monographs and digraphs involving backspace by assuming that all * characters are equally mistyped. */ void initTypingData() { uint64_t i; FILE *file; file = fopen("allDigraphs.txt", "r"); if( file == NULL ) { internalError( 7 ); return; } if( digraphs == NULL ) { digraphs = createTable(); if( digraphs == NULL ) { return; } } if( monographs == NULL ) { monographs = createTable(); if( monographs == NULL ) { return; } } char key1; char key2; Value value; int c = '\0'; i = 0; totalDi = 0; while (TRUE) { /* Skip any extra newlines. */ while ((c = getc(file)) == '\n') ; if (c == EOF) break; if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In digraph file, unknown escape character \\%c.\n", c); fclose(file); return; } key1 = c; c = getc(file); if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In digraph file, unknown escape character \\%c.\n", c); fclose(file); return; } key2 = c; c = getc(file); /* Skip the space between the digraph and the value. */ if (strchr(keysToInclude, key1) && strchr(keysToInclude, key2)) { value = 0; while ((c = getc(file)) != EOF && c >= '0' && c <= '9') { value *= 10; value += c - '0'; } value /= DIVISOR; totalDi += value; char keys[3] = { key1, key2, '\0' }; includeKeyInTable( keys, value, digraphs ); } /* Skip all extra characters. */ while (c != EOF && c != '\n') c = getc(file); } fclose(file); file = fopen("allChars.txt", "r"); if( file == NULL ) { internalError( 8 ); return; } c = '\0'; i = 0; totalMon = 0; while (TRUE) { /* Skip any extra newlines. */ while ((c = getc(file)) == '\n') ; if (c == EOF) break; if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In monograph file, unknown escape character \\%c.\n", c); return; } key1 = c; c = getc(file); /* Skip the space between the char and the value. */ if (strchr(keysToInclude, key1)) { value = 0; while ((c = getc(file)) != EOF && c >= '0' && c <= '9') { value *= 10; value += c - '0'; } value /= DIVISOR; totalMon += value; char keys[2] = { key1, '\0' }; includeKeyInTable( keys, value, monographs ); } /* Skip all extra characters. */ while (c != EOF && c != '\n') c = getc(file); } fclose(file); /* If necessary, add the stats for backspace. */ if (strchr(keysToInclude, '\b')) { const uint64_t used = monographs->kvt_used; KeystrokeValue *theTable = monographs->kvt_table; KeystrokeValue kv; Value theValue; Keystroke theStroke; char theStrokeToAdd[3] = { '\0', '\0', '\0' }; char theKey; /* Add backpace to the digraph list. */ for (i = 0; i < used; ++i) { kv = theTable[i]; theValue = kv.theValue; theStroke = kv.theStroke; theKey = theStroke[0]; value = theValue * ERROR_RATE_PERCENT / 100; theStrokeToAdd[0] = '\b'; theStrokeToAdd[1] = theKey; includeKeyInTable(theStrokeToAdd, value, digraphs); theStrokeToAdd[0] = theKey; theStrokeToAdd[1] = '\b'; includeKeyInTable(theStrokeToAdd, value, digraphs); } /* Add backspace to the monograph list. */ theStrokeToAdd[0] = '\b'; theStrokeToAdd[1] = '\0'; value = totalMon * ERROR_RATE_PERCENT / 100; includeKeyInTable(theStrokeToAdd, value, monographs); } sortTable(digraphs, kvComparingValues); sortTable(monographs, kvComparingValues); }
/* Reads typing data from allChars.txt and allDigraphs.txt. * * Produces monographs and digraphs involving backspace by assuming that all * characters are equally mistyped. */ void initTypingData() { int i; FILE *file; file = fopen("allDigraphs.txt", "r"); char c = '\0'; i = 0; totalDi = 0; diLen = 0; while (TRUE) { /* Skip any extra newlines. */ while ((c = getc(file)) == '\n') ; if (c == EOF) break; if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In digraph file, unknown escape character \\%c.\n", c); return; } diKeys[i][0] = c; c = getc(file); if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In digraph file, unknown escape character \\%c.\n", c); return; } diKeys[i][1] = c; c = getc(file); /* Skip the space between the digraph and the value. */ if (strchr(keysToInclude, diKeys[i][0]) && strchr(keysToInclude, diKeys[i][1])) { diValues[i] = 0; while ((c = getc(file)) != EOF && c >= '0' && c <= '9') { diValues[i] *= 10; diValues[i] += c - '0'; } diValues[i] /= DIVISOR; totalDi += diValues[i++]; if (i >= MAX_DI_LEN) break; } /* Skip all extra characters. */ while (c != EOF && c != '\n') c = getc(file); } diLen = i; fclose(file); file = fopen("allChars.txt", "r"); c = '\0'; totalMon = 0; monLen = 0; for (i = 0; i < MAX_MON_LEN; ) { /* Skip any extra newlines. */ while ((c = getc(file)) == '\n') ; if (c == EOF) break; if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In monograph file, unknown escape character \\%c.\n", c); return; } monKeys[i] = c; c = getc(file); /* Skip the space between the char and the value. */ if (strchr(keysToInclude, monKeys[i])) { monValues[i] = 0; while ((c = getc(file)) != EOF && c >= '0' && c <= '9') { monValues[i] *= 10; monValues[i] += c - '0'; } monValues[i] /= DIVISOR; totalMon += monValues[i]; ++i; } /* Skip all extra characters. */ while (c != EOF && c != '\n') c = getc(file); } monLen = i; fclose(file); /* If necessary, add the stats for backspace. */ if (strchr(keysToInclude, '\b')) { /* Add backpace to the digraph list. */ for (i = 0; i < monLen; ++i) { diKeys[diLen][0] = '\b'; diKeys[diLen][1] = monKeys[i]; diValues[diLen] = monValues[i] * ERROR_RATE_PERCENT / 100; ++diLen; diKeys[diLen][1] = '\b'; diKeys[diLen][0] = monKeys[i]; diValues[diLen] = monValues[i] * ERROR_RATE_PERCENT / 100; ++diLen; } /* Add backspace to the monograph list. */ monKeys[monLen] = '\b'; monValues[monLen] = totalMon * ERROR_RATE_PERCENT / 100; ++monLen; } sortDigraphs(diKeys, diValues, 0, diLen - 1); sortMonographs(monKeys, monValues, 0, monLen - 1); }
/* Reads typing data from allChars.txt and allDigraphs.txt. * * Produces monographs and digraphs involving backspace by assuming that all * characters are equally mistyped. */ int initTypingData() { int i; FILE *file = fopen(DIGRAPH_FILE, "r"); CHECK_FILE_FOR_NULL(file, DIGRAPH_FILE); int c = '\0'; i = 0; totalDi = 0; diLen = 0; while (TRUE) { /* Skip any extra newlines. */ while ((c = getc(file)) == '\n') ; if (c == EOF) break; if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In file %s, unknown escape character \\%c.\n", DIGRAPH_FILE, c); fclose(file); return 1; } digraphs[i].key[0] = c; c = getc(file); if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In file %s, unknown escape character \\%c.\n", DIGRAPH_FILE, c); fclose(file); return 1; } digraphs[i].key[1] = c; c = getc(file); /* Skip the space between the digraph and the value. */ if (strchr(keysToInclude, digraphs[i].key[0]) && strchr(keysToInclude, digraphs[i].key[1])) { digraphs[i].value = 0; while ((c = getc(file)) != EOF && c >= '0' && c <= '9') { digraphs[i].value *= 10; digraphs[i].value += c - '0'; } digraphs[i].value /= DIVISOR; totalDi += digraphs[i++].value; if (i >= DI_LEN_MAX) break; } /* Skip all extra characters. */ while (c != EOF && c != '\n') c = getc(file); } diLen = i; fclose(file); if (diLen == 0) fprintf(stderr, "Warning: In file %s, no digraphs found.\n", DIGRAPH_FILE); file = fopen(MONOGRAPHFILE, "r"); CHECK_FILE_FOR_NULL(file, MONOGRAPHFILE); initVariables(); c = '\0'; totalMon = 0; monLen = 0; for (i = 0; i < MON_LEN_MAX; ) { /* Skip any extra newlines. */ while ((c = getc(file)) == '\n') ; if (c == EOF) break; if (c == '\\') c = convertEscapeChar(getc(file)); if (c == 0) { fprintf(stderr, "Error: In file %s, unknown escape character \\%c.\n", MONOGRAPHFILE, c); fclose(file); return 1; } monographs[i].key = (char) c; c = getc(file); /* Skip the space between the char and the value. */ if (strchr(keysToInclude, monographs[i].key)) { monographs[i].value = 0; while ((c = getc(file)) != EOF && c >= '0' && c <= '9') { monographs[i].value *= 10; monographs[i].value += c - '0'; } monographs[i].value /= DIVISOR; totalMon += monographs[i].value; ++i; } /* Skip all extra characters. */ while (c != EOF && c != '\n') c = getc(file); } monLen = i; fclose(file); if (monLen == 0) fprintf(stderr, "Warning: In file %s, no monographs found.\n", MONOGRAPHFILE); /* If necessary, add the stats for backspace. */ if (strchr(keysToInclude, '\b')) { /* Add backpace to the digraph list. */ for (i = 0; i < monLen; ++i) { int64_t errorRate = monographs[i].value * ERROR_RATE_PERCENT / 100; digraphs[diLen].key[0] = '\b'; digraphs[diLen].key[1] = monographs[i].key; digraphs[diLen].value = errorRate; ++diLen; digraphs[diLen].key[0] = monographs[i].key; digraphs[diLen].key[1] = '\b'; digraphs[diLen].value = errorRate; ++diLen; } /* Add backspace to the monograph list. */ monographs[monLen].key = '\b'; monographs[monLen].value = totalMon * ERROR_RATE_PERCENT / 100; ++monLen; } qsort(monographs, monLen, sizeof(struct Monograph), &cmpMonographsByValue); qsort(digraphs, diLen, sizeof(struct Digraph), &cmpDigraphsByValue); return 0; }
FSM_BlockState FSM::transition(char c){ if(c == EOF && state != STATE_START && state != STATE_COMMENT && state != STATE_HALT_EOF && state != STATE_HALT_OUT_BRACE && state != STATE_HALT_SEMICOLON){ THROW_ERROR("Unexpected end of file"); } switch(state){ case STATE_START: if(isWhiteSpace(c)){ //Ignore whitespace. //Do nothing. state = STATE_START; } else if(isNumeric(c)){ //Start integer intVal = atoi(&c); state = STATE_HALT_INTEGER; } else { //Handle special characters switch(c){ case '+': state = STATE_HALT_PLUS; break; case '-': state = STATE_HALT_MINUS; break; case '*': state = STATE_HALT_MULT; break; case '/': state = STATE_HALT_DIVIDE; break; case '(': state = STATE_HALT_IN_PAREN; break; case ')': state = STATE_HALT_OUT_PAREN; break; case '{': state = STATE_HALT_IN_BRACE; break; case '}': state = STATE_HALT_OUT_BRACE; break; case '=': state = STATE_HALT_EQUALS; break; case '>': state = STATE_HALT_GT; break; case '<': state = STATE_HALT_LT; break; case '!': state = STATE_HALT_BANG; break; case ';': state = STATE_HALT_SEMICOLON; break; case ',': state = STATE_HALT_COMMA; break; case '\"': state = STATE_STRING_READ; break; case '|': state = STATE_OR; break; case '&': state = STATE_AND; break; case EOF: state = STATE_HALT_EOF; break; default: //Nothing special, must be an identifier if its valid. if(isAlpha(c)){ state = STATE_HALT_IDENTIFIER; currentString<<c; }else{ return FSM_BLOCK; } } } break; case STATE_HALT_INTEGER: if(isNumeric(c)){ //Continue reading the int. state = STATE_HALT_INTEGER; if(intVal > (INT_MAX - atoi(&c))/10){ THROW_ERROR("Constant too large!"); } intVal = 10*intVal + atoi(&c); } else if(isAlpha(c)) { state = STATE_FAIL; THROW_ERROR("Variable starting with numeric characters detected!!") } else { return FSM_BLOCK; } break; case STATE_HALT_IDENTIFIER: if(isAlpha(c) || isNumeric(c)){ currentString<<c; state = STATE_HALT_IDENTIFIER; }else{ return FSM_BLOCK; } break; case STATE_HALT_EQUALS: if(c == '='){ state = STATE_HALT_EQUIVALENCE; }else{ return FSM_BLOCK; } break; case STATE_HALT_GT: if(c == '='){ state = STATE_HALT_GTE; }else{ return FSM_BLOCK; } break; case STATE_HALT_LT: if(c == '='){ state = STATE_HALT_LTE; }else{ return FSM_BLOCK; } break; case STATE_HALT_BANG: if(c == '='){ state = STATE_HALT_NE; }else{ return FSM_BLOCK; } break; case STATE_HALT_DIVIDE: if(c == '/'){ state = STATE_COMMENT; }else if(c == '*'){ state = STATE_COMMENT_BLOCK; }else{ return FSM_BLOCK; } break; case STATE_COMMENT: //Keep reading and ignoring input untill a new line comes up. if(c == '\n' || c == EOF){ state = STATE_START; } break; case STATE_COMMENT_BLOCK: //Keep reading and ignoring input until a star comes up. if(c == '*' || c == EOF){ state = STATE_COMMENT_BLOCK_STAR; } break; case STATE_COMMENT_BLOCK_STAR: if(c == '/'){ state = STATE_START; }else{ state = STATE_COMMENT_BLOCK; } break; case STATE_STRING_READ: if(c == '\\'){ state = STATE_STRING_ESCAPE; }else if(c == '\"'){ state = STATE_HALT_STRING_FINISH; }else{ currentString<<c; } break; case STATE_STRING_ESCAPE: state = STATE_STRING_READ; currentString<<convertEscapeChar(c); break; case STATE_OR: if(c != '|'){ return FSM_BLOCK; } state = STATE_HALT_OR; break; case STATE_AND: if(c != '&'){ return FSM_BLOCK; } state = STATE_HALT_AND; break; //States which block on all input case STATE_HALT_SEMICOLON: case STATE_HALT_IN_PAREN: case STATE_HALT_OUT_PAREN: case STATE_HALT_IN_BRACE: case STATE_HALT_OUT_BRACE: case STATE_HALT_COMMA: case STATE_HALT_EQUIVALENCE: case STATE_HALT_GTE: case STATE_HALT_LTE: case STATE_HALT_NE: case STATE_HALT_MINUS: case STATE_HALT_MULT: case STATE_HALT_PLUS: case STATE_HALT_STRING_FINISH: case STATE_HALT_AND: case STATE_HALT_OR: case STATE_HALT_EOF: return FSM_BLOCK; default: THROW_ERROR("My tummy has got the rumblies!!"); }