Example #1
0
static BOOL CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
 LPCWSTR *ppszError)
{
    BOOL ret = TRUE;

    while (*str && isspaceW(*str))
        str++;
    if (*str)
    {
        token->start = str;
        while (*str && *str != '=' && !isspaceW(*str))
            str++;
        if (*str && (*str == '=' || isspaceW(*str)))
            token->end = str;
        else
        {
            TRACE("missing equals char at %s\n", debugstr_w(token->start));
            if (ppszError)
                *ppszError = token->start;
            SetLastError(CRYPT_E_INVALID_X500_STRING);
            ret = FALSE;
        }
    }
    else
        token->start = NULL;
    return ret;
}
Example #2
0
static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
 LPCWSTR *ppszError)
{
    DWORD ret = ERROR_SUCCESS;

    while (*str && isspaceW(*str))
        str++;
    if (*str)
    {
        token->start = str;
        while (*str && *str != '=' && !isspaceW(*str))
            str++;
        if (*str && (*str == '=' || isspaceW(*str)))
            token->end = str;
        else
        {
            TRACE("missing equals char at %s\n", debugstr_w(token->start));
            if (ppszError)
                *ppszError = token->start;
            ret = CRYPT_E_INVALID_X500_STRING;
        }
    }
    else
        token->start = NULL;
    return ret;
}
Example #3
0
/******************************************************************************
 * This function is a wrapper for the setValue function.  It prepares the
 * land and cleans the area once completed.
 * Note: this function modifies the line parameter.
 *
 * line - registry file unwrapped line. Should have the registry value name and
 *      complete registry value data.
 */
static void processSetValue(WCHAR* line, BOOL is_unicode)
{
    WCHAR* val_name;                   /* registry value name   */
    WCHAR* val_data;                   /* registry value data   */
    int line_idx = 0;                 /* current character under analysis */
    LONG res;

    /* get value name */
    while ( isspaceW(line[line_idx]) ) line_idx++;
    if (line[line_idx] == '@' && line[line_idx + 1] == '=') {
        line[line_idx] = '\0';
        val_name = line;
        line_idx++;
    } else if (line[line_idx] == '\"') {
        line_idx++;
        val_name = line + line_idx;
        while (line[line_idx]) {
            if (line[line_idx] == '\\')   /* skip escaped character */
            {
                line_idx += 2;
            } else {
                if (line[line_idx] == '\"') {
                    line[line_idx] = '\0';
                    line_idx++;
                    break;
                } else {
                    line_idx++;
                }
            }
        }
        while ( isspaceW(line[line_idx]) ) line_idx++;
        if (!line[line_idx]) {
            output_message(STRING_UNEXPECTED_EOL, line);
            return;
        }
        if (line[line_idx] != '=') {
            line[line_idx] = '\"';
            output_message(STRING_UNRECOGNIZED_LINE, line);
            return;
        }

    } else {
        output_message(STRING_UNRECOGNIZED_LINE, line);
        return;
    }
    line_idx++;                   /* skip the '=' character */

    while ( isspaceW(line[line_idx]) ) line_idx++;
    val_data = line + line_idx;
    /* trim trailing blanks */
    line_idx = strlenW(val_data);
    while (line_idx > 0 && isspaceW(val_data[line_idx-1])) line_idx--;
    val_data[line_idx] = '\0';

    REGPROC_unescape_string(val_name);
    res = setValue(val_name, val_data, is_unicode);
    if ( res != ERROR_SUCCESS )
        output_message(STRING_SETVALUE_FAILED, val_name, currentKeyName);
}
Example #4
0
static HRESULT WINAPI wb_BreakText( IWordBreaker *iface,
         TEXT_SOURCE *ts, IWordSink *pWordSink, IPhraseSink *pPhraseSink)
{
    UINT len, state = 0;
    WCHAR ch;

    TRACE("%p %p %p\n", ts, pWordSink, pPhraseSink);

    if (pPhraseSink)
        FIXME("IPhraseSink won't be called\n");

    do
    {
        len = 0;
        while ((ts->iCur + len) < ts->iEnd)
        {
            ch = ts->awcBuffer[ts->iCur + len];

            switch (state)
            {
            case 0: /* skip spaces and punctuation */

                if (!ch || ispunctW(ch) || isspaceW(ch))
                    ts->iCur ++;
                else
                    state = 1;
                break;

            case 1: /* find the end of the word */

                if (ch && !ispunctW(ch) && !isspaceW(ch))
                    len++;
                else
                {
                    call_sink( pWordSink, ts, len );
                    len = 0;
                    state = 0;
                }
                break;

            }
        }
        call_sink( pWordSink, ts, len );

    } while (S_OK == ts->pfnFillTextBuffer( ts ));

    return S_OK;
}
Example #5
0
File: lex.c Project: mikekap/wine
static void skip_spaces(parser_ctx_t *ctx)
{
    while(ctx->ptr < ctx->end && isspaceW(*ctx->ptr)) {
        if(is_endline(*ctx->ptr++))
            ctx->nl = TRUE;
    }
}
Example #6
0
DWORD
GetFunctionPointer(
    IN PWSTR InstallerName,
    OUT HMODULE* ModulePointer,
    OUT PVOID* FunctionPointer)
{
    HMODULE hModule = NULL;
    LPSTR FunctionNameA = NULL;
    PWCHAR Comma;
    DWORD rc;

    *ModulePointer = NULL;
    *FunctionPointer = NULL;

    Comma = strchrW(InstallerName, ',');
    if (!Comma)
    {
        rc = ERROR_INVALID_PARAMETER;
        goto cleanup;
    }

    /* Load library */
    *Comma = '\0';
    hModule = LoadLibraryW(InstallerName);
    *Comma = ',';
    if (!hModule)
    {
        rc = GetLastError();
        goto cleanup;
    }

    /* Skip comma spaces */
    while (*Comma == ',' || isspaceW(*Comma))
        Comma++;

    /* W->A conversion for function name */
    FunctionNameA = pSetupUnicodeToMultiByte(Comma, CP_ACP);
    if (!FunctionNameA)
    {
        rc = GetLastError();
        goto cleanup;
    }

    /* Search function */
    *FunctionPointer = GetProcAddress(hModule, FunctionNameA);
    if (!*FunctionPointer)
    {
        rc = GetLastError();
        goto cleanup;
    }

    *ModulePointer = hModule;
    rc = ERROR_SUCCESS;

cleanup:
    if (rc != ERROR_SUCCESS && hModule)
        FreeLibrary(hModule);
    MyFree(FunctionNameA);
    return rc;
}
Example #7
0
File: shape.c Project: Jactry/wine
static HRESULT default_set_text_glyphs_props(struct scriptshaping_context *context, UINT16 *clustermap, UINT16 *glyph_indices,
                                     UINT32 glyphcount, DWRITE_SHAPING_TEXT_PROPERTIES *text_props, DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props)
{
    UINT32 i;

    for (i = 0; i < glyphcount; i++) {
        UINT32 char_index[20];
        UINT32 char_count = 0;
        INT32 k;

        k = map_glyph_to_text_pos(clustermap, context->length, i);
        if (k >= 0) {
            for (; k < context->length && clustermap[k] == i; k++)
                char_index[char_count++] = k;
        }

        if (char_count == 0)
            continue;

        if (char_count == 1 && isspaceW(context->text[char_index[0]])) {
            glyph_props[i].justification = SCRIPT_JUSTIFY_BLANK;
            text_props[char_index[0]].isShapedAlone = context->text[char_index[0]] == ' ';
        }
        else
            glyph_props[i].justification = SCRIPT_JUSTIFY_CHARACTER;
    }

    /* FIXME: update properties using GDEF table */
    shape_update_clusters_from_glyphprop(glyphcount, context->length, clustermap, glyph_props);

    return S_OK;
}
Example #8
0
static HRESULT WINAPI WshShortcut_put_IconLocation(IWshShortcut *iface, BSTR IconPath)
{
    WshShortcut *This = impl_from_IWshShortcut(iface);
    HRESULT hr;
    WCHAR *ptr;
    BSTR path;
    INT icon;

    TRACE("(%p)->(%s)\n", This, debugstr_w(IconPath));

    /* scan for icon id */
    ptr = strrchrW(IconPath, ',');
    if (!ptr)
    {
        WARN("icon index not found\n");
        return E_FAIL;
    }

    path = SysAllocStringLen(IconPath, ptr-IconPath);

    /* skip spaces if any */
    while (isspaceW(*++ptr))
        ;

    icon = atoiW(ptr);

    hr = IShellLinkW_SetIconLocation(This->link, path, icon);
    SysFreeString(path);

    return hr;
}
Example #9
0
/* Assumes separators are characters in the 0-255 range */
static BOOL CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
 struct X500TokenW *token, LPCWSTR *ppszError)
{
    BOOL ret = TRUE;

