Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenparser.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Build Tools [Keyboard Layout Compiler] 00003 * LICENSE: BSD - See COPYING.BSD in the top level directory 00004 * FILE: tools/kbdtool/parser.c 00005 * PURPOSE: Parsing Logic 00006 * PROGRAMMERS: ReactOS Foundation 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include "kbdtool.h" 00012 00013 /* GLOBALS ********************************************************************/ 00014 00015 /* Internal parser data about everything that was parsed */ 00016 CHAR gBuf[256]; 00017 CHAR gKBDName[10]; 00018 CHAR gCopyright[256]; 00019 CHAR gDescription[256]; 00020 CHAR gCompany[256]; 00021 CHAR gLocaleName[256]; 00022 CHAR gVKeyName[32]; 00023 ULONG gID = 0; 00024 ULONG gKbdLayoutVersion; 00025 LAYOUT g_Layout; 00026 ULONG gLineCount; 00027 00028 /* Table of keywords the parser recognizes */ 00029 PCHAR KeyWordList[KEYWORD_COUNT] = 00030 { 00031 "KBD", 00032 "VERSION", 00033 "COPYRIGHT", 00034 "COMPANY", 00035 "LOCALENAME", 00036 "MODIIFERS", 00037 "SHIFTSTATE", 00038 "ATTRIBUTES", 00039 "LAYOUT", 00040 "DEADKEY", 00041 "LIGATURE", 00042 "KEYNAME", 00043 "KEYNAME_EXT", 00044 "KEYNAME_DEAD", 00045 "DESCRIPTIONS", 00046 "LANGUAGENAMES", 00047 "ENDKBD", 00048 }; 00049 00050 /* FUNCTIONS ******************************************************************/ 00051 00052 ULONG 00053 isKeyWord(PCHAR p) 00054 { 00055 ULONG i; 00056 00057 /* Check if we know this keyword */ 00058 for (i = 0; i < KEYWORD_COUNT; i++) if (strcmp(KeyWordList[i], p) == 0) break; 00059 00060 /* If we didn't find anything, i will be KEYWORD_COUNT, which is invalid */ 00061 return i; 00062 } 00063 00064 PCHAR 00065 getVKName(IN ULONG VirtualKey, 00066 IN BOOLEAN Prefix) 00067 { 00068 ULONG i; 00069 00070 /* Loop for standard virtual key */ 00071 if (((VirtualKey >= 'A') && (VirtualKey <= 'Z')) || 00072 ((VirtualKey >= '0') && (VirtualKey <= '9'))) 00073 { 00074 /* Fill out the name */ 00075 gVKeyName[0] = '\''; 00076 gVKeyName[1] = VirtualKey; 00077 gVKeyName[2] = '\''; 00078 gVKeyName[3] = '\0'; 00079 return gVKeyName; 00080 } 00081 00082 /* Check if a prefix is required */ 00083 if (Prefix) 00084 { 00085 /* Add it */ 00086 strcpy(gVKeyName, "VK_"); 00087 } 00088 else 00089 { 00090 /* Otherwise, don't add anything */ 00091 strcpy(gVKeyName, ""); 00092 } 00093 00094 /* Loop all virtual keys */ 00095 for (i = 0; i < 36; i++) 00096 { 00097 /* Check if this key matches */ 00098 if (VKName[i].VirtualKey == VirtualKey) 00099 { 00100 /* Copy the key's name into the buffer */ 00101 strcat(gVKeyName, VKName[i].Name); 00102 return gVKeyName; 00103 } 00104 } 00105 00106 /* If we got here, then we failed, so print out an error name */ 00107 strcpy(gVKeyName, "#ERROR#"); 00108 return gVKeyName; 00109 } 00110 00111 ULONG 00112 getVKNum(IN PCHAR p) 00113 { 00114 ULONG Length; 00115 ULONG i; 00116 ULONG KeyNumber; 00117 00118 /* Compute the length of the string */ 00119 Length = strlen(p); 00120 if (!Length) return -1; 00121 00122 /* Check if this is is a simple key */ 00123 if (Length == 1) 00124 { 00125 /* If it's a number, return it now */ 00126 if ((*p >= '0') && (*p <= '9')) return *p; 00127 00128 /* Otherwise, convert the letter to upper case */ 00129 *p = toupper(*p); 00130 00131 /* And make sure it's a valid letter */ 00132 if ((*p >= 'A') && (*p <='Z')) return *p; 00133 00134 /* Otherwise, fail */ 00135 return -1; 00136 } 00137 00138 /* Otherwise, scan our virtual key names */ 00139 for (i = 0; i < 36; i++) 00140 { 00141 /* Check if we have a match */ 00142 if (!strcmp(VKName[i].Name, p)) return VKName[i].VirtualKey; 00143 } 00144 00145 /* Check if this is a hex string */ 00146 if ((*p == '0') && ((*(p + 1) == 'x') || (*(p + 1) == 'X'))) 00147 { 00148 /* Get the key number from the hex string */ 00149 *(p + 1) = 'x'; 00150 if (sscanf(p, "0x%x", &KeyNumber) == 1) return KeyNumber; 00151 } 00152 00153 /* No hope: fail */ 00154 return -1; 00155 } 00156 00157 UCHAR 00158 getCharacterInfo(IN PCHAR State, 00159 OUT PULONG EntryChar, 00160 OUT PCHAR LigatureChar) 00161 { 00162 ULONG Length; 00163 ULONG CharInfo = CHAR_NORMAL_KEY; 00164 UCHAR StateChar; 00165 ULONG CharCode; 00166 00167 /* Calculate the length of the state */ 00168 Length = strlen(State); 00169 00170 /* Check if this is at least a simple key state */ 00171 if (Length > 1) 00172 { 00173 /* Read the first character and check if it's a dead key */ 00174 StateChar = State[Length - 1]; 00175 if (StateChar == '@') 00176 { 00177 /* This is a dead key */ 00178 CharInfo = CHAR_DEAD_KEY; 00179 } 00180 else if (StateChar == '%') 00181 { 00182 /* This is another key */ 00183 CharInfo = CHAR_OTHER_KEY; 00184 } 00185 } 00186 00187 /* Check if this is a numerical key state */ 00188 if ((Length - 1) >= 2) 00189 { 00190 /* Scan for extended character code entry */ 00191 if ((sscanf(State, "%6x", &CharCode) == 1) && 00192 ((Length == 5) && (State[0] == '0') || 00193 (Length == 6) && ((State[0] == '0') && (State[1] == '0')))) 00194 { 00195 /* Handle a ligature key */ 00196 CharInfo = CHAR_LIGATURE_KEY; 00197 00198 /* Not yet handled */ 00199 printf("Ligatured character entries not yet supported!\n"); 00200 exit(1); 00201 } 00202 else 00203 { 00204 /* Get the normal character entry */ 00205 if (sscanf(State, "%4x", &CharCode) == 1) 00206 { 00207 /* Does the caller want the key? */ 00208 if (EntryChar) *EntryChar = CharCode; 00209 } 00210 else 00211 { 00212 /* The entry is totally invalid */ 00213 if (Verbose) printf("An unparseable character entry '%s' was found.\n", State); 00214 if (EntryChar) *EntryChar = 0; 00215 CharInfo = CHAR_INVALID_KEY; 00216 } 00217 } 00218 } 00219 else 00220 { 00221 /* Save the key if the caller requested it */ 00222 if (EntryChar) *EntryChar = *State; 00223 } 00224 00225 /* Return the type of character this is */ 00226 return CharInfo; 00227 } 00228 00229 BOOLEAN 00230 NextLine(PCHAR LineBuffer, 00231 ULONG BufferSize, 00232 FILE *File) 00233 { 00234 PCHAR p, pp; 00235 00236 /* Scan each line */ 00237 while (fgets(LineBuffer, BufferSize, File)) 00238 { 00239 /* Remember it */ 00240 gLineCount++; 00241 00242 /* Reset the pointer at the beginning of the line */ 00243 p = LineBuffer; 00244 00245 /* Now bypass all whitespace (and tabspace) */ 00246 while ((*p) && ((*p == ' ') || (*p == '\t'))) p++; 00247 00248 /* If this is an old-style comment, skip the line */ 00249 if (*p == ';') continue; 00250 00251 /* Otherwise, check for new-style comment */ 00252 pp = strstr(p, "//"); 00253 if (pp) 00254 { 00255 /* We have a comment, so terminate there (unless the whole line is one) */ 00256 if (pp == p) continue; 00257 *pp = '\0'; 00258 } 00259 else 00260 { 00261 /* No comment, so find the new line and terminate there */ 00262 p = strchr(p, '\n'); 00263 if (p) *p = '\0'; 00264 } 00265 00266 /* We have a line! */ 00267 return TRUE; 00268 } 00269 00270 /* No line found */ 00271 return FALSE; 00272 } 00273 00274 ULONG 00275 SkipLines(VOID) 00276 { 00277 ULONG KeyWord; 00278 CHAR KeyWordChars[32]; 00279 00280 /* Scan each line, skipping it if it's not a keyword */ 00281 while (NextLine(gBuf, sizeof(gBuf), gfpInput)) 00282 { 00283 /* Read a single word */ 00284 if (sscanf(gBuf, "%s", KeyWordChars) == 1) 00285 { 00286 /* If the word is a keyword, stop skipping lines */ 00287 KeyWord = isKeyWord(KeyWordChars); 00288 if (KeyWord < KEYWORD_COUNT) return KeyWord; 00289 } 00290 } 00291 00292 /* We skipped all the possible lines, not finding anything */ 00293 return KEYWORD_COUNT; 00294 } 00295 00296 ULONG 00297 DoKBD(VOID) 00298 { 00299 /* On Unicode files, we need to find the Unicode marker (FEEF) */ 00300 ASSERT(UnicodeFile == FALSE); 00301 00302 /* Initial values */ 00303 *gKBDName = '\0'; 00304 *gDescription = '\0'; 00305 00306 /* Scan for the values */ 00307 if (sscanf(gBuf, "KBD %8s \"%40[^\"]\" %d", gKBDName, gDescription, &gID) < 2) 00308 { 00309 /* Couldn't find them */ 00310 printf("Unable to read keyboard name or description.\n"); 00311 exit(1); 00312 } 00313 00314 /* Debug only */ 00315 DPRINT1("KBD Name: [%8s] Description: [%40s] ID: [%d]\n", gKBDName, gDescription, gID); 00316 return SkipLines(); 00317 } 00318 00319 ULONG 00320 DoVERSION(VOID) 00321 { 00322 /* Scan for the value */ 00323 if (sscanf(gBuf, "VERSION %d", &gKbdLayoutVersion) < 1) 00324 { 00325 /* Couldn't find them */ 00326 printf("Unable to read keyboard version information.\n"); 00327 } 00328 00329 /* Debug only */ 00330 DPRINT1("VERSION [%d]\n", gKbdLayoutVersion); 00331 return SkipLines(); 00332 } 00333 00334 ULONG 00335 DoCOPYRIGHT(VOID) 00336 { 00337 /* Initial values */ 00338 *gCopyright = '\0'; 00339 00340 /* Scan for the value */ 00341 if (sscanf(gBuf, "COPYRIGHT \"%40[^\"]\"", gCopyright) < 1) 00342 { 00343 /* Couldn't find them */ 00344 printf("Unable to read the specified COPYRIGHT string.\n"); 00345 } 00346 00347 /* Debug only */ 00348 DPRINT1("COPYRIGHT [%40s]\n", gCopyright); 00349 return SkipLines(); 00350 } 00351 00352 ULONG 00353 DoCOMPANY(VOID) 00354 { 00355 /* Initial values */ 00356 *gCompany = '\0'; 00357 00358 /* Scan for the value */ 00359 if (sscanf(gBuf, "COMPANY \"%85[^\"]\"", gCompany) < 1) 00360 { 00361 /* Couldn't find them */ 00362 printf("Unable to read the specified COMPANY name.\n"); 00363 } 00364 00365 /* Debug only */ 00366 DPRINT1("COMPANY [%85s]\n", gCompany); 00367 return SkipLines(); 00368 } 00369 00370 ULONG 00371 DoLOCALENAME(VOID) 00372 { 00373 /* Initial values */ 00374 *gLocaleName = '\0'; 00375 00376 /* Scan for the value */ 00377 if (sscanf(gBuf, "LOCALENAME \"%40[^\"]\"", gLocaleName) < 1) 00378 { 00379 /* Couldn't find them */ 00380 printf("Unable to read the specified COPYRIGHT string.\n"); 00381 } 00382 00383 /* Debug only */ 00384 DPRINT1("LOCALENAME [%40s]\n", gLocaleName); 00385 return SkipLines(); 00386 } 00387 00388 ULONG 00389 DoDESCRIPTIONS(IN PKEYNAME* DescriptionData) 00390 { 00391 ULONG KeyWord = 0; 00392 CHAR Token[32]; 00393 ULONG LanguageCode; 00394 PCHAR p, pp; 00395 PKEYNAME Description; 00396 00397 /* Assume nothing */ 00398 *DescriptionData = 0; 00399 00400 /* Start scanning */ 00401 while (NextLine(gBuf, 256, gfpInput)) 00402 { 00403 /* Search for token */ 00404 if (sscanf(gBuf, "%s", Token) != 1) continue; 00405 00406 /* Make sure it's not just a comment */ 00407 if (*Token == ';') continue; 00408 00409 /* Make sure it's not a keyword */ 00410 KeyWord = isKeyWord(Token); 00411 if (KeyWord < KEYWORD_COUNT) break; 00412 00413 /* Now scan for the language code */ 00414 if (sscanf(Token, " %4x", &LanguageCode) != 1) 00415 { 00416 /* Skip */ 00417 printf("An invalid LANGID was specified.\n"); 00418 continue; 00419 } 00420 00421 /* Now get the actual description */ 00422 if (sscanf(gBuf, " %*4x %s[^\n]", Token) != 1) 00423 { 00424 /* Skip */ 00425 printf("A language description is missing.\n"); 00426 continue; 00427 } 00428 00429 /* Get the description string and find the ending */ 00430 p = strstr(gBuf, Token); 00431 pp = strchr(p, '\n'); 00432 if (!pp) pp = strchr(p, '\r'); 00433 00434 /* Terminate the description string here */ 00435 if (pp) *pp = 0; 00436 00437 /* Now allocate the description */ 00438 Description = malloc(sizeof(KEYNAME)); 00439 if (!Description) 00440 { 00441 /* Fail */ 00442 printf("Unable to allocate the KEYNAME struct (out of memory?).\n"); 00443 exit(1); 00444 } 00445 00446 /* Fill out the structure */ 00447 Description->Code = LanguageCode; 00448 Description->Name = strdup(p); 00449 Description->Next = NULL; 00450 00451 /* Debug only */ 00452 DPRINT1("LANGID: [%4x] Description: [%s]\n", Description->Code, Description->Name); 00453 00454 /* Point to it and advance the pointer */ 00455 *DescriptionData = Description; 00456 DescriptionData = &Description->Next; 00457 } 00458 00459 /* We are done */ 00460 return KeyWord; 00461 } 00462 00463 ULONG 00464 DoLANGUAGENAMES(IN PKEYNAME* LanguageData) 00465 { 00466 ULONG KeyWord = 0; 00467 CHAR Token[32]; 00468 ULONG LanguageCode; 00469 PCHAR p, pp; 00470 PKEYNAME Language; 00471 00472 /* Assume nothing */ 00473 *LanguageData = 0; 00474 00475 /* Start scanning */ 00476 while (NextLine(gBuf, 256, gfpInput)) 00477 { 00478 /* Search for token */ 00479 if (sscanf(gBuf, "%s", Token) != 1) continue; 00480 00481 /* Make sure it's not just a comment */ 00482 if (*Token == ';') continue; 00483 00484 /* Make sure it's not a keyword */ 00485 KeyWord = isKeyWord(Token); 00486 if (KeyWord < KEYWORD_COUNT) break; 00487 00488 /* Now scan for the language code */ 00489 if (sscanf(Token, " %4x", &LanguageCode) != 1) 00490 { 00491 /* Skip */ 00492 printf("An invalid LANGID was specified.\n"); 00493 continue; 00494 } 00495 00496 /* Now get the actual language */ 00497 if (sscanf(gBuf, " %*4x %s[^\n]", Token) != 1) 00498 { 00499 /* Skip */ 00500 printf("A language name is missing\n"); 00501 continue; 00502 } 00503 00504 /* Get the language string and find the ending */ 00505 p = strstr(gBuf, Token); 00506 pp = strchr(p, '\n'); 00507 if (!pp) pp = strchr(p, '\r'); 00508 00509 /* Terminate the language string here */ 00510 if (pp) *pp = 0; 00511 00512 /* Now allocate the language */ 00513 Language = malloc(sizeof(KEYNAME)); 00514 if (!Language) 00515 { 00516 /* Fail */ 00517 printf("Unable to allocate the KEYNAME struct (out of memory?).\n"); 00518 exit(1); 00519 } 00520 00521 /* Fill out the structure */ 00522 Language->Code = LanguageCode; 00523 Language->Name = strdup(p); 00524 Language->Next = NULL; 00525 00526 /* Debug only */ 00527 DPRINT1("LANGID: [%4x] Name: [%s]\n", Language->Code, Language->Name); 00528 00529 /* Point to it and advance the pointer */ 00530 *LanguageData = Language; 00531 LanguageData = &Language->Next; 00532 } 00533 00534 /* We are done */ 00535 return KeyWord; 00536 } 00537 00538 ULONG 00539 DoKEYNAME(IN PKEYNAME* KeyNameData) 00540 { 00541 ULONG KeyWord = 0; 00542 CHAR Token[32]; 00543 ULONG CharacterCode; 00544 PCHAR p, pp; 00545 PKEYNAME KeyName; 00546 00547 /* Assume nothing */ 00548 *KeyNameData = 0; 00549 00550 /* Start scanning */ 00551 while (NextLine(gBuf, 256, gfpInput)) 00552 { 00553 /* Search for token */ 00554 if (sscanf(gBuf, "%s", Token) != 1) continue; 00555 00556 /* Make sure it's not just a comment */ 00557 if (*Token == ';') continue; 00558 00559 /* Make sure it's not a keyword */ 00560 KeyWord = isKeyWord(Token); 00561 if (KeyWord < KEYWORD_COUNT) break; 00562 00563 /* Now scan for the character code */ 00564 if (sscanf(Token, " %4x", &CharacterCode) != 1) 00565 { 00566 /* Skip */ 00567 printf("An invalid character code was specified.\n"); 00568 continue; 00569 } 00570 00571 /* Now get the actual key name */ 00572 if (sscanf(gBuf, " %*4x %s[^\n]", Token) != 1) 00573 { 00574 /* Skip */ 00575 printf("A key name is missing\n"); 00576 continue; 00577 } 00578 00579 /* Get the key name string and find the ending */ 00580 p = strstr(gBuf, Token); 00581 pp = strchr(p, '\n'); 00582 if (!pp) pp = strchr(p, '\r'); 00583 00584 /* Terminate the key name string here */ 00585 if (pp) *pp = 0; 00586 00587 /* Now allocate the language */ 00588 KeyName = malloc(sizeof(KEYNAME)); 00589 if (!KeyName) 00590 { 00591 /* Fail */ 00592 printf("Unable to allocate the KEYNAME struct (out of memory?).\n"); 00593 exit(1); 00594 } 00595 00596 /* Fill out the structure */ 00597 KeyName->Code = CharacterCode; 00598 KeyName->Name = strdup(p); 00599 KeyName->Next = NULL; 00600 00601 /* Debug only */ 00602 DPRINT1("CHARCODE: [%4x] Name: [%s]\n", KeyName->Code, KeyName->Name); 00603 00604 /* Point to it and advance the pointer */ 00605 *KeyNameData = KeyName; 00606 KeyNameData = &KeyName->Next; 00607 } 00608 00609 /* We are done */ 00610 return KeyWord; 00611 } 00612 00613 ULONG 00614 DoSHIFTSTATE(IN PULONG StateCount, 00615 IN OUT PULONG ShiftStates) 00616 { 00617 ULONG KeyWord; 00618 ULONG i; 00619 ULONG ShiftState; 00620 CHAR Token[32]; 00621 00622 /* Reset the shift states */ 00623 for (i = 0; i < 8; i++) ShiftStates[i] = -1; 00624 00625 /* Start with no states */ 00626 *StateCount = 0; 00627 00628 /* Scan for shift states */ 00629 while (NextLine(gBuf, 256, gfpInput)) 00630 { 00631 /* Search for token */ 00632 if (sscanf(gBuf, "%s", Token) != 1) continue; 00633 00634 /* Make sure it's not a keyword */ 00635 KeyWord = isKeyWord(Token); 00636 if (KeyWord < KEYWORD_COUNT) break; 00637 00638 /* Now scan for the shift state */ 00639 if (sscanf(gBuf, " %1s[012367]", Token) != 1) 00640 { 00641 /* We failed -- should we warn? */ 00642 if (Verbose) printf("An invalid shift state '%s' was found (use 0, 1, 2, 3, 6, or 7.)\n", Token); 00643 continue; 00644 } 00645 00646 /* Now read the state */ 00647 ShiftState = atoi(Token); 00648 00649 /* Scan existing states */ 00650 for (i = 0; i < *StateCount; i++) 00651 { 00652 /* Check for duplicate */ 00653 if ((ShiftStates[i] == ShiftState) && (Verbose)) 00654 { 00655 /* Warn user */ 00656 printf("The state '%d' was duplicated for this Virtual Key.\n", ShiftStates[i]); 00657 break; 00658 } 00659 } 00660 00661 /* Make sure we won't overflow */ 00662 if (*StateCount < 8) 00663 { 00664 /* Save this state */ 00665 ShiftStates[(*StateCount)++] = ShiftState; 00666 } 00667 else 00668 { 00669 /* Too many states -- should we warn? */ 00670 if (Verbose) printf("There were too many states (you defined %d).\n", *StateCount); 00671 } 00672 } 00673 00674 /* Debug only */ 00675 DPRINT1("Found %d Shift States: [", *StateCount); 00676 for (i = 0; i < *StateCount; i++) DPRINT1("%d ", ShiftStates[i]); 00677 DPRINT1("]\n"); 00678 00679 /* We are done */ 00680 return KeyWord; 00681 } 00682 00683 ULONG 00684 DoLIGATURE(PVOID LigatureData) 00685 { 00686 printf("LIGATURE support is not yet implemented. Please bug Arch to fix it\n"); 00687 return SkipLines(); 00688 } 00689 00690 ULONG 00691 DoATTRIBUTES(PVOID AttributeData) 00692 { 00693 printf("ATTRIBUTES support is not yet implemented. Please bug Arch to fix it\n"); 00694 return SkipLines(); 00695 } 00696 00697 ULONG 00698 DoMODIFIERS(VOID) 00699 { 00700 printf("MODIFIERS support is not yet implemented. Please bug Arch to fix it\n"); 00701 return SkipLines(); 00702 } 00703 00704 ULONG 00705 DoDEADKEY(PVOID DeadKeyData) 00706 { 00707 printf("DEADKEY support is not yet implemented. Please bug Arch to fix it\n"); 00708 return SkipLines(); 00709 } 00710 00711 ULONG 00712 DoLAYOUT(IN PLAYOUT LayoutData, 00713 IN PVOID LigatureData, 00714 IN PULONG ShiftStates, 00715 IN ULONG StateCount) 00716 { 00717 CHAR Token[32]; 00718 CHAR Cap[8]; 00719 ULONG KeyWord; 00720 ULONG ScanCode, CurrentCode; 00721 ULONG TokenCount; 00722 ULONG VirtualKey; 00723 ULONG i; 00724 ULONG Count; 00725 BOOLEAN FullEntry; 00726 CHAR State[8][8]; 00727 ULONG ScanCodeCount = -1; 00728 PLAYOUTENTRY Entry; 00729 UCHAR CharacterType, LigatureChar; 00730 00731 /* Zero out the layout */ 00732 memset(LayoutData, 0, sizeof(LAYOUT)); 00733 00734 /* Read each line */ 00735 Entry = &LayoutData->Entry[0]; 00736 while (NextLine(gBuf, 256, gfpInput)) 00737 { 00738 /* Search for token */ 00739 if (sscanf(gBuf, "%s", Token) != 1) continue; 00740 00741 /* Make sure it's not just a comment */ 00742 if (*Token == ';') continue; 00743 00744 /* Make sure it's not a keyword */ 00745 KeyWord = isKeyWord(Token); 00746 if (KeyWord < KEYWORD_COUNT) break; 00747 00748 /* Now read the entry */ 00749 TokenCount = sscanf(gBuf, " %x %s %s", &ScanCode, Token, Cap); 00750 if (TokenCount == 3) 00751 { 00752 /* Full entry with cap */ 00753 FullEntry = TRUE; 00754 } 00755 else if (TokenCount != 2) 00756 { 00757 /* Fail, invalid LAYOUT entry */ 00758 printf("There are not enough columns in the layout list.\n"); 00759 exit(1); 00760 } 00761 else 00762 { 00763 /* Simplified layout with no cap */ 00764 FullEntry = FALSE; 00765 } 00766 00767 /* One more */ 00768 DPRINT1("RAW ENTRY: [%x %s %s]\n", ScanCode, Token, Cap); 00769 Entry++; 00770 if (++ScanCodeCount >= 110) 00771 { 00772 /* Too many! */ 00773 printf("ScanCode %02x - too many scancodes here to parse.\n", ScanCode); 00774 exit(1); 00775 } 00776 00777 /* Fill out this entry */ 00778 Entry->ScanCode = ScanCode; 00779 Entry->LineCount = gLineCount; 00780 00781 /* Loop scancode table */ 00782 for (i = 0; i < 110; i++) 00783 { 00784 /* Get the current code */ 00785 CurrentCode = ScVk[i].ScanCode; 00786 if (CurrentCode == 0xFFFF) 00787 { 00788 /* New code */ 00789 if (Verbose) printf("A new scancode is being defined: 0x%2X, %s\n", Entry->ScanCode, Token); 00790 00791 /* Fill out the entry */ 00792 Entry->VirtualKey = getVKNum(Token); 00793 break; 00794 } 00795 else if (ScanCode == CurrentCode) 00796 { 00797 /* Make sure we didn't already process it */ 00798 if (ScVk[i].Processed) 00799 { 00800 /* Fail */ 00801 printf("Scancode %X was previously defined.\n", ScanCode); 00802 exit(1); 00803 } 00804 00805 /* Check if there is a valid virtual key */ 00806 if (ScVk[i].VirtualKey == 0xFFFF) 00807 { 00808 /* Fail */ 00809 printf("The Scancode you tried to use (%X) is reserved.\n", ScanCode); 00810 exit(1); 00811 } 00812 00813 /* Fill out the entry */ 00814 Entry->OriginalVirtualKey = ScVk[i].VirtualKey; 00815 Entry->Name = ScVk[i].Name; 00816 break; 00817 } 00818 } 00819 00820 /* The entry is now processed */ 00821 Entry->Processed = TRUE; 00822 ScVk[i].Processed = TRUE; 00823 00824 /* Get the virtual key from the entry */ 00825 VirtualKey = getVKNum(Token); 00826 Entry->VirtualKey = VirtualKey; 00827 DPRINT1("ENTRY: [%x %x %x %s] with ", 00828 Entry->VirtualKey, Entry->OriginalVirtualKey, Entry->ScanCode, Entry->Name); 00829 00830 /* Make sure it's valid */ 00831 if (VirtualKey == 0xFFFF) 00832 { 00833 /* Warn the user */ 00834 if (Verbose) printf("An invalid Virtual Key '%s' was defined.\n", Token); 00835 continue; 00836 } 00837 00838 /* Is this a full entry */ 00839 if (FullEntry) 00840 { 00841 /* Do we have SGCAP data? Set cap mode to 2 */ 00842 if (!strcmp(Cap, "SGCAP")) *Cap = '2'; 00843 00844 /* Read the cap mode */ 00845 if (sscanf(Cap, "%1d[012]", &Entry->Cap) != 1) 00846 { 00847 /* Invalid cap mode */ 00848 printf("invalid Cap specified (%s). Must be 0, 1, or 2.\n", Cap); 00849 exit(1); 00850 } 00851 } 00852 00853 /* Read the states */ 00854 Count = sscanf(gBuf, 00855 " %*s %*s %*s %s %s %s %s %s %s %s %s", 00856 State[0], 00857 State[1], 00858 State[2], 00859 State[3], 00860 State[4], 00861 State[5], 00862 State[6], 00863 State[7]); 00864 Entry->StateCount = Count; 00865 DPRINT1("%d STATES: [", Count); 00866 00867 /* Check if there are less than 2 states */ 00868 if ((Count < 2) && (FullEntry)) 00869 { 00870 /* Fail */ 00871 printf("You must have at least 2 characters.\n"); 00872 exit(1); 00873 } 00874 00875 /* Loop all states */ 00876 for (i = 0; i < Count; i++) 00877 { 00878 /* Check if this is an undefined state */ 00879 DPRINT1("%s ", State[i]); 00880 if (!strcmp(State[i], "-1")) 00881 { 00882 /* No data for this state */ 00883 Entry->CharData[i] = -1; 00884 continue; 00885 } 00886 00887 /* Otherwise, check what kind of character this is */ 00888 CharacterType = getCharacterInfo(State[i], 00889 &Entry->CharData[i], 00890 &LigatureChar); 00891 if (CharacterType == CHAR_DEAD_KEY) 00892 { 00893 /* Save it as such */ 00894 Entry->DeadCharData[i] = 1; 00895 } 00896 else if (CharacterType == CHAR_OTHER_KEY) 00897 { 00898 /* Save it as such */ 00899 Entry->OtherCharData[i] = 1; 00900 } 00901 } 00902 00903 /* Check for sanity checks */ 00904 DPRINT1("]\n"); 00905 if (SanityCheck) 00906 { 00907 /* Not yet handled... */ 00908 printf("Sanity checks not yet handled!\n"); 00909 exit(1); 00910 } 00911 00912 /* Check if we had SGCAP data */ 00913 if (Entry->Cap & 2) 00914 { 00915 /* Not yet handled... */ 00916 printf("SGCAP state not yet handled!\n"); 00917 exit(1); 00918 } 00919 } 00920 00921 /* Process the scan code table */ 00922 Entry = &LayoutData->Entry[ScanCodeCount]; 00923 for (i = 0; i < 110; i++) 00924 { 00925 /* Get the scan code */ 00926 CurrentCode = ScVk[i].ScanCode; 00927 if (CurrentCode == 0xFFFF) break; 00928 00929 /* Check if this entry had been processed */ 00930 if (ScVk[i].Processed) 00931 { 00932 /* Skip it */ 00933 ScVk[i].Processed = FALSE; 00934 } 00935 else 00936 { 00937 /* Do we have too many? */ 00938 if (++ScanCodeCount >= 110) 00939 { 00940 /* Fail */ 00941 printf("ScanCode %02x - too many scancodes here to parse.\n", CurrentCode); 00942 exit(1); 00943 } 00944 00945 /* Build an entry for it */ 00946 Entry++; 00947 Entry->ScanCode = CurrentCode; 00948 Entry->VirtualKey = ScVk[i].VirtualKey; 00949 Entry->OriginalVirtualKey = ScVk[i].VirtualKey; 00950 Entry->Name = ScVk[i].Name; 00951 Entry->Processed = TRUE; 00952 Entry->LineCount = 0; 00953 DPRINT1("AUTOMATIC ENTRY: [%x %x %s]\n", 00954 Entry->VirtualKey, Entry->ScanCode, Entry->Name); 00955 } 00956 } 00957 00958 /* Skip what's left */ 00959 return KeyWord; 00960 } 00961 00962 ULONG 00963 DoParsing(VOID) 00964 { 00965 ULONG KeyWords[KEYWORD_COUNT]; 00966 ULONG KeyWord; 00967 ULONG StateCount; 00968 ULONG ShiftStates[8]; 00969 PKEYNAME DescriptionData = NULL, LanguageData = NULL; 00970 PKEYNAME KeyNameData = NULL, KeyNameExtData = NULL, KeyNameDeadData = NULL; 00971 PVOID AttributeData = NULL, LigatureData = NULL, DeadKeyData = NULL; 00972 00973 /* Parse keywords */ 00974 gLineCount = 0; 00975 KeyWord = SkipLines(); 00976 if (KeyWord >= KEYWORD_COUNT) 00977 { 00978 /* Invalid keyword count, fail */ 00979 fclose(gfpInput); 00980 printf("No keywords were found in '%s'.\n", gpszFileName); 00981 exit(1); 00982 } 00983 00984 /* Now parse the keywords */ 00985 while (KeyWord < (KEYWORD_COUNT - 1)) 00986 { 00987 /* Save this keyword */ 00988 KeyWords[KeyWord]++; 00989 00990 /* Check for duplicate entires, other than DEADKEY, which is okay */ 00991 if ((KeyWord != 9) && (KeyWords[KeyWord] > 1) && (Verbose)) 00992 { 00993 /* On a verbose run, warn the user */ 00994 printf("The '%s' keyword appeared multiple times.\n", 00995 KeyWordList[KeyWord]); 00996 } 00997 00998 /* Now parse this keyword */ 00999 switch (KeyWord) 01000 { 01001 /* KBD */ 01002 case 0: 01003 01004 DPRINT1("Found KBD section\n"); 01005 KeyWord = DoKBD(); 01006 break; 01007 01008 /* VERSION */ 01009 case 1: 01010 01011 DPRINT1("Found VERSION section\n"); 01012 KeyWord = DoVERSION(); 01013 break; 01014 01015 /* COPYRIGHT */ 01016 case 2: 01017 01018 DPRINT1("Found COPYRIGHT section\n"); 01019 KeyWord = DoCOPYRIGHT(); 01020 break; 01021 01022 /* COMPANY */ 01023 case 3: 01024 01025 DPRINT1("Found COMPANY section\n"); 01026 KeyWord = DoCOMPANY(); 01027 break; 01028 01029 /* LOCALENAME */ 01030 case 4: 01031 01032 DPRINT1("Found LOCALENAME section\n"); 01033 KeyWord = DoLOCALENAME(); 01034 break; 01035 01036 /* MODIFIERS */ 01037 case 5: 01038 01039 DPRINT1("Found MODIFIERS section\n"); 01040 KeyWord = DoMODIFIERS(); 01041 break; 01042 01043 /* SHIFTSTATE */ 01044 case 6: 01045 01046 DPRINT1("Found SHIFTSTATE section\n"); 01047 KeyWord = DoSHIFTSTATE(&StateCount, ShiftStates); 01048 if (StateCount < 2) 01049 { 01050 /* Fail */ 01051 fclose(gfpInput); 01052 printf("ERROR"); 01053 exit(1); 01054 } 01055 break; 01056 01057 /* ATTRIBUTES */ 01058 case 7: 01059 01060 DPRINT1("Found ATTRIBUTES section\n"); 01061 KeyWord = DoATTRIBUTES(&AttributeData); 01062 break; 01063 01064 /* LAYOUT */ 01065 case 8: 01066 01067 DPRINT1("Found LAYOUT section\n"); 01068 KeyWord = DoLAYOUT(&g_Layout, 01069 &LigatureData, 01070 ShiftStates, 01071 StateCount); 01072 break; 01073 01074 /* DEADKEY */ 01075 case 9: 01076 01077 DPRINT1("Found DEADKEY section\n"); 01078 KeyWord = DoDEADKEY(&DeadKeyData); 01079 break; 01080 01081 /* LIGATURE */ 01082 case 10: 01083 01084 DPRINT1("Found LIGATURE section\n"); 01085 KeyWord = DoLIGATURE(&LigatureData); 01086 break; 01087 01088 /* KEYNAME */ 01089 case 11: 01090 01091 DPRINT1("Found KEYNAME section\n"); 01092 KeyWord = DoKEYNAME(&KeyNameData); 01093 break; 01094 01095 /* KEYNAME_EXT */ 01096 case 12: 01097 01098 DPRINT1("Found KEYNAME_EXT section\n"); 01099 KeyWord = DoKEYNAME(&KeyNameExtData); 01100 break; 01101 01102 /* KEYNAME_DEAD */ 01103 case 13: 01104 01105 DPRINT1("Found KEYNAME_DEAD section\n"); 01106 KeyWord = DoKEYNAME(&KeyNameDeadData); 01107 break; 01108 01109 /* DESCRIPTIONS */ 01110 case 14: 01111 01112 DPRINT1("Found DESCRIPTIONS section\n"); 01113 KeyWord = DoDESCRIPTIONS(&DescriptionData); 01114 break; 01115 01116 /* LANGUAGENAMES */ 01117 case 15: 01118 01119 DPRINT1("Found LANGUAGENAMES section\n"); 01120 KeyWord = DoLANGUAGENAMES(&LanguageData); 01121 break; 01122 01123 /* ENDKBD */ 01124 case 16: 01125 01126 DPRINT1("Found ENDKBD section\n"); 01127 KeyWord = SkipLines(); 01128 break; 01129 01130 01131 default: 01132 break; 01133 } 01134 } 01135 01136 /* We are done */ 01137 fclose(gfpInput); 01138 01139 /* Now enter the output phase */ 01140 return DoOutput(StateCount, 01141 ShiftStates, 01142 DescriptionData, 01143 LanguageData, 01144 AttributeData, 01145 DeadKeyData, 01146 LigatureData, 01147 KeyNameData, 01148 KeyNameExtData, 01149 KeyNameDeadData); 01150 } 01151 /* EOF */ Generated on Sat May 26 2012 04:16:18 for ReactOS by
1.7.6.1
|