diff options
Diffstat (limited to 'private/windows/diamond/format.c')
-rw-r--r-- | private/windows/diamond/format.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/private/windows/diamond/format.c b/private/windows/diamond/format.c new file mode 100644 index 000000000..4037f76ee --- /dev/null +++ b/private/windows/diamond/format.c @@ -0,0 +1,185 @@ +/*** format.c - Parameter Formatter + * + * Microsoft Confidential + * Copyright (C) Microsoft Corporation 1994 + * All Rights Reserved. + * + * Author: + * Benjamin W. Slivka + * + * History: + * 28-Apr-1994 bens Initial version + * 10-May-1994 bens Add braces support + */ + +#include <memory.h> +#include <string.h> + +#include "types.h" +#include "asrt.h" +#include "error.h" +#include "message.h" +#include "misc.h" + +#include "inf.h" +#include "format.h" +#include "format.msg" + + +/*** SubstituteFormatString - Do parameter substitution + * + * NOTE: See format.h for entry/exit conditions. + */ +BOOL SubstituteFormatString(char *pszDst, + int cbDst, + char *pszSrc, + PFNFORMATPARM pfnfp, + void *pv, + PERROR perr) +{ + char achParmName[cbPARM_NAME_MAX]; + int cb; + int cch; + BOOL fParmSeen; // TRUE => parm seen in {braces} + BOOL fParmEmpty; // TRUE => all parms were empty in {opt} + char *pch; + char *pszAfterParm; // Points to first char after var subst. + char *pszOptStart; // Start of optional text + char *pszParmStart; // Points to first * in var substitution + + //** Not in conditional test + pszOptStart = NULL; + + //** Process string for parameters and conditional text + while (*pszSrc != '\0') { + switch (*pszSrc) { + + case chFP_LBRACE: + pszSrc++; // Eat the left brace + if (*pszSrc == chFP_LBRACE) { // Have "{{" + //** Collapse two {{ into one { + if (!copyBounded(&pszDst,&cbDst,&pszSrc,1)) { + goto error_copying; + } + } + else { + //** Make sure we're not already in a brace section + if (pszOptStart) { + ErrSet(perr,pszFMTERR_NESTED_BRACES,"%c%s", + chFP_LBRACE,pszSrc); + return FALSE; + } + pszOptStart = pszDst; // Save start of conditional text + fParmSeen = FALSE; // No parm seen, yet + fParmEmpty = TRUE; // Assume parm was empty + } + break; + + case chFP_RBRACE: + pszSrc++; // Eat the right brace + if (*pszSrc == chFP_RBRACE) { // Have "}}" + //** Collapse two }} into one } + if (!copyBounded(&pszDst,&cbDst,&pszSrc,1)) { + goto error_copying; + } + } + else { + //** Make sure we are in a brace section + if (!pszOptStart) { + ErrSet(perr,pszFMTERR_RIGHT_WITH_NO_LEFT,"%c%c%s", + chFP_RBRACE,chFP_LBRACE,pszSrc); + return FALSE; + } + //** Omit text if we need to + if (fParmSeen && fParmEmpty) { // All parms were empty + //** Remove optional text + Assert(pszDst >= pszOptStart); + cbDst += pszDst - pszOptStart; + pszDst = pszOptStart; + } + //** Reset state variables + pszOptStart = NULL; + } + break; + + case chFP_MARKER: + pszParmStart = pszSrc; // Save start for error messgages + pszSrc++; // Skip first * + if (*pszSrc == chFP_MARKER) { // Have "**" + //** Collapse two ** into one * + if (!copyBounded(&pszDst,&cbDst,&pszSrc,1)) { + goto error_copying; + } + } + else { + //** Attempt parameter substitution + pch = strchr(pszSrc,chFP_MARKER); // Finding ending * + if (!pch) { // No terminating * + ErrSet(perr,pszFMTERR_MISSING_SUBST,"%c%s", + chFP_MARKER,pszParmStart); + return FALSE; + } + pszAfterParm = pch+1; // Point after ending * + + //** Extract parameter name + cch = pch - pszSrc; // Length of parameter name + if (cch >= sizeof(achParmName)) { + ErrSet(perr,pszFMTERR_PARM_NAME_TOO_LONG,"%d%s", + sizeof(achParmName)-1,pszParmStart); + return FALSE; + } + memcpy(achParmName,pszSrc,cch); // Copy it + achParmName[cch] = '\0'; // Terminate it + + //** Get parameter value + if (-1 == (cb = (*pfnfp)(pszDst, // Destination + cbDst, // Space remaining + achParmName, // Parm name + pv, // Context + perr))) { + return FALSE; // Error already filled in + } + //** Adjust output buffer and space remaining + // NOTE: Don't count NUL byte, as we do that at the very end + Assert(cbDst >= cb); + pszDst += cb; + cbDst -= cb; + + //** Remember we saw a parm, and if it was not empty + fParmSeen = TRUE; + if (cb > 0) { + fParmEmpty = FALSE; // At least one parm not empty + } + + //** Skip over parameter name + pszSrc = pszAfterParm; + } + break; + + default: + //** Just copy the character + if (!copyBounded(&pszDst,&cbDst,&pszSrc,1)) { + goto error_copying; + } + } + } /* while */ + + //** Make sure we didn't leave an open optional text section + if (pszOptStart) { + ErrSet(perr,pszFMTERR_MISSING_RIGHT_BRACE,"%c",chFP_RBRACE); + return FALSE; + } + + //** Terminate processed string + if (cbDst == 0) { // No room for terminator + goto error_copying; + } + *pszDst++ = '\0'; // Terminate string + + //** Success + return TRUE; + +error_copying: + ErrSet(perr,pszFMTERR_COPYING_OVERFLOW,"%s",pszSrc); + return FALSE; +} /* SubstituteFormatString() */ |