+/**\r
+ Parses a line from a MAN file to see if it is the Title Header. If it is, then\r
+ if the "Brief Description" is desired, allocate a buffer for it and return a\r
+ copy. Upon a sucessful return the caller is responsible to free the memory in\r
+ *BriefDesc\r
+\r
+ Uses a simple state machine that allows "unlimited" whitespace before and after the\r
+ ".TH", compares Command and the MAN file commnd name without respect to case, and\r
+ allows "unlimited" whitespace and '0' and '1' characters before the Short Description.\r
+ The PCRE regex describing this functionality is: ^\s*\.TH\s+(\S)\s[\s01]*(.*)$\r
+ where group 1 is the Command Name and group 2 is the Short Description.\r
+\r
+ @param[in] Command name of command whose MAN file we think Line came from\r
+ @param[in] Line Pointer to a line from the MAN file\r
+ @param[out] BriefDesc pointer to pointer to string where description goes.\r
+ @param[out] BriefSize pointer to size of allocated BriefDesc\r
+ @param[out] Found TRUE if the Title Header was found and it belongs to Command\r
+\r
+ @retval TRUE Line contained the Title Header\r
+ @retval FALSE Line did not contain the Title Header\r
+**/\r
+BOOLEAN\r
+IsTitleHeader(\r
+ IN CONST CHAR16 *Command,\r
+ IN CHAR16 *Line,\r
+ OUT CHAR16 **BriefDesc OPTIONAL,\r
+ OUT UINTN *BriefSize OPTIONAL,\r
+ OUT BOOLEAN *Found\r
+ )\r
+{\r
+ // The states of a simple state machine used to recognize a title header line\r
+ // and to extract the Short Description, if desired.\r
+ typedef enum {\r
+ LookForThMacro, LookForCommandName, CompareCommands, GetBriefDescription, Final\r
+ } STATEVALUES;\r
+\r
+ STATEVALUES State;\r
+ UINTN CommandIndex; // Indexes Command as we compare its chars to the MAN file.\r
+ BOOLEAN ReturnValue; // TRUE if this the Title Header line of *some* MAN file.\r
+ BOOLEAN ReturnFound; // TRUE if this the Title Header line of *the desired* MAN file.\r
+\r
+ ReturnValue = FALSE;\r
+ ReturnFound = FALSE;\r
+ CommandIndex = 0;\r
+ State = LookForThMacro;\r
+\r
+ do {\r
+\r
+ if (*Line == L'\0') {\r
+ break;\r
+ }\r
+\r
+ switch (State) {\r
+\r
+ // Handle "^\s*.TH\s"\r
+ // Go to state LookForCommandName if the title header macro is present; otherwise,\r
+ // eat white space. If we see something other than white space, this is not a\r
+ // title header line.\r
+ case LookForThMacro:\r
+ if (StrnCmp (L".TH ", Line, 4) == 0 || StrnCmp (L".TH\t", Line, 4) == 0) {\r
+ Line += 4;\r
+ State = LookForCommandName;\r
+ }\r
+ else if (*Line == L' ' || *Line == L'\t') {\r
+ Line++;\r
+ }\r
+ else {\r
+ State = Final;\r
+ }\r
+ break;\r
+\r
+ // Handle "\s*"\r
+ // Eat any "extra" whitespace after the title header macro (we have already seen\r
+ // at least one white space character). Go to state CompareCommands when a\r
+ // non-white space is seen.\r
+ case LookForCommandName:\r
+ if (*Line == L' ' || *Line == L'\t') {\r
+ Line++;\r
+ }\r
+ else {\r
+ ReturnValue = TRUE; // This is *some* command's title header line.\r
+ State = CompareCommands;\r
+ // Do not increment Line; it points to the first character of the command\r
+ // name on the title header line.\r
+ }\r
+ break;\r
+\r
+ // Handle "(\S)\s"\r
+ // Compare Command to the title header command name, ignoring case. When we\r
+ // reach the end of the command (i.e. we see white space), the next state\r
+ // depends on whether the caller wants a copy of the Brief Description.\r
+ case CompareCommands:\r
+ if (*Line == L' ' || *Line == L'\t') {\r
+ ReturnFound = TRUE; // This is the desired command's title header line.\r
+ State = (BriefDesc == NULL) ? Final : GetBriefDescription;\r
+ }\r
+ else if (InternalShellCharToUpper (*Line) != InternalShellCharToUpper (*(Command + CommandIndex++))) {\r
+ State = Final;\r
+ }\r
+ Line++;\r
+ break;\r
+\r
+ // Handle "[\s01]*(.*)$"\r
+ // Skip whitespace, '0', and '1' characters, if any, prior to the brief description.\r
+ // Return the description to the caller.\r
+ case GetBriefDescription:\r
+ if (*Line != L' ' && *Line != L'\t' && *Line != L'0' && *Line != L'1') {\r
+ *BriefSize = StrSize(Line);\r
+ *BriefDesc = AllocateZeroPool(*BriefSize);\r
+ if (*BriefDesc != NULL) {\r
+ StrCpyS(*BriefDesc, (*BriefSize)/sizeof(CHAR16), Line);\r
+ }\r
+ State = Final;\r
+ }\r
+ Line++;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ } while (State < Final);\r
+\r
+ *Found = ReturnFound;\r
+ return ReturnValue;\r
+}\r
+\r