    TRACE("(%s, %s, %p, %p)\n", debugstr_w(str), debugstr_w(separators), token,
     ppszError);

    while (*str && isspaceW(*str))
        str++;
    if (*str)
    {
        token->start = str;
        if (!(dwFlags & CERT_NAME_STR_NO_QUOTING_FLAG) && *str == '"')
        {
            token->end = NULL;
            str++;
            while (!token->end && ret)
            {
                while (*str && *str != '"')
                    str++;
                if (*str == '"')
                {
                    if (*(str + 1) != '"')
                        token->end = str + 1;
                    else
                        str += 2;
                }
                else
                {
                    TRACE("unterminated quote at %s\n", debugstr_w(str));
                    if (ppszError)
                        *ppszError = str;
                    SetLastError(CRYPT_E_INVALID_X500_STRING);
                    ret = FALSE;
                }
            }
        }
        else
        {
            WCHAR map[256] = { 0 };

            while (*separators)
                map[*separators++] = 1;
            while (*str && (*str >= 0xff || !map[*str]))
                str++;
            token->end = str;
        }
    }
    else
    {
        TRACE("missing value at %s\n", debugstr_w(str));
        if (ppszError)
            *ppszError = str;
        SetLastError(CRYPT_E_INVALID_X500_STRING);
        ret = FALSE;
    }
    return ret;
}
Example #10
0
static BOOL skip_spaces(parser_ctx_t *ctx)
{
    while(ctx->ptr < ctx->end && (isspaceW(*ctx->ptr) || *ctx->ptr == 0xFEFF /* UTF16 BOM */)) {
        if(is_endline(*ctx->ptr++))
            ctx->nl = TRUE;
    }

    return ctx->ptr != ctx->end;
}
Example #11
0
/* find the directory that contains the file being run */
static LPWSTR RunDlg_GetParentDir(LPCWSTR cmdline)
{
    const WCHAR *src;
    WCHAR *dest, *result, *result_end=NULL;
    static const WCHAR dotexeW[] = L".exe";

    result = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(strlenW(cmdline)+5));

    if (NULL == result)
    {
        TRACE("HeapAlloc couldn't allocate %d bytes\n", sizeof(WCHAR)*(strlenW(cmdline)+5));
        return NULL;
    }

    src = cmdline;
    dest = result;

    if (*src == '"')
    {
        src++;
        while (*src && *src != '"')
        {
            if (*src == '\\')
                result_end = dest;
            *dest++ = *src++;
        }
    }
    else {
        while (*src)
        {
            if (isspaceW(*src))
            {
                *dest = 0;
                if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result))
                    break;
                strcatW(dest, dotexeW);
                if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result))
                    break;
            }
            else if (*src == '\\')
                result_end = dest;
            *dest++ = *src++;
        }
    }

    if (result_end)
    {
        *result_end = 0;
        return result;
    }
    else
    {
        HeapFree(GetProcessHeap(), 0, result);
        return NULL;
    }
}
Example #12
0
static int copy_path_string(LPWSTR target, LPWSTR source)
{
    INT i = 0;

    while (isspaceW(*source)) source++;

    if (*source == '\"')
    {
        source ++;
        while (*source != '\"') target[i++] = *source++;
        target[i] = 0;
        source ++;
        i+=2;
    }
    else
    {
        while (*source && !isspaceW(*source)) target[i++] = *source++;
        target[i] = 0;
    }
    return i;
}
Example #13
0
/* handler for parser KEY_NAME state */
static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p, *token_end = parser->start;

    for (p = pos; !is_eol( parser, p ); p++)
    {
        if (*p == ',') break;
        switch(*p)
        {

         case '=':
            push_token( parser, token_end );
            if (!add_field_from_token( parser, 1 )) return NULL;
            parser->start = p + 1;
            push_state( parser, VALUE_NAME );
            set_state( parser, LEADING_SPACES );
            return p + 1;
        case ';':
            push_token( parser, token_end );
            if (!add_field_from_token( parser, 0 )) return NULL;
            push_state( parser, LINE_START );
            set_state( parser, COMMENT );
            return p + 1;
        case '"':
            push_token( parser, token_end );
            parser->start = p + 1;
            push_state( parser, KEY_NAME );
            set_state( parser, QUOTES );
            return p + 1;
        case '\\':
            push_token( parser, token_end );
            parser->start = p;
            push_state( parser, KEY_NAME );
            set_state( parser, EOL_BACKSLASH );
            return p;
        default:
            if (!isspaceW(*p)) token_end = p + 1;
            else
            {
                push_token( parser, p );
                push_state( parser, KEY_NAME );
                set_state( parser, TRAILING_SPACES );
                return p;
            }
            break;
        }
    }
    push_token( parser, token_end );
    set_state( parser, VALUE_NAME );
    return p;
}
Example #14
0
static HRESULT get_word(LPCOLESTR *str, strbuf *buf)
{
    LPCOLESTR iter, iter2 = *str;

    buf->len = 0;
    buf->str[0] = '\0';

    while(isspaceW(*iter2))
        iter2++;
    iter = iter2;
    if(!*iter) {
        *str = iter;
        return S_OK;
    }

    if(*iter == '}' || *iter == '=') {
        strbuf_write(iter++, buf, 1);
    }else if(*iter == '\'') {
        iter2 = ++iter;
        iter = strchrW(iter, '\'');
        if(!iter) {
            WARN("Unexpected end of script\n");
            *str = iter;
            return DISP_E_EXCEPTION;
        }
        strbuf_write(iter2, buf, iter-iter2);
        iter++;
    }else {
        while(*iter && !isspaceW(*iter))
            iter++;
        strbuf_write(iter2, buf, iter-iter2);
    }

    while(isspaceW(*iter))
        iter++;
    *str = iter;
    return S_OK;
}
Example #15
0
/* handler for parser TRAILING_SPACES state */
static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos )
{
  const WCHAR *p;

  for (p = pos; !is_eol( parser, p ); p++)
    {
      if (*p == '\\')
        {
          set_state( parser, EOL_BACKSLASH );
          return p;
        }
      if (!isspaceW(*p))
        break;
    }
  pop_state( parser );
  return p;
}
Example #16
0
/* handler for parser LINE_START state */
static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos )
{
  const WCHAR *p;

  for (p = pos; !is_eof( parser, p ); p++)
    {
      switch(*p)
        {
          case '\r':
            continue;

          case '\n':
            parser->line_pos++;
            close_current_line( parser );
            break;

          case ';':
            push_state( parser, LINE_START );
            set_state( parser, COMMENT );
            return p + 1;

          case '[':
            parser->start = p + 1;
            set_state( parser, SECTION_NAME );
            return p + 1;

          default:
            if (!isspaceW(*p))
              {
                parser->start = p;
                set_state( parser, KEY_NAME );
                return p;
              }
            break;
        }
    }
  close_current_line( parser );
  return NULL;
}
Example #17
0
/* handler for parser EOL_BACKSLASH state */
static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos )
{
  const WCHAR *p;

  for (p = pos; !is_eof( parser, p ); p++)
    {
      switch(*p)
        {
          case '\r':
            continue;

          case '\n':
            parser->line_pos++;
            parser->start = p + 1;
            set_state( parser, LEADING_SPACES );
            return p + 1;

          case '\\':
            continue;

          case ';':
            push_state( parser, EOL_BACKSLASH );
            set_state( parser, COMMENT );
            return p + 1;

          default:
            if (isspaceW(*p))
              continue;
            push_token( parser, p );
            pop_state( parser );
            return p;
        }
    }
  parser->start = p;
  pop_state( parser );

  return p;
}
Example #18
0
/*********************************************************************
 *      _wtoi64   (NTDLL.@)
 *
 * Converts a unicode string to a large integer.
 *
 * PARAMS
 *  str [I] Wstring to be converted
 *
 * RETURNS
 *  On success it returns the integer value otherwise it returns 0.
 *
 * NOTES
 *  Accepts: {whitespace} [+|-] {digits}
 *  No check is made for value overflow, only the lower 64 bits are assigned.
 *  If str is NULL it crashes, as the native function does.
 */
