SquareTree::SquareTree(const char* data) : root(nullptr) {
    // convert the file content to UTF-8
    if (str::StartsWith(data, UTF8_BOM)) {
        dataUtf8.SetCopy(data + 3);
    } else if (str::StartsWith(data, UTF16_BOM)) {
        auto tmp = str::conv::ToUtf8((const WCHAR*)(data + 2));
        dataUtf8.Set(tmp.StealData());
    } else if (data) {
        AutoFreeW tmp(str::conv::FromAnsi(data));
        auto tmp2 = str::conv::ToUtf8(tmp.Get());
        dataUtf8.Set(tmp2.StealData());
    }
    if (!dataUtf8) {
        return;
    }

    char* start = dataUtf8.Get();
    root = ParseSquareTreeRec(start, true);
    CrashIf(*start || !root);
}
Example #2
0
 /// Changes the ownership of the data; after the call the Vector is empty
 inline double *StealData() { double *p; StealData(&p); return p; }
/* parse argument list. we assume that all unrecognized arguments are file names. */
void CommandLineInfo::ParseCommandLine(const WCHAR* cmdLine) {
    WStrVec argList;
    ParseCmdLine(cmdLine, argList);
    size_t argCount = argList.size();

#define is_arg_with_param(_argNo) (param && _argNo == arg)
#define additional_param() argList.at(n + 1)
#define has_additional_param() ((argCount > n + 1) && ('-' != additional_param()[0]))
#define handle_string_param(name) name.SetCopy(argList.at(++n))
#define handle_int_param(name) name = _wtoi(argList.at(++n))

    for (size_t n = 1; n < argCount; n++) {
        WCHAR* argName = argList.at(n);
        int arg = GetArgNo(argName);
        WCHAR* param = nullptr;
        if (argCount > n + 1) {
            param = argList.at(n + 1);
        }
        if (RegisterForPdf == arg) {
            makeDefault = true;
            exitImmediately = true;
            return;
        } else if (Silent == arg) {
            // silences errors happening during -print-to and -print-to-default
            silent = true;
        } else if (PrintToDefault == arg) {
            printerName.Set(GetDefaultPrinterName());
            if (!printerName)
                printDialog = true;
            exitWhenDone = true;
        } else if (is_arg_with_param(PrintTo)) {
            handle_string_param(printerName);
            exitWhenDone = true;
        } else if (PrintDialog == arg) {
            printDialog = true;
        } else if (is_arg_with_param(PrintSettings)) {
            // argument is a comma separated list of page ranges and
            // advanced options [even|odd], [noscale|shrink|fit] and [autorotation|portrait|landscape]
            // e.g. -print-settings "1-3,5,10-8,odd,fit"
            handle_string_param(printSettings);
            str::RemoveChars(printSettings, L" ");
            str::TransChars(printSettings, L";", L",");
        } else if (ExitWhenDone == arg || ExitOnPrint == arg) {
            // only affects -print-dialog (-print-to and -print-to-default
            // always exit on print) and -stress-test (useful for profiling)
            exitWhenDone = true;
        } else if (is_arg_with_param(InverseSearch)) {
            inverseSearchCmdLine.SetCopy(argList.at(++n));
        } else if ((is_arg_with_param(ForwardSearch) || is_arg_with_param(FwdSearch)) && argCount > n + 2) {
            // -forward-search is for consistency with -inverse-search
            // -fwdsearch is for consistency with -fwdsearch-*
            handle_string_param(forwardSearchOrigin);
            handle_int_param(forwardSearchLine);
        } else if (is_arg_with_param(NamedDest) || is_arg_with_param(NamedDest2)) {
            // -nameddest is for backwards compat (was used pre-1.3)
            // -named-dest is for consistency
            handle_string_param(destName);
        } else if (is_arg_with_param(Page)) {
            handle_int_param(pageNumber);
        } else if (Restrict == arg) {
            restrictedUse = true;
        } else if (InvertColors1 == arg || InvertColors2 == arg) {
            // -invertcolors is for backwards compat (was used pre-1.3)
            // -invert-colors is for consistency
            // -invert-colors used to be a shortcut for -set-color-range 0xFFFFFF 0x000000
            // now it non-permanently swaps textColor and backgroundColor
            invertColors = true;
        } else if (Presentation == arg) {
            enterPresentation = true;
        } else if (Fullscreen == arg) {
            enterFullScreen = true;
        } else if (is_arg_with_param(View)) {
            ParseViewMode(&startView, param);
            ++n;
        } else if (is_arg_with_param(Zoom)) {
            ParseZoomValue(&startZoom, param);
            ++n;
        } else if (is_arg_with_param(Scroll)) {
            ParseScrollValue(&startScroll, param);
            ++n;
        } else if (Console == arg) {
            showConsole = true;
        } else if (is_arg_with_param(AppData)) {
            appdataDir.SetCopy(param);
            ++n;
        } else if (is_arg_with_param(Plugin)) {
            // -plugin [<URL>] <parent HWND>
            if (argCount > n + 2 && !str::IsDigit(*argList.at(n + 1)) && *argList.at(n + 2) != '-')
                handle_string_param(pluginURL);
            // the argument is a (numeric) window handle to
            // become the parent of a frameless SumatraPDF
            // (used e.g. for embedding it into a browser plugin)
            hwndPluginParent = (HWND)(INT_PTR)_wtol(argList.at(++n));
        } else if (is_arg_with_param(StressTest)) {
            // -stress-test <file or dir path> [<file filter>] [<page/file range(s)>] [<cycle
            // count>x]
            // e.g. -stress-test file.pdf 25x  for rendering file.pdf 25 times
            //      -stress-test file.pdf 1-3  render only pages 1, 2 and 3 of file.pdf
            //      -stress-test dir 301- 2x   render all files in dir twice, skipping first 300
            //      -stress-test dir *.pdf;*.xps  render all files in dir that are either PDF or XPS
            handle_string_param(stressTestPath);
            int num;
            if (has_additional_param() && str::FindChar(additional_param(), '*'))
                handle_string_param(stressTestFilter);
            if (has_additional_param() && IsValidPageRange(additional_param()))
                handle_string_param(stressTestRanges);
            if (has_additional_param() && str::Parse(additional_param(), L"%dx%$", &num) && num > 0) {
                stressTestCycles = num;
                n++;
            }
        } else if (is_arg_with_param(ArgN)) {
            handle_int_param(stressParallelCount);
        } else if (is_arg_with_param(Render)) {
            handle_int_param(pageNumber);
            testRenderPage = true;
        } else if (is_arg_with_param(ExtractText)) {
            handle_int_param(pageNumber);
            testExtractPage = true;
        } else if (Rand == arg) {
            stressRandomizeFiles = true;
        } else if (is_arg_with_param(Bench)) {
            WCHAR* s = str::Dup(param);
            ++n;
            pathsToBenchmark.Push(s);
            s = nullptr;
            if (has_additional_param() && IsBenchPagesInfo(additional_param())) {
                s = str::Dup(argList.at(++n));
            }
            pathsToBenchmark.Push(s);
            exitImmediately = true;
        } else if (CrashOnOpen == arg) {
            // to make testing of crash reporting system in pre-release/release
            // builds possible
            crashOnOpen = true;
        } else if (ReuseInstance == arg) {
            // for backwards compatibility, -reuse-instance reuses whatever
            // instance has registered as DDE server
            reuseDdeInstance = true;
        }
        // TODO: remove the following deprecated options within a release or two
        else if (is_arg_with_param(Lang)) {
            auto tmp = str::conv::ToAnsi(param);
            lang.Set(tmp.StealData());
            ++n;
        } else if (EscToExit == arg) {
            globalPrefArgs.Append(str::Dup(argList.at(n)));
        } else if (is_arg_with_param(BgColor) || is_arg_with_param(BgColor2) || is_arg_with_param(FwdSearchOffset) ||
                   is_arg_with_param(FwdSearchWidth) || is_arg_with_param(FwdSearchColor) ||
                   is_arg_with_param(FwdSearchPermanent) || is_arg_with_param(MangaMode)) {
            globalPrefArgs.Append(str::Dup(argList.at(n)));
            globalPrefArgs.Append(str::Dup(argList.at(++n)));
        } else if (SetColorRange == arg && argCount > n + 2) {
            globalPrefArgs.Append(str::Dup(argList.at(n)));
            globalPrefArgs.Append(str::Dup(argList.at(++n)));
            globalPrefArgs.Append(str::Dup(argList.at(++n)));
        }
#ifdef DEBUG
        else if (ArgEnumPrinters == arg) {
            EnumeratePrinters();
            /* this is for testing only, exit immediately */
            exitImmediately = true;
            return;
        }
#endif
        // this should have been handled already by AutoUpdateMain
        else if (is_arg_with_param(AutoUpdate)) {
            n++;
        } else {
            // Remember this argument as a filename to open
            WCHAR* filePath = nullptr;
            if (str::EndsWithI(argName, L".lnk"))
                filePath = ResolveLnk(argName);
            if (!filePath)
                filePath = str::Dup(argName);
            fileNames.Push(filePath);
        }
    }
#undef is_arg_with_param
#undef additional_param
#undef has_additional_param
#undef handle_string_param
#undef handle_int_param
}