Something went wrong. Try again.
Reactos
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162/* * PROJECT: ReactOS Build Tools [Keyboard Layout Compiler] * LICENSE: BSD - See COPYING.BSD in the top level directory * FILE: tools/kbdtool/parser.c * PURPOSE: Parsing Logic * PROGRAMMERS: ReactOS Foundation */
/* INCLUDES *******************************************************************/
#include "kbdtool.h"
/* GLOBALS ********************************************************************/
/* Internal parser data about everything that was parsed */CHAR gBuf[256];CHAR gKBDName[10];CHAR gCopyright[256];CHAR gDescription[256];CHAR gCompany[256];CHAR gLocaleName[256];CHAR gVKeyName[32];ULONG gID = 0;ULONG gKbdLayoutVersion;LAYOUT g_Layout;ULONG gLineCount;
/* Table of keywords the parser recognizes */PCHAR KeyWordList[KEYWORD_COUNT] ={ "KBD", "VERSION", "COPYRIGHT", "COMPANY", "LOCALENAME", "MODIIFERS", "SHIFTSTATE", "ATTRIBUTES", "LAYOUT", "DEADKEY", "LIGATURE", "KEYNAME", "KEYNAME_EXT", "KEYNAME_DEAD", "DESCRIPTIONS", "LANGUAGENAMES", "ENDKBD",};
/* FUNCTIONS ******************************************************************/
ULONGisKeyWord(PCHAR p){ ULONG i;
/* Check if we know this keyword */ for (i = 0; i < KEYWORD_COUNT; i++) if (strcmp(KeyWordList[i], p) == 0) break;
/* If we didn't find anything, i will be KEYWORD_COUNT, which is invalid */ return i;}
PCHARgetVKName(IN ULONG VirtualKey, IN BOOLEAN Prefix){ ULONG i;
/* Loop for standard virtual key */ if (((VirtualKey >= 'A') && (VirtualKey <= 'Z')) || ((VirtualKey >= '0') && (VirtualKey <= '9'))) { /* Fill out the name */ gVKeyName[0] = '\''; gVKeyName[1] = VirtualKey; gVKeyName[2] = '\''; gVKeyName[3] = '\0'; return gVKeyName; }
/* Check if a prefix is required */ if (Prefix) { /* Add it */ strcpy(gVKeyName, "VK_"); } else { /* Otherwise, don't add anything */ strcpy(gVKeyName, ""); }
/* Loop all virtual keys */ for (i = 0; i < 36; i++) { /* Check if this key matches */ if (VKName[i].VirtualKey == VirtualKey) { /* Copy the key's name into the buffer */ strcat(gVKeyName, VKName[i].Name); return gVKeyName; } }
/* If we got here, then we failed, so print out an error name */ strcpy(gVKeyName, "#ERROR#"); return gVKeyName;}
ULONGgetVKNum(IN PCHAR p){ ULONG Length; ULONG i; ULONG KeyNumber;
/* Compute the length of the string */ Length = strlen(p); if (!Length) return -1;
/* Check if this is is a simple key */ if (Length == 1) { /* If it's a number, return it now */ if ((*p >= '0') && (*p <= '9')) return *p;
/* Otherwise, convert the letter to upper case */ *p = toupper(*p);
/* And make sure it's a valid letter */ if ((*p >= 'A') && (*p <='Z')) return *p;
/* Otherwise, fail */ return -1; }
/* Otherwise, scan our virtual key names */ for (i = 0; i < 36; i++) { /* Check if we have a match */ if (!strcmp(VKName[i].Name, p)) return VKName[i].VirtualKey; }
/* Check if this is a hex string */ if ((*p == '0') && ((*(p + 1) == 'x') || (*(p + 1) == 'X'))) { /* Get the key number from the hex string */ *(p + 1) = 'x'; if (sscanf(p, "0x%x", &KeyNumber) == 1) return KeyNumber; }
/* No hope: fail */ return -1;}
UCHARgetCharacterInfo(IN PCHAR State, OUT PULONG EntryChar, OUT PCHAR LigatureChar){ ULONG Length; ULONG CharInfo = CHAR_NORMAL_KEY; UCHAR StateChar; ULONG CharCode;
/* Calculate the length of the state */ Length = strlen(State);
/* Check if this is at least a simple key state */ if (Length > 1) { /* Read the first character and check if it's a dead key */ StateChar = State[Length - 1]; if (StateChar == '@') { /* This is a dead key */ CharInfo = CHAR_DEAD_KEY; } else if (StateChar == '%') { /* This is another key */ CharInfo = CHAR_OTHER_KEY; } }
/* Check if this is a numerical key state */ if ((Length - 1) >= 2) { /* Scan for extended character code entry */ if ((sscanf(State, "%6x", &CharCode) == 1) && (((Length == 5) && (State[0] == '0')) || ((Length == 6) && ((State[0] == '0') && (State[1] == '0'))))) { /* Handle a ligature key */ CharInfo = CHAR_LIGATURE_KEY;
/* Not yet handled */ printf("Ligatured character entries not yet supported!\n"); exit(1); } else { /* Get the normal character entry */ if (sscanf(State, "%4x", &CharCode) == 1) { /* Does the caller want the key? */ if (EntryChar) *EntryChar = CharCode; } else { /* The entry is totally invalid */ if (Verbose) printf("An unparseable character entry '%s' was found.\n", State); if (EntryChar) *EntryChar = 0; CharInfo = CHAR_INVALID_KEY; } } } else { /* Save the key if the caller requested it */ if (EntryChar) *EntryChar = *State; }
/* Return the type of character this is */ return CharInfo;}
BOOLEANNextLine(PCHAR LineBuffer, ULONG BufferSize, FILE *File){ PCHAR p, pp;
/* Scan each line */ while (fgets(LineBuffer, BufferSize, File)) { /* Remember it */ gLineCount++;
/* Reset the pointer at the beginning of the line */ p = LineBuffer;
/* Now bypass all whitespace (and tabspace) */ while ((*p) && ((*p == ' ') || (*p == '\t'))) p++;
/* If this is an old-style comment, skip the line */ if (*p == ';') continue;
/* Otherwise, check for new-style comment */ pp = strstr(p, "//"); if (pp) { /* We have a comment, so terminate there (unless the whole line is one) */ if (pp == p) continue; *pp = '\0'; } else { /* No comment, so find the new line and terminate there */ p = strchr(p, '\n'); if (p) *p = '\0'; }
/* We have a line! */ return TRUE; }
/* No line found */ return FALSE;}
ULONGSkipLines(VOID){ ULONG KeyWord; CHAR KeyWordChars[32];
/* Scan each line, skipping it if it's not a keyword */ while (NextLine(gBuf, sizeof(gBuf), gfpInput)) { /* Read a single word */ if (sscanf(gBuf, "%s", KeyWordChars) == 1) { /* If the word is a keyword, stop skipping lines */ KeyWord = isKeyWord(KeyWordChars); if (KeyWord < KEYWORD_COUNT) return KeyWord; } }
/* We skipped all the possible lines, not finding anything */ return KEYWORD_COUNT;}
ULONGDoKBD(VOID){ /* On Unicode files, we need to find the Unicode marker (FEEF) */ ASSERT(UnicodeFile == FALSE);
/* Initial values */ *gKBDName = '\0'; *gDescription = '\0';
/* Scan for the values */ if (sscanf(gBuf, "KBD %8s \"%40[^\"]\" %d", gKBDName, gDescription, &gID) < 2) { /* Couldn't find them */ printf("Unable to read keyboard name or description.\n"); exit(1); }
/* Debug only */ DPRINT1("KBD Name: [%8s] Description: [%40s] ID: [%d]\n", gKBDName, gDescription, gID); return SkipLines();}
ULONGDoVERSION(VOID){ /* Scan for the value */ if (sscanf(gBuf, "VERSION %d", &gKbdLayoutVersion) < 1) { /* Couldn't find them */ printf("Unable to read keyboard version information.\n"); }
/* Debug only */ DPRINT1("VERSION [%d]\n", gKbdLayoutVersion); return SkipLines();}
ULONGDoCOPYRIGHT(VOID){ /* Initial values */ *gCopyright = '\0';
/* Scan for the value */ if (sscanf(gBuf, "COPYRIGHT \"%40[^\"]\"", gCopyright) < 1) { /* Couldn't find them */ printf("Unable to read the specified COPYRIGHT string.\n"); }
/* Debug only */ DPRINT1("COPYRIGHT [%40s]\n", gCopyright); return SkipLines();}
ULONGDoCOMPANY(VOID){ /* Initial values */ *gCompany = '\0';
/* Scan for the value */ if (sscanf(gBuf, "COMPANY \"%85[^\"]\"", gCompany) < 1) { /* Couldn't find them */ printf("Unable to read the specified COMPANY name.\n"); }
/* Debug only */ DPRINT1("COMPANY [%85s]\n", gCompany); return SkipLines();}
ULONGDoLOCALENAME(VOID){ /* Initial values */ *gLocaleName = '\0';
/* Scan for the value */ if (sscanf(gBuf, "LOCALENAME \"%40[^\"]\"", gLocaleName) < 1) { /* Couldn't find them */ printf("Unable to read the specified COPYRIGHT string.\n"); }
/* Debug only */ DPRINT1("LOCALENAME [%40s]\n", gLocaleName); return SkipLines();}
ULONGDoDESCRIPTIONS(IN PKEYNAME* DescriptionData){ ULONG KeyWord = 0; CHAR Token[32]; ULONG LanguageCode; PCHAR p, pp; PKEYNAME Description;
/* Assume nothing */ *DescriptionData = 0;
/* Start scanning */ while (NextLine(gBuf, 256, gfpInput)) { /* Search for token */ if (sscanf(gBuf, "%s", Token) != 1) continue;
/* Make sure it's not just a comment */ if (*Token == ';') continue;
/* Make sure it's not a keyword */ KeyWord = isKeyWord(Token); if (KeyWord < KEYWORD_COUNT) break;
/* Now scan for the language code */ if (sscanf(Token, " %4x", &LanguageCode) != 1) { /* Skip */ printf("An invalid LANGID was specified.\n"); continue; }
/* Now get the actual description */ if (sscanf(gBuf, " %*4x %s[^\n]", Token) != 1) { /* Skip */ printf("A language description is missing.\n"); continue; }
/* Get the description string and find the ending */ p = strstr(gBuf, Token); pp = strchr(p, '\n'); if (!pp) pp = strchr(p, '\r');
/* Terminate the description string here */ if (pp) *pp = 0;
/* Now allocate the description */ Description = malloc(sizeof(KEYNAME)); if (!Description) { /* Fail */ printf("Unable to allocate the KEYNAME struct (out of memory?).\n"); exit(1); }
/* Fill out the structure */ Description->Code = LanguageCode; Description->Name = strdup(p); Description->Next = NULL;
/* Debug only */ DPRINT1("LANGID: [%4x] Description: [%s]\n", Description->Code, Description->Name);
/* Point to it and advance the pointer */ *DescriptionData = Description; DescriptionData = &Description->Next; }
/* We are done */ return KeyWord;}
ULONGDoLANGUAGENAMES(IN PKEYNAME* LanguageData){ ULONG KeyWord = 0; CHAR Token[32]; ULONG LanguageCode; PCHAR p, pp; PKEYNAME Language;
/* Assume nothing */ *LanguageData = 0;
/* Start scanning */ while (NextLine(gBuf, 256, gfpInput)) { /* Search for token */ if (sscanf(gBuf, "%s", Token) != 1) continue;
/* Make sure it's not just a comment */ if (*Token == ';') continue;
/* Make sure it's not a keyword */ KeyWord = isKeyWord(Token); if (KeyWord < KEYWORD_COUNT) break;
/* Now scan for the language code */ if (sscanf(Token, " %4x", &LanguageCode) != 1) { /* Skip */ printf("An invalid LANGID was specified.\n"); continue; }
/* Now get the actual language */ if (sscanf(gBuf, " %*4x %s[^\n]", Token) != 1) { /* Skip */ printf("A language name is missing\n"); continue; }
/* Get the language string and find the ending */ p = strstr(gBuf, Token); pp = strchr(p, '\n'); if (!pp) pp = strchr(p, '\r');
/* Terminate the language string here */ if (pp) *pp = 0;
/* Now allocate the language */ Language = malloc(sizeof(KEYNAME)); if (!Language) { /* Fail */ printf("Unable to allocate the KEYNAME struct (out of memory?).\n"); exit(1); }
/* Fill out the structure */ Language->Code = LanguageCode; Language->Name = strdup(p); Language->Next = NULL;
/* Debug only */ DPRINT1("LANGID: [%4x] Name: [%s]\n", Language->Code, Language->Name);
/* Point to it and advance the pointer */ *LanguageData = Language; LanguageData = &Language->Next; }
/* We are done */ return KeyWord;}
ULONGDoKEYNAME(IN PKEYNAME* KeyNameData){ ULONG KeyWord = 0; CHAR Token[32]; ULONG CharacterCode; PCHAR p, pp; PKEYNAME KeyName;
/* Assume nothing */ *KeyNameData = 0;
/* Start scanning */ while (NextLine(gBuf, 256, gfpInput)) { /* Search for token */ if (sscanf(gBuf, "%s", Token) != 1) continue;
/* Make sure it's not just a comment */ if (*Token == ';') continue;
/* Make sure it's not a keyword */ KeyWord = isKeyWord(Token); if (KeyWord < KEYWORD_COUNT) break;
/* Now scan for the character code */ if (sscanf(Token, " %4x", &CharacterCode) != 1) { /* Skip */ printf("An invalid character code was specified.\n"); continue; }
/* Now get the actual key name */ if (sscanf(gBuf, " %*4x %s[^\n]", Token) != 1) { /* Skip */ printf("A key name is missing\n"); continue; }
/* Get the key name string and find the ending */ p = strstr(gBuf, Token); pp = strchr(p, '\n'); if (!pp) pp = strchr(p, '\r');
/* Terminate the key name string here */ if (pp) *pp = 0;
/* Now allocate the language */ KeyName = malloc(sizeof(KEYNAME)); if (!KeyName) { /* Fail */ printf("Unable to allocate the KEYNAME struct (out of memory?).\n"); exit(1); }
/* Fill out the structure */ KeyName->Code = CharacterCode; KeyName->Name = strdup(p); KeyName->Next = NULL;
/* Debug only */ DPRINT1("CHARCODE: [%4x] Name: [%s]\n", KeyName->Code, KeyName->Name);
/* Point to it and advance the pointer */ *KeyNameData = KeyName; KeyNameData = &KeyName->Next; }
/* We are done */ return KeyWord;}
ULONGDoSHIFTSTATE(IN PULONG StateCount, IN OUT PULONG ShiftStates){ ULONG KeyWord; ULONG i; ULONG ShiftState; CHAR Token[32];
/* Reset the shift states */ for (i = 0; i < 8; i++) ShiftStates[i] = -1;
/* Start with no states */ *StateCount = 0;
/* Scan for shift states */ while (NextLine(gBuf, 256, gfpInput)) { /* Search for token */ if (sscanf(gBuf, "%s", Token) != 1) continue;
/* Make sure it's not a keyword */ KeyWord = isKeyWord(Token); if (KeyWord < KEYWORD_COUNT) break;
/* Now scan for the shift state */ if (sscanf(gBuf, " %1s[012367]", Token) != 1) { /* We failed -- should we warn? */ if (Verbose) printf("An invalid shift state '%s' was found (use 0, 1, 2, 3, 6, or 7.)\n", Token); continue; }
/* Now read the state */ ShiftState = atoi(Token);
/* Scan existing states */ for (i = 0; i < *StateCount; i++) { /* Check for duplicate */ if ((ShiftStates[i] == ShiftState) && (Verbose)) { /* Warn user */ printf("The state '%d' was duplicated for this Virtual Key.\n", ShiftStates[i]); break; } }
/* Make sure we won't overflow */ if (*StateCount < 8) { /* Save this state */ ShiftStates[(*StateCount)++] = ShiftState; } else { /* Too many states -- should we warn? */ if (Verbose) printf("There were too many states (you defined %d).\n", *StateCount); } }
/* Debug only */ DPRINT1("Found %d Shift States: [", *StateCount); for (i = 0; i < *StateCount; i++) DPRINT1("%d ", ShiftStates[i]); DPRINT1("]\n");
/* We are done */ return KeyWord;}
ULONGDoLIGATURE(PVOID LigatureData){ printf("LIGATURE support is not yet implemented. Please bug Arch to fix it\n"); return SkipLines();}
ULONGDoATTRIBUTES(PVOID AttributeData){ printf("ATTRIBUTES support is not yet implemented. Please bug Arch to fix it\n"); return SkipLines();}
ULONGDoMODIFIERS(VOID){ printf("MODIFIERS support is not yet implemented. Please bug Arch to fix it\n"); return SkipLines();}
ULONGDoDEADKEY(PVOID DeadKeyData){ printf("DEADKEY support is not yet implemented. Please bug Arch to fix it\n"); return SkipLines();}
ULONGDoLAYOUT(IN PLAYOUT LayoutData, IN PVOID LigatureData, IN PULONG ShiftStates, IN ULONG StateCount){ CHAR Token[32]; CHAR Cap[8]; ULONG KeyWord; ULONG ScanCode, CurrentCode; ULONG TokenCount; ULONG VirtualKey; ULONG i; ULONG Count; BOOLEAN FullEntry; CHAR State[8][8]; ULONG ScanCodeCount = -1; PLAYOUTENTRY Entry; UCHAR CharacterType; CHAR LigatureChar;
/* Zero out the layout */ memset(LayoutData, 0, sizeof(LAYOUT));
/* Read each line */ Entry = &LayoutData->Entry[0]; while (NextLine(gBuf, 256, gfpInput)) { /* Search for token */ if (sscanf(gBuf, "%s", Token) != 1) continue;
/* Make sure it's not just a comment */ if (*Token == ';') continue;
/* Make sure it's not a keyword */ KeyWord = isKeyWord(Token); if (KeyWord < KEYWORD_COUNT) break;
/* Now read the entry */ TokenCount = sscanf(gBuf, " %x %s %s", &ScanCode, Token, Cap); if (TokenCount == 3) { /* Full entry with cap */ FullEntry = TRUE; } else if (TokenCount != 2) { /* Fail, invalid LAYOUT entry */ printf("There are not enough columns in the layout list.\n"); exit(1); } else { /* Simplified layout with no cap */ FullEntry = FALSE; }
/* One more */ DPRINT1("RAW ENTRY: [%x %s %s]\n", ScanCode, Token, Cap); Entry++; if (++ScanCodeCount >= 110) { /* Too many! */ printf("ScanCode %02x - too many scancodes here to parse.\n", ScanCode); exit(1); }
/* Fill out this entry */ Entry->ScanCode = ScanCode; Entry->LineCount = gLineCount;
/* Loop scancode table */ for (i = 0; i < 110; i++) { /* Get the current code */ CurrentCode = ScVk[i].ScanCode; if (CurrentCode == 0xFFFF) { /* New code */ if (Verbose) printf("A new scancode is being defined: 0x%2X, %s\n", Entry->ScanCode, Token);
/* Fill out the entry */ Entry->VirtualKey = getVKNum(Token); break; } else if (ScanCode == CurrentCode) { /* Make sure we didn't already process it */ if (ScVk[i].Processed) { /* Fail */ printf("Scancode %X was previously defined.\n", ScanCode); exit(1); }
/* Check if there is a valid virtual key */ if (ScVk[i].VirtualKey == 0xFFFF) { /* Fail */ printf("The Scancode you tried to use (%X) is reserved.\n", ScanCode); exit(1); }
/* Fill out the entry */ Entry->OriginalVirtualKey = ScVk[i].VirtualKey; Entry->Name = ScVk[i].Name; break; } }
/* The entry is now processed */ Entry->Processed = TRUE; ScVk[i].Processed = TRUE;
/* Get the virtual key from the entry */ VirtualKey = getVKNum(Token); Entry->VirtualKey = VirtualKey; DPRINT1("ENTRY: [%x %x %x %s] with ", Entry->VirtualKey, Entry->OriginalVirtualKey, Entry->ScanCode, Entry->Name);
/* Make sure it's valid */ if (VirtualKey == 0xFFFF) { /* Warn the user */ if (Verbose) printf("An invalid Virtual Key '%s' was defined.\n", Token); continue; }
/* Is this a full entry */ if (FullEntry) { /* Do we have SGCAP data? Set cap mode to 2 */ if (!strcmp(Cap, "SGCAP")) *Cap = '2';
/* Read the cap mode */ if (sscanf(Cap, "%1d[012]", &Entry->Cap) != 1) { /* Invalid cap mode */ printf("invalid Cap specified (%s). Must be 0, 1, or 2.\n", Cap); exit(1); } }
/* Read the states */ Count = sscanf(gBuf, " %*s %*s %*s %s %s %s %s %s %s %s %s", State[0], State[1], State[2], State[3], State[4], State[5], State[6], State[7]); Entry->StateCount = Count; DPRINT1("%d STATES: [", Count);
/* Check if there are less than 2 states */ if ((Count < 2) && (FullEntry)) { /* Fail */ printf("You must have at least 2 characters.\n"); exit(1); }
/* Loop all states */ for (i = 0; i < Count; i++) { /* Check if this is an undefined state */ DPRINT1("%s ", State[i]); if (!strcmp(State[i], "-1")) { /* No data for this state */ Entry->CharData[i] = -1; continue; }
/* Otherwise, check what kind of character this is */ CharacterType = getCharacterInfo(State[i], &Entry->CharData[i], &LigatureChar); if (CharacterType == CHAR_DEAD_KEY) { /* Save it as such */ Entry->DeadCharData[i] = 1; } else if (CharacterType == CHAR_OTHER_KEY) { /* Save it as such */ Entry->OtherCharData[i] = 1; } }
/* Check for sanity checks */ DPRINT1("]\n"); if (SanityCheck) { /* Not yet handled... */ printf("Sanity checks not yet handled!\n"); exit(1); }
/* Check if we had SGCAP data */ if (Entry->Cap & 2) { /* Not yet handled... */ printf("SGCAP state not yet handled!\n"); exit(1); } }
/* Check if we have found any ScanCode in the file */
if (ScanCodeCount == -1) { printf("No ScanCode found!\n"); exit(1); }
/* Process the scan code table */ Entry = &LayoutData->Entry[ScanCodeCount]; for (i = 0; i < 110; i++) { /* Get the scan code */ CurrentCode = ScVk[i].ScanCode; if (CurrentCode == 0xFFFF) break;
/* Check if this entry had been processed */ if (ScVk[i].Processed) { /* Skip it */ ScVk[i].Processed = FALSE; } else { /* Do we have too many? */ if (++ScanCodeCount >= 110) { /* Fail */ printf("ScanCode %02x - too many scancodes here to parse.\n", CurrentCode); exit(1); }
/* Build an entry for it */ Entry++; Entry->ScanCode = CurrentCode; Entry->VirtualKey = ScVk[i].VirtualKey; Entry->OriginalVirtualKey = ScVk[i].VirtualKey; Entry->Name = ScVk[i].Name; Entry->Processed = TRUE; Entry->LineCount = 0; DPRINT1("AUTOMATIC ENTRY: [%x %x %s]\n", Entry->VirtualKey, Entry->ScanCode, Entry->Name); } }
/* Skip what's left */ return KeyWord;}
ULONGDoParsing(VOID){ ULONG KeyWords[KEYWORD_COUNT]; ULONG KeyWord; ULONG StateCount; ULONG ShiftStates[8]; PKEYNAME DescriptionData = NULL, LanguageData = NULL; PKEYNAME KeyNameData = NULL, KeyNameExtData = NULL, KeyNameDeadData = NULL; PVOID AttributeData = NULL, LigatureData = NULL, DeadKeyData = NULL;
/* Parse keywords */ gLineCount = 0; KeyWord = SkipLines(); if (KeyWord >= KEYWORD_COUNT) { /* Invalid keyword count, fail */ fclose(gfpInput); printf("No keywords were found in '%s'.\n", gpszFileName); exit(1); }
/* Now parse the keywords */ memset(KeyWords, 0, sizeof(KeyWords)); while (KeyWord < (KEYWORD_COUNT - 1)) { /* Save this keyword */ KeyWords[KeyWord]++;
/* Check for duplicate entires, other than DEADKEY, which is okay */ if ((KeyWord != 9) && (KeyWords[KeyWord] > 1) && (Verbose)) { /* On a verbose run, warn the user */ printf("The '%s' keyword appeared multiple times.\n", KeyWordList[KeyWord]); }
/* Now parse this keyword */ switch (KeyWord) { /* KBD */ case 0:
DPRINT1("Found KBD section\n"); KeyWord = DoKBD(); break;
/* VERSION */ case 1:
DPRINT1("Found VERSION section\n"); KeyWord = DoVERSION(); break;
/* COPYRIGHT */ case 2:
DPRINT1("Found COPYRIGHT section\n"); KeyWord = DoCOPYRIGHT(); break;
/* COMPANY */ case 3:
DPRINT1("Found COMPANY section\n"); KeyWord = DoCOMPANY(); break;
/* LOCALENAME */ case 4:
DPRINT1("Found LOCALENAME section\n"); KeyWord = DoLOCALENAME(); break;
/* MODIFIERS */ case 5:
DPRINT1("Found MODIFIERS section\n"); KeyWord = DoMODIFIERS(); break;
/* SHIFTSTATE */ case 6:
DPRINT1("Found SHIFTSTATE section\n"); KeyWord = DoSHIFTSTATE(&StateCount, ShiftStates); if (StateCount < 2) { /* Fail */ fclose(gfpInput); printf("ERROR"); exit(1); } break;
/* ATTRIBUTES */ case 7:
DPRINT1("Found ATTRIBUTES section\n"); KeyWord = DoATTRIBUTES(&AttributeData); break;
/* LAYOUT */ case 8:
DPRINT1("Found LAYOUT section\n"); KeyWord = DoLAYOUT(&g_Layout, &LigatureData, ShiftStates, StateCount); break;
/* DEADKEY */ case 9:
DPRINT1("Found DEADKEY section\n"); KeyWord = DoDEADKEY(&DeadKeyData); break;
/* LIGATURE */ case 10:
DPRINT1("Found LIGATURE section\n"); KeyWord = DoLIGATURE(&LigatureData); break;
/* KEYNAME */ case 11:
DPRINT1("Found KEYNAME section\n"); KeyWord = DoKEYNAME(&KeyNameData); break;
/* KEYNAME_EXT */ case 12:
DPRINT1("Found KEYNAME_EXT section\n"); KeyWord = DoKEYNAME(&KeyNameExtData); break;
/* KEYNAME_DEAD */ case 13:
DPRINT1("Found KEYNAME_DEAD section\n"); KeyWord = DoKEYNAME(&KeyNameDeadData); break;
/* DESCRIPTIONS */ case 14:
DPRINT1("Found DESCRIPTIONS section\n"); KeyWord = DoDESCRIPTIONS(&DescriptionData); break;
/* LANGUAGENAMES */ case 15:
DPRINT1("Found LANGUAGENAMES section\n"); KeyWord = DoLANGUAGENAMES(&LanguageData); break;
/* ENDKBD */ case 16:
DPRINT1("Found ENDKBD section\n"); KeyWord = SkipLines(); break;
default: break; } }
/* We are done */ fclose(gfpInput);
/* Now enter the output phase */ return DoOutput(StateCount, ShiftStates, DescriptionData, LanguageData, AttributeData, DeadKeyData, LigatureData, KeyNameData, KeyNameExtData, KeyNameDeadData);}/* EOF */