LONGLONG  __cdecl _wtoi64( LPCWSTR str )
{
    ULONGLONG RunningTotal = 0;
    char bMinus = 0;

    while (isspaceW(*str)) {
	str++;
    } /* while */

    if (*str == '+') {
	str++;
    } else if (*str == '-') {
	bMinus = 1;
	str++;
    } /* if */

    while (*str >= '0' && *str <= '9') {
	RunningTotal = RunningTotal * 10 + *str - '0';
	str++;
    } /* while */

    return bMinus ? -RunningTotal : RunningTotal;
}
Example #19
0
UBOOL AfoDetect
    (LPWCHAR         lpwszLine,         // Ptr to the AFO text
     LPAFODETECT_STR lpafoDetectStr)    // Ptr to AFO Detect struc

{
    APLNELM       aplNELM;              // NELM of lpwszLine
    UINT          uChar;                // Loop counter
    WCHAR         wchOrig;              // The original char
    AFOCOLINDICES colIndex;             // The translated char for tokenization as a AFOCOL_*** value
    AFO_ACTION    afoAction1_EM,        // Ptr to primary action routine
                  afoAction2_EM;        // ...    secondary ...
    AFOLOCALVARS  afoLocalVars = {0};   // Local vars
    UBOOL         bRet;                 // TRUE iff the input is an AFO

    // Get the length
    aplNELM = lstrlenW (lpwszLine);

    // Save local vars in struct which we pass to each FSA action routine
    afoLocalVars.State           = AFOROW_SOS;      // Initial state (Start-Of-Statement)
    afoLocalVars.lpwszOrig       = lpwszLine;       // Save ptr to start of input line
////afoLocalVars.lbrCount        = 0;               // Already zero from = {0}
    afoLocalVars.lpafoDetectStr  = lpafoDetectStr;  // Ptr to AFODETECT_STR

    // Initialize values
    lpafoDetectStr->uLastLineOff = 0;               // Initialize the last line offset
    lpafoDetectStr->numPhyLines  =                  // Initialize the counts
    lpafoDetectStr->numLogLines  = 1;               // ...

    // Skip over leading blanks (more to reduce clutter
    //   in the debugging window)
    for (uChar = 0; uChar < aplNELM; uChar++)
    if (!IsWhiteW (lpwszLine[uChar]))
        break;

    while (uChar <= aplNELM)
    {
        // Use a FSA to tokenize the line

        // Save current index (may be modified by an action)
        afoLocalVars.uChar = uChar;

        /* The FSA works as follows:

           1.  Get the next WCHAR from the input;
           2.  Translate it into a AFOCOL_*** index;
           3.  Use the current state as a row index and the
               above index as a column index into fsaActTableAFO,
               take the appropriate action.
           4.  Repeat until EOL or an error occurs.
         */

        if (uChar EQ aplNELM)
            wchOrig = WC_EOS;
        else
            wchOrig = lpwszLine[uChar];

        // Strip out EOL check so we don't confuse a zero-value char with EOL
        if (uChar EQ aplNELM)
            colIndex = AFOCOL_EOL;
        else
            colIndex = CharTransAFO (wchOrig);

        // Get the action function (if any) and new state
        afoAction1_EM      = fsaActTableAFO[afoLocalVars.State][colIndex].afoAction1;
        afoAction2_EM      = fsaActTableAFO[afoLocalVars.State][colIndex].afoAction2;
        afoLocalVars.State = fsaActTableAFO[afoLocalVars.State][colIndex].iNewState;

        // Check for primary action
        if (afoAction1_EM NE NULL
         && !(*afoAction1_EM) (&afoLocalVars))
            goto ERROR_EXIT;

        // Check for secondary action
        if (afoAction2_EM NE NULL
         && !(*afoAction2_EM) (&afoLocalVars))
            goto ERROR_EXIT;

        // Get next index (may have been modified by an action)
        uChar = afoLocalVars.uChar + 1;

        // Split cases based upon the return code
        switch (afoLocalVars.State)
        {
            case AFOROW_EXIT:
                // Check the trailing chars (if any)
                for (     ; uChar <= aplNELM; uChar++)
                // If the char is not a space, CR, or LF ...
                if (!isspaceW (lpwszLine[uChar])
                 && lpwszLine[uChar] NE WC_CR
                 && lpwszLine[uChar] NE WC_LF)
                    break;

                // Test for matched and properly nested grouping symbols, and
                //   proper trailing chars, and
                //   all bases touched
                bRet = (afoLocalVars.lbrCount EQ 0
                     && (lpwszLine[uChar] EQ WC_EOS
                      || lpwszLine[uChar] EQ UTF16_LAMP)
                     && afoLocalVars.bLbrAlpha
                     && afoLocalVars.bLbrAssign
                     && afoLocalVars.bLbrInit);
                if (bRet)
                    goto NORMAL_EXIT;
                else
                    goto ERROR_EXIT;

            case AFOROW_WSFULL:
                goto WSFULL_EXIT;

            default:
                break;
        } // End SWITCH
    } // End WHILE

    // We should never get here as we process the
    //   trailing zero in the input line which should
    //   exit from one of the actions with AFOROW_EXIT.
    DbgStop ();

WSFULL_EXIT:
    DbgBrk ();              // ***FINISHME***







ERROR_EXIT:
NORMAL_EXIT:
    return bRet;
} // End AfoDetect
Example #20
0
/******************************************************************************
 * This function is a wrapper for the setValue function.  It prepares the
 * land and cleans the area once completed.
 * Note: this function modifies the line parameter.
 *
 * line - registry file unwrapped line. Should have the registry value name and
 *      complete registry value data.
 */
