ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

parser.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.