static void processSetValue(WCHAR* line, BOOL is_unicode)
{
    WCHAR* val_name;                   /* registry value name   */
    WCHAR* val_data;                   /* registry value data   */
    int line_idx = 0;                 /* current character under analysis */
    LONG res;

    /* get value name */
    while ( isspaceW(line[line_idx]) ) line_idx++;
    if (line[line_idx] == '@' && line[line_idx + 1] == '=') {
        line[line_idx] = '\0';
        val_name = line;
        line_idx++;
    } else if (line[line_idx] == '\"') {
        line_idx++;
        val_name = line + line_idx;
        while (line[line_idx]) {
            if (line[line_idx] == '\\')   /* skip escaped character */
            {
                line_idx += 2;
            } else {
                if (line[line_idx] == '\"') {
                    line[line_idx] = '\0';
                    line_idx++;
                    break;
                } else {
                    line_idx++;
                }
            }
        }
        while ( isspaceW(line[line_idx]) ) line_idx++;
        if (!line[line_idx]) {
            fprintf(stderr, "%s: warning: unexpected EOL\n", getAppName());
            return;
        }
        if (line[line_idx] != '=') {
            char* lineA;
            line[line_idx] = '\"';
            lineA = GetMultiByteString(line);
            fprintf(stderr,"%s: warning: unrecognized line: '%s'\n", getAppName(), lineA);
            HeapFree(GetProcessHeap(), 0, lineA);
            return;
        }

    } else {
        char* lineA = GetMultiByteString(line);
        fprintf(stderr,"%s: warning: unrecognized line: '%s'\n", getAppName(), lineA);
        HeapFree(GetProcessHeap(), 0, lineA);
        return;
    }
    line_idx++;                   /* skip the '=' character */

    while ( isspaceW(line[line_idx]) ) line_idx++;
    val_data = line + line_idx;
    /* trim trailing blanks */
    line_idx = strlenW(val_data);
    while (line_idx > 0 && isspaceW(val_data[line_idx-1])) line_idx--;
    val_data[line_idx] = '\0';

    REGPROC_unescape_string(val_name);
    res = setValue(val_name, val_data, is_unicode);
    if ( res != ERROR_SUCCESS )
    {
        char* val_nameA = GetMultiByteString(val_name);
        char* val_dataA = GetMultiByteString(val_data);
        fprintf(stderr,"%s: ERROR Key %s not created. Value: %s, Data: %s\n",
                getAppName(),
                currentKeyName,
                val_nameA,
                val_dataA);
        HeapFree(GetProcessHeap(), 0, val_nameA);
        HeapFree(GetProcessHeap(), 0, val_dataA);
    }
}
Example #21
0
/* ECMA-262 3rd Edition    9.3.1 */
static HRESULT str_to_number(BSTR str, VARIANT *ret)
{
    const WCHAR *ptr = str;
    BOOL neg = FALSE;
    DOUBLE d = 0.0;

    static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'};

    while(isspaceW(*ptr))
        ptr++;

    if(*ptr == '-') {
        neg = TRUE;
        ptr++;
    }else if(*ptr == '+') {
        ptr++;
    }

    if(!strncmpW(ptr, infinityW, sizeof(infinityW)/sizeof(WCHAR))) {
        ptr += sizeof(infinityW)/sizeof(WCHAR);
        while(*ptr && isspaceW(*ptr))
            ptr++;

        if(*ptr)
            num_set_nan(ret);
        else
            num_set_inf(ret, !neg);
        return S_OK;
    }

    if(*ptr == '0' && ptr[1] == 'x') {
        DWORD l = 0;

        ptr += 2;
        while((l = hex_to_int(*ptr)) != -1) {
            d = d*16 + l;
            ptr++;
        }

        num_set_val(ret, d);
        return S_OK;
    }

    while(isdigitW(*ptr))
        d = d*10 + (*ptr++ - '0');

    if(*ptr == 'e' || *ptr == 'E') {
        BOOL eneg = FALSE;
        LONG l = 0;

        ptr++;
        if(*ptr == '-') {
            ptr++;
            eneg = TRUE;
        }else if(*ptr == '+') {
            ptr++;
        }

        while(isdigitW(*ptr))
            l = l*10 + (*ptr++ - '0');
        if(eneg)
            l = -l;

        d *= pow(10, l);
    }else if(*ptr == '.') {
        DOUBLE dec = 0.1;

        ptr++;
        while(isdigitW(*ptr)) {
            d += dec * (*ptr++ - '0');
            dec *= 0.1;
        }
    }

    while(isspaceW(*ptr))
        ptr++;

    if(*ptr) {
        num_set_nan(ret);
        return S_OK;
    }

    if(neg)
        d = -d;

    num_set_val(ret, d);
    return S_OK;
}
Example #22
0
/*********************************************************************
 *		iswspace (NTDLL.@)
 *
 * Checks if a unicode char wc is a white space character
 *
 * RETURNS
 *  TRUE: The unicode char wc is a white space character.
 *  FALSE: Otherwise
 */
INT __cdecl NTDLL_iswspace( WCHAR wc )
{
    return isspaceW(wc);
}
/* ECMA-262 3rd Edition    9.3.1 */
static HRESULT str_to_number(jsstr_t *str, double *ret)
{
    const WCHAR *ptr = str->str;
    BOOL neg = FALSE;
    DOUBLE d = 0.0;

    static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'};

    if(!ptr) {
        *ret = 0;
        return S_OK;
    }

    while(isspaceW(*ptr))
        ptr++;

    if(*ptr == '-') {
        neg = TRUE;
        ptr++;
    }else if(*ptr == '+') {
        ptr++;
    }

    if(!strncmpW(ptr, infinityW, sizeof(infinityW)/sizeof(WCHAR))) {
        ptr += sizeof(infinityW)/sizeof(WCHAR);
        while(*ptr && isspaceW(*ptr))
            ptr++;

        if(*ptr)
            *ret = NAN;
        else
            *ret = neg ? -INFINITY : INFINITY;
        return S_OK;
    }

    if(*ptr == '0' && ptr[1] == 'x') {
        DWORD l = 0;

        ptr += 2;
        while((l = hex_to_int(*ptr)) != -1) {
            d = d*16 + l;
            ptr++;
        }

        *ret = d;
        return S_OK;
    }

    while(isdigitW(*ptr))
        d = d*10 + (*ptr++ - '0');

    if(*ptr == 'e' || *ptr == 'E') {
        BOOL eneg = FALSE;
        LONG l = 0;

        ptr++;
        if(*ptr == '-') {
            ptr++;
            eneg = TRUE;
        }else if(*ptr == '+') {
            ptr++;
        }

        while(isdigitW(*ptr))
            l = l*10 + (*ptr++ - '0');
        if(eneg)
            l = -l;

        d *= pow(10, l);
    }else if(*ptr == '.') {
        DOUBLE dec = 0.1;

        ptr++;
        while(isdigitW(*ptr)) {
            d += dec * (*ptr++ - '0');
            dec *= 0.1;
        }
    }

    while(isspaceW(*ptr))
        ptr++;

    if(*ptr) {
        *ret = NAN;
        return S_OK;
    }

    if(neg)
        d = -d;

    *ret = d;
    return S_OK;
}
Example #24
0
long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base )
{
  int negative;
  register unsigned long int cutoff;
  register unsigned int cutlim;
  register unsigned long int i;
  register const WCHAR *s;
  register WCHAR c;
  const WCHAR *save, *end;
  int overflow;

  if (base < 0 || base == 1 || base > 36) return 0;

  save = s = nptr;

  /* Skip white space.  */
  while (isspaceW (*s))
    ++s;
  if (!*s) goto noconv;

  /* Check for a sign.  */
  negative = 0;
  if (*s == '-')
    {
      negative = 1;
      ++s;
    }
  else if (*s == '+')
    ++s;

  /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
  if (*s == '0')
    {
      if ((base == 0 || base == 16) && toupperW(s[1]) == 'X')
	{
	  s += 2;
	  base = 16;
	}
      else if (base == 0)
	base = 8;
    }
  else if (base == 0)
    base = 10;

  /* Save the pointer so we can check later if anything happened.  */
  save = s;
  end = NULL;

  cutoff = ULONG_MAX / (unsigned long int) base;
  cutlim = ULONG_MAX % (unsigned long int) base;

  overflow = 0;
  i = 0;
  c = *s;
  for (;c != '\0'; c = *++s)
  {
      if (s == end)
          break;
      if (c >= '0' && c <= '9')
          c -= '0';
      else if (isalphaW (c))
          c = toupperW (c) - 'A' + 10;
      else
          break;
      if ((int) c >= base)
          break;
      /* Check for overflow.  */
      if (i > cutoff || (i == cutoff && c > cutlim))
          overflow = 1;
      else
      {
          i *= (unsigned long int) base;
          i += c;
      }
  }

  /* Check if anything actually happened.  */
  if (s == save)
    goto noconv;

  /* Store in ENDPTR the address of one character
     past the last character we converted.  */
  if (endptr != NULL)
    *endptr = (WCHAR *)s;

  /* Check for a value that is within the range of
     `unsigned LONG int', but outside the range of `LONG int'.  */
  if (overflow == 0
      && i > (negative
	      ? -((unsigned long int) (LONG_MIN + 1)) + 1
	      : (unsigned long int) LONG_MAX))
    overflow = 1;

  if (overflow)
    {
      return negative ? LONG_MIN : LONG_MAX;
    }

  /* Return the result of the appropriate sign.  */
  return negative ? -i : i;

noconv:
  /* We must handle a special case here: the base is 0 or 16 and the
     first two characters are '0' and 'x', but the rest are not
     hexadecimal digits.  This is no error case.  We return 0 and
     ENDPTR points to the `x`.  */
  if (endptr != NULL)
    {
      if (save - nptr >= 2 && toupperW (save[-1]) == 'X'
	  && save[-2] == '0')
	*endptr = (WCHAR *)&save[-1];
      else
	/*  There was no number to convert.  */
	*endptr = (WCHAR *)nptr;
    }

  return 0L;
}
Example #25
0
static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register)
{
    LPCOLESTR iter = *pstr;
    HRESULT hres;
    LONG lres;
    HKEY hkey = 0;
    strbuf name;
    
    enum {
        NORMAL,
        NO_REMOVE,
        IS_VAL,
        FORCE_REMOVE,
        DO_DELETE
    } key_type = NORMAL; 

    static const WCHAR wstrNoRemove[] = {'N','o','R','e','m','o','v','e',0};
    static const WCHAR wstrForceRemove[] = {'F','o','r','c','e','R','e','m','o','v','e',0};
    static const WCHAR wstrDelete[] = {'D','e','l','e','t','e',0};
    static const WCHAR wstrval[] = {'v','a','l',0};

    iter = *pstr;
    hres = get_word(&iter, buf);
    if(FAILED(hres))
        return hres;
    strbuf_init(&name);

    while(buf->str[1] || buf->str[0] != '}') {
        key_type = NORMAL;
        if(!lstrcmpiW(buf->str, wstrNoRemove))
            key_type = NO_REMOVE;
        else if(!lstrcmpiW(buf->str, wstrForceRemove))
            key_type = FORCE_REMOVE;
        else if(!lstrcmpiW(buf->str, wstrval))
            key_type = IS_VAL;
        else if(!lstrcmpiW(buf->str, wstrDelete))
            key_type = DO_DELETE;

        if(key_type != NORMAL) {
            hres = get_word(&iter, buf);
            if(FAILED(hres))
                break;
        }
        TRACE("name = %s\n", debugstr_w(buf->str));
    
        if(do_register) {
            if(key_type == IS_VAL) {
                hkey = parent_key;
                strbuf_write(buf->str, &name, -1);
            }else if(key_type == DO_DELETE) {
                TRACE("Deleting %s\n", debugstr_w(buf->str));
                lres = RegDeleteTreeW(parent_key, buf->str);
            }else {
                if(key_type == FORCE_REMOVE)
                    RegDeleteTreeW(parent_key, buf->str);
                lres = RegCreateKeyW(parent_key, buf->str, &hkey);
                if(lres != ERROR_SUCCESS) {
                    WARN("Could not create(open) key: %08x\n", lres);
                    hres = HRESULT_FROM_WIN32(lres);
                    break;
                }
            }
        }else if(key_type != IS_VAL && key_type != DO_DELETE) {
            strbuf_write(buf->str, &name, -1);
            lres = RegOpenKeyW(parent_key, buf->str, &hkey);
              if(lres != ERROR_SUCCESS)
                WARN("Could not open key %s: %08x\n", debugstr_w(name.str), lres);
        }

        if(key_type != DO_DELETE && *iter == '=') {
            iter++;
            hres = get_word(&iter, buf);
            if(FAILED(hres))
                break;
            if(buf->len != 1) {
                WARN("Wrong registry type: %s\n", debugstr_w(buf->str));
                hres = DISP_E_EXCEPTION;
                break;
            }
            if(do_register) {
                switch(buf->str[0]) {
                case 's':
                    hres = get_word(&iter, buf);
                    if(FAILED(hres))
                        break;
                    lres = RegSetValueExW(hkey, name.len ? name.str :  NULL, 0, REG_SZ, (PBYTE)buf->str,
                            (lstrlenW(buf->str)+1)*sizeof(WCHAR));
                    if(lres != ERROR_SUCCESS) {
                        WARN("Could set value of key: %08x\n", lres);
                        hres = HRESULT_FROM_WIN32(lres);
                        break;
                    }
                    break;
                case 'd': {
                    WCHAR *end;
                    DWORD dw;
                    if(*iter == '0' && iter[1] == 'x') {
                        iter += 2;
                        dw = strtolW(iter, &end, 16);
                    }else {
                        dw = strtolW(iter, &end, 10);
                    }
                    iter = end;
                    lres = RegSetValueExW(hkey, name.len ? name.str :  NULL, 0, REG_DWORD,
                            (PBYTE)&dw, sizeof(dw));
                    if(lres != ERROR_SUCCESS) {
                        WARN("Could set value of key: %08x\n", lres);
                        hres = HRESULT_FROM_WIN32(lres);
                        break;
                    }
                    break;
                }
                default:
                    WARN("Wrong resource type: %s\n", debugstr_w(buf->str));
                    hres = DISP_E_EXCEPTION;
                };
                if(FAILED(hres))
                    break;
            }else {
                if(*iter == '-')
                    iter++;
                hres = get_word(&iter, buf);
                if(FAILED(hres))
                    break;
            }
        }else if(key_type == IS_VAL) {
            WARN("value not set!\n");
            hres = DISP_E_EXCEPTION;
            break;
        }

        if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && isspaceW(iter[1])) {
            hres = get_word(&iter, buf);
            if(FAILED(hres))
                break;
            hres = do_process_key(&iter, hkey, buf, do_register);
            if(FAILED(hres))
                break;
        }

        TRACE("%x %x\n", do_register, key_type);
        if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) {
            TRACE("Deleting %s\n", debugstr_w(name.str));
            RegDeleteKeyW(parent_key, name.str);
        }

        if(hkey && key_type != IS_VAL)
            RegCloseKey(hkey);
        hkey = 0;
        name.len = 0;
        
        hres = get_word(&iter, buf);
        if(FAILED(hres))
            break;
    }

    HeapFree(GetProcessHeap(), 0, name.str);
    if(hkey && key_type != IS_VAL)
        RegCloseKey(hkey);
    *pstr = iter;
    return hres;
}
Example #26
0
File: wcs.c Project: bpowers/wine
/*********************************************************************
 * _wcstod_l - not exported in native msvcrt
 */
double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end,
        MSVCRT__locale_t locale)
{
    MSVCRT_pthreadlocinfo locinfo;
    unsigned __int64 d=0, hlp;
    unsigned fpcontrol;
    int exp=0, sign=1;
    const MSVCRT_wchar_t *p;
    double ret;
    BOOL found_digit = FALSE;

    if (!MSVCRT_CHECK_PMT(str != NULL)) return 0;

    if(!locale)
        locinfo = get_locinfo();
    else
        locinfo = locale->locinfo;

    p = str;
    while(isspaceW(*p))
        p++;

    if(*p == '-') {
        sign = -1;
        p++;
    } else  if(*p == '+')
        p++;

    while(isdigitW(*p)) {
        found_digit = TRUE;
        hlp = d*10+*(p++)-'0';
        if(d>MSVCRT_UI64_MAX/10 || hlp<d) {
            exp++;
            break;
        } else
            d = hlp;
    }
    while(isdigitW(*p)) {
        exp++;
        p++;
    }
    if(*p == *locinfo->lconv->decimal_point)
        p++;

    while(isdigitW(*p)) {
        found_digit = TRUE;
        hlp = d*10+*(p++)-'0';
        if(d>MSVCRT_UI64_MAX/10 || hlp<d)
            break;

        d = hlp;
        exp--;
    }
    while(isdigitW(*p))
        p++;

    if(!found_digit) {
        if(end)
            *end = (MSVCRT_wchar_t*)str;
        return 0.0;
    }

    if(*p=='e' || *p=='E' || *p=='d' || *p=='D') {
        int e=0, s=1;

        p++;
        if(*p == '-') {
            s = -1;
            p++;
        } else if(*p == '+')
            p++;

        if(isdigitW(*p)) {
            while(isdigitW(*p)) {
                if(e>INT_MAX/10 || (e=e*10+*p-'0')<0)
                    e = INT_MAX;
                p++;
            }
            e *= s;

            if(exp<0 && e<0 && exp+e>=0) exp = INT_MIN;
            else if(exp>0 && e>0 && exp+e<0) exp = INT_MAX;
            else exp += e;
        } else {
            if(*p=='-' || *p=='+')
                p--;
            p--;
        }
    }

    fpcontrol = _control87(0, 0);
    _control87(MSVCRT__EM_DENORMAL|MSVCRT__EM_INVALID|MSVCRT__EM_ZERODIVIDE
            |MSVCRT__EM_OVERFLOW|MSVCRT__EM_UNDERFLOW|MSVCRT__EM_INEXACT, 0xffffffff);

    if(exp>0)
        ret = (double)sign*d*pow(10, exp);
    else
        ret = (double)sign*d/pow(10, -exp);

    _control87(fpcontrol, 0xffffffff);

    if((d && ret==0.0) || isinf(ret))
        *MSVCRT__errno() = MSVCRT_ERANGE;

    if(end)
        *end = (MSVCRT_wchar_t*)p;

    return ret;
}
Example #27
0
static LPWSTR *get_extrac_args(LPWSTR cmdline, int *pargc)
{
    enum {OUTSIDE_ARG, INSIDE_ARG, INSIDE_QUOTED_ARG} state;
    LPWSTR str;
    int argc;
    LPWSTR *argv;
    int max_argc = 16;
    BOOL new_arg;

    WINE_TRACE("cmdline: %s\n", wine_dbgstr_w(cmdline));
    str = HeapAlloc(GetProcessHeap(), 0, (strlenW(cmdline) + 1) * sizeof(WCHAR));
    if(!str) return NULL;
    strcpyW(str, cmdline);
    argv = HeapAlloc(GetProcessHeap(), 0, (max_argc + 1) * sizeof(LPWSTR));
    if(!argv)
    {
        HeapFree(GetProcessHeap(), 0, str);
        return NULL;
    }

    /* Split command line to separate arg-strings and fill argv */
    state = OUTSIDE_ARG;
    argc = 0;
    while(*str)
    {
        new_arg = FALSE;
        /* Check character */
        if(isspaceW(*str))          /* white space */
        {
            if(state == INSIDE_ARG)
            {
                state = OUTSIDE_ARG;
                *str = 0;
            }
        }
        else if(*str == '"')        /* double quote */
            switch(state)
            {
                case INSIDE_QUOTED_ARG:
                    state = OUTSIDE_ARG;
                    *str = 0;
                    break;
                case INSIDE_ARG:
                    *str = 0;
                    /* Fall through */
                case OUTSIDE_ARG:
                    if(!*++str) continue;
                    state = INSIDE_QUOTED_ARG;
                    new_arg = TRUE;
                    break;
            }
        else                        /* regular character */
            if(state == OUTSIDE_ARG)
            {
                state = INSIDE_ARG;
                new_arg = TRUE;
            }

        /* Add new argv entry, if need */
        if(new_arg)
        {
            if(argc >= max_argc - 1)
            {
                /* Realloc argv here because there always should be
                   at least one reserved cell for terminating NULL */
                max_argc *= 2;
                argv = HeapReAlloc(GetProcessHeap(), 0, argv,
                        (max_argc + 1) * sizeof(LPWSTR));
                if(!argv)
                {
                    HeapFree(GetProcessHeap(), 0, str);
                    return NULL;
                }
            }
            argv[argc++] = str;
        }

        str++;
    }

    argv[argc] = NULL;
    *pargc = argc;

    if(TRACE_ON(extrac32))
    {
        int i;
        for(i = 0; i < argc; i++)
            WINE_TRACE("arg %d: %s\n", i, wine_dbgstr_w(argv[i]));
    }
    return argv;
}
Example #28
0
/*********************************************************************
 *		wcstod (MSVCRT.@)
 */
double CDECL wcstod(const wchar_t* lpszStr, wchar_t** end)
{
  const wchar_t* str = lpszStr;
  int negative = 0;
  double ret = 0, divisor = 10.0;

  TRACE("(%s,%p) semi-stub\n", debugstr_w(lpszStr), end);

  /* FIXME:
   * - Should set errno on failure
   * - Should fail on overflow
   * - Need to check which input formats are allowed
   */
  while (isspaceW(*str))
    str++;

  if (*str == '-')
  {
    negative = 1;
    str++;
  }

  while (isdigitW(*str))
  {
    ret = ret * 10.0 + (*str - '0');
    str++;
  }
  if (*str == '.')
    str++;
  while (isdigitW(*str))
  {
    ret = ret + (*str - '0') / divisor;
    divisor *= 10;
    str++;
  }

  if (*str == 'E' || *str == 'e' || *str == 'D' || *str == 'd')
  {
    int negativeExponent = 0;
    int exponent = 0;
    if (*(++str) == '-')
    {
      negativeExponent = 1;
      str++;
    }
    while (isdigitW(*str))
    {
      exponent = exponent * 10 + (*str - '0');
      str++;
    }
    if (exponent != 0)
    {
      if (negativeExponent)
        ret = ret / pow(10.0, exponent);
      else
        ret = ret * pow(10.0, exponent);
    }
  }

  if (negative)
    ret = -ret;

  if (end)
    *end = (wchar_t*)str;

  TRACE("returning %g\n", ret);
  return ret;
}
Example #29
0
static PRUnichar *handle_insert_comment(HTMLDocumentNode *doc, const PRUnichar *comment)
{
    int majorv = 0, minorv = 0;
    const PRUnichar *ptr, *end;
    PRUnichar *buf;
    DWORD len;

    enum {
        CMP_EQ,
        CMP_LT,
        CMP_LTE,
        CMP_GT,
        CMP_GTE
    } cmpt = CMP_EQ;

    static const PRUnichar endifW[] = {'<','!','[','e','n','d','i','f',']'};

    if(comment[0] != '[' || comment[1] != 'i' || comment[2] != 'f')
        return NULL;

    ptr = comment+3;
    while(isspaceW(*ptr))
        ptr++;

    if(ptr[0] == 'l' && ptr[1] == 't') {
        ptr += 2;
        if(*ptr == 'e') {
            cmpt = CMP_LTE;
            ptr++;
        } else {
            cmpt = CMP_LT;
        }
    } else if(ptr[0] == 'g' && ptr[1] == 't') {
        ptr += 2;
        if(*ptr == 'e') {
            cmpt = CMP_GTE;
            ptr++;
        } else {
            cmpt = CMP_GT;
        }
    }

    if(!isspaceW(*ptr++))
        return NULL;
    while(isspaceW(*ptr))
        ptr++;

    if(ptr[0] != 'I' || ptr[1] != 'E')
        return NULL;

    ptr +=2;
    if(!isspaceW(*ptr++))
        return NULL;
    while(isspaceW(*ptr))
        ptr++;

    if(!isdigitW(*ptr))
        return NULL;
    while(isdigitW(*ptr))
        majorv = majorv*10 + (*ptr++ - '0');

    if(*ptr == '.') {
        ptr++;
        if(!isdigitW(*ptr))
            return NULL;
        while(isdigitW(*ptr))
            minorv = minorv*10 + (*ptr++ - '0');
    }

    while(isspaceW(*ptr))
        ptr++;
    if(ptr[0] != ']' || ptr[1] != '>')
        return NULL;
    ptr += 2;

    len = strlenW(ptr);
    if(len < sizeof(endifW)/sizeof(WCHAR))
        return NULL;

    end = ptr + len-sizeof(endifW)/sizeof(WCHAR);
    if(memcmp(end, endifW, sizeof(endifW)))
        return NULL;

    switch(cmpt) {
    case CMP_EQ:
        if(majorv == IE_MAJOR_VERSION && minorv == IE_MINOR_VERSION)
            break;
        return NULL;
    case CMP_LT:
        if(majorv > IE_MAJOR_VERSION)
            break;
        if(majorv == IE_MAJOR_VERSION && minorv > IE_MINOR_VERSION)
            break;
        return NULL;
    case CMP_LTE:
        if(majorv > IE_MAJOR_VERSION)
            break;
        if(majorv == IE_MAJOR_VERSION && minorv >= IE_MINOR_VERSION)
            break;
        return NULL;
    case CMP_GT:
        if(majorv < IE_MAJOR_VERSION)
            break;
        if(majorv == IE_MAJOR_VERSION && minorv < IE_MINOR_VERSION)
            break;
        return NULL;
    case CMP_GTE:
        if(majorv < IE_MAJOR_VERSION)
            break;
        if(majorv == IE_MAJOR_VERSION && minorv <= IE_MINOR_VERSION)
            break;
        return NULL;
    }

    buf = heap_alloc((end-ptr+1)*sizeof(WCHAR));
    if(!buf)
        return NULL;

    memcpy(buf, ptr, (end-ptr)*sizeof(WCHAR));
    buf[end-ptr] = 0;

    return buf;
}
Example #30
0
static PRUnichar *handle_insert_comment(HTMLDocumentNode *doc, const PRUnichar *comment)
{
    unsigned majorv = 0, minorv = 0, compat_version;
    const PRUnichar *ptr, *end;
    PRUnichar *buf;
    DWORD len;

    enum {
        CMP_EQ,
        CMP_LT,
        CMP_LTE,
        CMP_GT,
        CMP_GTE
    } cmpt = CMP_EQ;

    static const PRUnichar endifW[] = {'<','!','[','e','n','d','i','f',']'};

    if(comment[0] != '[' || comment[1] != 'i' || comment[2] != 'f')
        return NULL;

    ptr = comment+3;
    while(isspaceW(*ptr))
        ptr++;

    if(ptr[0] == 'l' && ptr[1] == 't') {
        ptr += 2;
        if(*ptr == 'e') {
            cmpt = CMP_LTE;
            ptr++;
        }else {
            cmpt = CMP_LT;
        }
    }else if(ptr[0] == 'g' && ptr[1] == 't') {
        ptr += 2;
        if(*ptr == 'e') {
            cmpt = CMP_GTE;
            ptr++;
        }else {
            cmpt = CMP_GT;
        }
    }

    if(!isspaceW(*ptr++))
        return NULL;
    while(isspaceW(*ptr))
        ptr++;

    if(ptr[0] != 'I' || ptr[1] != 'E')
        return NULL;

    ptr +=2;
    if(!isspaceW(*ptr++))
        return NULL;
    while(isspaceW(*ptr))
        ptr++;

    if(!isdigitW(*ptr))
        return NULL;
    while(isdigitW(*ptr))
        majorv = majorv*10 + (*ptr++ - '0');

    if(*ptr == '.') {
        ptr++;
        if(!isdigitW(*ptr))
            return NULL;
        while(isdigitW(*ptr))
            minorv = minorv*10 + (*ptr++ - '0');
    }

    while(isspaceW(*ptr))
        ptr++;
    if(ptr[0] != ']' || ptr[1] != '>')
        return NULL;
    ptr += 2;

    len = strlenW(ptr);
    if(len < ARRAY_SIZE(endifW))
        return NULL;

    end = ptr + len - ARRAY_SIZE(endifW);
    if(memcmp(end, endifW, sizeof(endifW)))
        return NULL;

    compat_version = compat_mode_info[doc->document_mode].ie_version;

    switch(cmpt) {
    case CMP_EQ:
        if(compat_version == majorv && !minorv)
            break;
        return NULL;
    case CMP_LT:
        if(compat_version < majorv || (compat_version == majorv && minorv))
            break;
        return NULL;
    case CMP_LTE:
        if(compat_version <= majorv)
            break;
        return NULL;
    case CMP_GT:
        if(compat_version > majorv)
            break;
        return NULL;
    case CMP_GTE:
        if(compat_version >= majorv || (compat_version == majorv && !minorv))
            break;
        return NULL;
    }

    buf = heap_alloc((end-ptr+1)*sizeof(WCHAR));
    if(!buf)
        return NULL;

    memcpy(buf, ptr, (end-ptr)*sizeof(WCHAR));
    buf[end-ptr] = 0;

    return buf;
}