LibreOffice Module desktop (master)  1
cmdlineargs.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <config_features.h>
21 
22 #if HAVE_FEATURE_MACOSX_SANDBOX
23 #include <premac.h>
24 #include <Foundation/Foundation.h>
25 #include <postmac.h>
26 #endif
27 
28 #include "cmdlineargs.hxx"
29 #include <osl/thread.hxx>
30 #include <tools/stream.hxx>
31 #include <rtl/ustring.hxx>
32 #include <rtl/process.h>
33 #include <comphelper/lok.hxx>
35 #include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
36 #include <unotools/bootstrap.hxx>
37 
38 #include <rtl/strbuf.hxx>
39 #include <osl/file.hxx>
40 #include <sal/log.hxx>
41 
42 using namespace com::sun::star::lang;
43 using namespace com::sun::star::uri;
44 using namespace com::sun::star::uno;
45 
46 namespace desktop
47 {
48 
49 namespace {
50 
51 OUString translateExternalUris(OUString const & input) {
52  OUString t(
55  translateToInternal(input));
56  return t.isEmpty() ? input : t;
57 }
58 
59 std::vector< OUString > translateExternalUris(
60  std::vector< OUString > const & input)
61 {
62  std::vector< OUString > t;
63  t.reserve(input.size());
64  for (auto const& elem : input)
65  {
66  t.push_back(translateExternalUris(elem));
67  }
68  return t;
69 }
70 
71 class ExtCommandLineSupplier: public CommandLineArgs::Supplier {
72 public:
73  explicit ExtCommandLineSupplier():
74  m_count(
75  comphelper::LibreOfficeKit::isActive()
76  ? 0 : rtl_getAppCommandArgCount()),
77  m_index(0)
78  {
79  OUString url;
81  m_cwdUrl = url;
82  }
83  }
84 
85  virtual std::optional< OUString > getCwdUrl() override { return m_cwdUrl; }
86 
87  virtual bool next(OUString * argument) override {
88  OSL_ASSERT(argument != nullptr);
89  if (m_index < m_count) {
90  rtl_getAppCommandArg(m_index++, &argument->pData);
91  return true;
92  } else {
93  return false;
94  }
95  }
96 
97 private:
98  std::optional< OUString > m_cwdUrl;
99  sal_uInt32 m_count;
100  sal_uInt32 m_index;
101 };
102 
103 enum class CommandLineEvent {
104  Open, Print, View, Start, PrintTo,
105  ForceOpen, ForceNew, Conversion, BatchPrint
106 };
107 
108 // Office URI Schemes: see https://msdn.microsoft.com/en-us/library/dn906146
109 // This functions checks if the arg is an Office URI.
110 // If applicable, it updates arg to inner URI.
111 // If no event argument is explicitly set in command line,
112 // then it returns updated command line event,
113 // according to Office URI command.
114 CommandLineEvent CheckOfficeURI(/* in,out */ OUString& arg, CommandLineEvent curEvt)
115 {
116  // 1. Strip the scheme name
117  OUString rest1;
118  bool isOfficeURI = ( arg.startsWithIgnoreAsciiCase("vnd.libreoffice.command:", &rest1) // Proposed extended schema
119  || arg.startsWithIgnoreAsciiCase("ms-word:", &rest1)
120  || arg.startsWithIgnoreAsciiCase("ms-powerpoint:", &rest1)
121  || arg.startsWithIgnoreAsciiCase("ms-excel:", &rest1)
122  || arg.startsWithIgnoreAsciiCase("ms-visio:", &rest1)
123  || arg.startsWithIgnoreAsciiCase("ms-access:", &rest1));
124  if (!isOfficeURI)
125  return curEvt;
126 
127  OUString rest2;
128  tools::Long nURIlen = -1;
129 
130  // URL might be encoded
131  OUString decoded_rest = rest1.replaceAll("%7C", "|").replaceAll("%7c", "|");
132 
133  // 2. Discriminate by command name (incl. 1st command argument descriptor)
134  // Extract URI: everything up to possible next argument
135  if (decoded_rest.startsWith("ofv|u|", &rest2))
136  {
137  // Open for view - override only in default mode
138  if (curEvt == CommandLineEvent::Open)
139  curEvt = CommandLineEvent::View;
140  nURIlen = rest2.indexOf("|");
141  }
142  else if (decoded_rest.startsWith("ofe|u|", &rest2))
143  {
144  // Open for editing - override only in default mode
145  if (curEvt == CommandLineEvent::Open)
146  curEvt = CommandLineEvent::ForceOpen;
147  nURIlen = rest2.indexOf("|");
148  }
149  else if (decoded_rest.startsWith("nft|u|", &rest2))
150  {
151  // New from template - override only in default mode
152  if (curEvt == CommandLineEvent::Open)
153  curEvt = CommandLineEvent::ForceNew;
154  nURIlen = rest2.indexOf("|");
155  // TODO: process optional second argument (default save-to location)
156  // For now, we just ignore it
157  }
158  else
159  {
160  // Abbreviated scheme: <scheme-name>:URI
161  // "ofv|u|" implied
162  // override only in default mode
163  if (curEvt == CommandLineEvent::Open)
164  curEvt = CommandLineEvent::View;
165  rest2 = rest1;
166  }
167  if (nURIlen < 0)
168  nURIlen = rest2.getLength();
169  arg = rest2.copy(0, nURIlen);
170  return curEvt;
171 }
172 
173 // Skip single newline (be it *NIX LF, MacOS CR, of Win CRLF)
174 // Changes the offset, and returns true if moved
175 bool SkipNewline(const char* & pStr)
176 {
177  if ((*pStr != '\r') && (*pStr != '\n'))
178  return false;
179  if (*pStr == '\r')
180  ++pStr;
181  if (*pStr == '\n')
182  ++pStr;
183  return true;
184 }
185 
186 // Web query: http://support.microsoft.com/kb/157482
187 CommandLineEvent CheckWebQuery(/* in,out */ OUString& arg, CommandLineEvent curEvt)
188 {
189  // Only handle files with extension .iqy
190  if (!arg.endsWithIgnoreAsciiCase(".iqy"))
191  return curEvt;
192 
193  static osl::Mutex aMutex;
194  osl::MutexGuard aGuard(aMutex);
195 
196  try
197  {
198  OUString sFileURL;
199  // Cannot use translateExternalUris yet, because process service factory is not yet available
200  if (osl::FileBase::getFileURLFromSystemPath(arg, sFileURL) != osl::FileBase::RC::E_None)
201  return curEvt;
202  SvFileStream stream(sFileURL, StreamMode::READ);
203 
204  const sal_Int32 nBufLen = 32000;
205  char sBuffer[nBufLen];
206  size_t nRead = stream.ReadBytes(sBuffer, nBufLen);
207  if (nRead < 8) // WEB\n1\n...
208  return curEvt;
209 
210  const char* pPos = sBuffer;
211  if (strncmp(pPos, "WEB", 3) != 0)
212  return curEvt;
213  pPos += 3;
214  if (!SkipNewline(pPos))
215  return curEvt;
216  if (*pPos != '1')
217  return curEvt;
218  ++pPos;
219  if (!SkipNewline(pPos))
220  return curEvt;
221 
222  OStringBuffer aResult(nRead);
223  do
224  {
225  const char* pPos1 = pPos;
226  const char* pEnd = sBuffer + nRead;
227  while ((pPos1 < pEnd) && (*pPos1 != '\r') && (*pPos1 != '\n'))
228  ++pPos1;
229  aResult.append(pPos, pPos1 - pPos);
230  if (pPos1 < pEnd) // newline
231  break;
232  pPos = sBuffer;
233  } while ((nRead = stream.ReadBytes(sBuffer, nBufLen)) > 0);
234 
235  stream.Close();
236 
237  arg = OStringToOUString(aResult.makeStringAndClear(), osl_getThreadTextEncoding());
238  return CommandLineEvent::ForceNew;
239  }
240  catch (...)
241  {
242  SAL_WARN("desktop.app", "An error processing Web Query file: " << arg);
243  }
244 
245  return curEvt;
246 }
247 
248 } // namespace
249 
250 CommandLineArgs::Supplier::Exception::Exception() {}
251 
252 CommandLineArgs::Supplier::Exception::Exception(Exception const &) {}
253 
255 CommandLineArgs::Supplier::Exception::operator =(Exception const &)
256 { return *this; }
257 
258 CommandLineArgs::Supplier::~Supplier() {}
259 
260 // initialize class with command line parameters from process environment
261 CommandLineArgs::CommandLineArgs()
262 {
263  InitParamValues();
264  ExtCommandLineSupplier s;
265  ParseCommandLine_Impl( s );
266 }
267 
268 CommandLineArgs::CommandLineArgs( Supplier& supplier )
269 {
270  InitParamValues();
271  ParseCommandLine_Impl( supplier );
272 }
273 
274 void CommandLineArgs::ParseCommandLine_Impl( Supplier& supplier )
275 {
276  m_cwdUrl = supplier.getCwdUrl();
277  CommandLineEvent eCurrentEvent = CommandLineEvent::Open;
278 
279  for (;;)
280  {
281  OUString aArg;
282  if ( !supplier.next( &aArg ) )
283  {
284  break;
285  }
286 
287  if ( !aArg.isEmpty() )
288  {
289  m_bEmpty = false;
290  OUString oArg;
291  OUString oDeprecatedArg;
292  if (!aArg.startsWith("--", &oArg) && aArg.startsWith("-", &oArg)
293  && aArg.getLength() > 2) // -h, -?, -n, -o, -p are still valid
294  {
295  oDeprecatedArg = aArg; // save here, since aArg can change later
296  }
297 
298  OUString rest;
299  if ( oArg == "minimized" )
300  {
301  m_minimized = true;
302  }
303  else if ( oArg == "invisible" )
304  {
305  m_invisible = true;
306  }
307  else if ( oArg == "norestore" )
308  {
309  m_norestore = true;
310  }
311  else if ( oArg == "nodefault" )
312  {
313  m_nodefault = true;
314  }
315  else if ( oArg == "headless" )
316  {
317  setHeadless();
318  }
319  else if ( oArg == "eventtesting" )
320  {
321  m_eventtesting = true;
322  }
323  else if ( oArg == "safe-mode" )
324  {
325  m_safemode = true;
326  }
327  else if ( oArg == "cat" )
328  {
329  m_textcat = true;
330  m_conversionparams = "txt:Text";
331  eCurrentEvent = CommandLineEvent::Conversion;
332  setHeadless();
333  }
334  else if ( oArg == "script-cat" )
335  {
336  m_scriptcat = true;
337  eCurrentEvent = CommandLineEvent::Conversion;
338  setHeadless();
339  }
340  else if ( oArg == "quickstart" )
341  {
342 #if defined(ENABLE_QUICKSTART_APPLET)
343  m_quickstart = true;
344 #endif
345  m_noquickstart = false;
346  }
347  else if ( oArg == "quickstart=no" )
348  {
349  m_noquickstart = true;
350  m_quickstart = false;
351  }
352  else if ( oArg == "terminate_after_init" )
353  {
354  m_terminateafterinit = true;
355  }
356  else if ( oArg == "nofirststartwizard" )
357  {
358  // Do nothing, accept only for backward compatibility
359  }
360  else if ( oArg == "nologo" )
361  {
362  m_nologo = true;
363  }
364 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
365  else if ( oArg == "nolockcheck" )
366  {
367  m_nolockcheck = true;
368  }
369 #endif
370  else if ( oArg == "help" || aArg == "-h" || aArg == "-?" )
371  {
372  m_help = true;
373  }
374  else if ( oArg == "helpwriter" )
375  {
376  m_helpwriter = true;
377  }
378  else if ( oArg == "helpcalc" )
379  {
380  m_helpcalc = true;
381  }
382  else if ( oArg == "helpdraw" )
383  {
384  m_helpdraw = true;
385  }
386  else if ( oArg == "helpimpress" )
387  {
388  m_helpimpress = true;
389  }
390  else if ( oArg == "helpbase" )
391  {
392  m_helpbase = true;
393  }
394  else if ( oArg == "helpbasic" )
395  {
396  m_helpbasic = true;
397  }
398  else if ( oArg == "helpmath" )
399  {
400  m_helpmath = true;
401  }
402  else if ( oArg == "protector" )
403  {
404  // Not relevant for us here, but can be used in unit tests.
405  // Usually unit tests would not end up here, but e.g. the
406  // LOK Tiled Rendering tests end up running a full soffice
407  // process, and we can't bail on the use of --protector.
408 
409  // We specifically need to consume the following 2 arguments
410  // for --protector
411  if ((!supplier.next(&aArg) || !supplier.next(&aArg)) && m_unknown.isEmpty())
412  m_unknown = "--protector must be followed by two arguments";
413  }
414  else if ( oArg == "version" )
415  {
416  m_version = true;
417  }
418  else if ( oArg.startsWith("splash-pipe=") )
419  {
420  m_splashpipe = true;
421  }
422 #ifdef MACOSX
423  /* #i84053# ignore -psn on Mac
424  Platform dependent #ifdef here is ugly, however this is currently
425  the only platform dependent parameter. Should more appear
426  we should find a better solution
427  */
428  else if ( aArg.startsWith("-psn") )
429  {
430  oDeprecatedArg.clear();
431  }
432 #endif
433 #if HAVE_FEATURE_MACOSX_SANDBOX
434  else if ( oArg == "nstemporarydirectory" )
435  {
436  printf("%s\n", [NSTemporaryDirectory() UTF8String]);
437  exit(0);
438  }
439 #endif
440 #ifdef _WIN32
441  /* fdo#57203 ignore -Embedding on Windows
442  when LibreOffice is launched by COM+
443  */
444  else if ( oArg == "Embedding" )
445  {
446  oDeprecatedArg.clear();
447  }
448 #endif
449  else if ( oArg.startsWith("infilter=", &rest))
450  {
451  m_infilter.push_back(rest);
452  }
453  else if ( oArg.startsWith("accept=", &rest))
454  {
455  m_accept.push_back(rest);
456  }
457  else if ( oArg.startsWith("unaccept=", &rest))
458  {
459  m_unaccept.push_back(rest);
460  }
461  else if ( oArg.startsWith("language=", &rest))
462  {
463  m_language = rest;
464  }
465  else if ( oArg.startsWith("pidfile=", &rest))
466  {
467  m_pidfile = rest;
468  }
469  else if ( oArg == "writer" )
470  {
471  m_writer = true;
472  m_bDocumentArgs = true;
473  }
474  else if ( oArg == "calc" )
475  {
476  m_calc = true;
477  m_bDocumentArgs = true;
478  }
479  else if ( oArg == "draw" )
480  {
481  m_draw = true;
482  m_bDocumentArgs = true;
483  }
484  else if ( oArg == "impress" )
485  {
486  m_impress = true;
487  m_bDocumentArgs = true;
488  }
489  else if ( oArg == "base" )
490  {
491  m_base = true;
492  m_bDocumentArgs = true;
493  }
494  else if ( oArg == "global" )
495  {
496  m_global = true;
497  m_bDocumentArgs = true;
498  }
499  else if ( oArg == "math" )
500  {
501  m_math = true;
502  m_bDocumentArgs = true;
503  }
504  else if ( oArg == "web" )
505  {
506  m_web = true;
507  m_bDocumentArgs = true;
508  }
509  else if ( aArg == "-n" )
510  {
511  // force new documents based on the following documents
512  eCurrentEvent = CommandLineEvent::ForceNew;
513  }
514  else if ( aArg == "-o" )
515  {
516  // force open documents regardless if they are templates or not
517  eCurrentEvent = CommandLineEvent::ForceOpen;
518  }
519  else if ( oArg == "pt" )
520  {
521  // Print to special printer
522  eCurrentEvent = CommandLineEvent::PrintTo;
523  // first argument after "-pt" must be the printer name
524  if (supplier.next(&aArg))
525  m_printername = aArg;
526  else if (m_unknown.isEmpty())
527  m_unknown = "--pt must be followed by printername";
528  }
529  else if ( aArg == "-p" )
530  {
531  // Print to default printer
532  eCurrentEvent = CommandLineEvent::Print;
533  }
534  else if ( oArg == "view")
535  {
536  // open in viewmode
537  eCurrentEvent = CommandLineEvent::View;
538  }
539  else if ( oArg == "show" )
540  {
541  // open in viewmode
542  eCurrentEvent = CommandLineEvent::Start;
543  }
544  else if ( oArg == "display" )
545  {
546  // The command line argument following --display should
547  // always be treated as the argument of --display.
548  // --display and its argument are handled "out of line"
549  // in Unix-only desktop/unx/source/splashx.c and vcl/unx/*,
550  // and just ignored here
551  (void)supplier.next(&aArg);
552  }
553  else if ( oArg == "convert-to" )
554  {
555  eCurrentEvent = CommandLineEvent::Conversion;
556  // first argument must be the params
557  if (supplier.next(&aArg))
558  {
559  m_conversionparams = aArg;
560  // It doesn't make sense to use convert-to without headless.
561  setHeadless();
562  }
563  else if (m_unknown.isEmpty())
564  m_unknown = "--convert-to must be followed by output_file_extension[:output_filter_name]";
565  }
566  else if ( oArg == "print-to-file" )
567  {
568  eCurrentEvent = CommandLineEvent::BatchPrint;
569  }
570  else if ( oArg == "printer-name" )
571  {
572  if (eCurrentEvent == CommandLineEvent::BatchPrint)
573  {
574  // first argument is the printer name
575  if (supplier.next(&aArg))
576  m_printername = aArg;
577  else if (m_unknown.isEmpty())
578  m_unknown = "--printer-name must be followed by printername";
579  }
580  else if (m_unknown.isEmpty())
581  {
582  m_unknown = "--printer-name must directly follow --print-to-file";
583  }
584  }
585  else if ( oArg == "outdir" )
586  {
587  if (eCurrentEvent == CommandLineEvent::Conversion ||
588  eCurrentEvent == CommandLineEvent::BatchPrint)
589  {
590  if (supplier.next(&aArg))
591  m_conversionout = aArg;
592  else if (m_unknown.isEmpty())
593  m_unknown = "--outdir must be followed by output directory path";
594  }
595  else if (m_unknown.isEmpty())
596  {
597  m_unknown = "--outdir must directly follow either output filter specification of --convert-to, or --print-to-file or its printer specification";
598  }
599  }
600  else if ( eCurrentEvent == CommandLineEvent::Conversion
601  && oArg == "convert-images-to" )
602  {
603  if (supplier.next(&aArg))
604  m_convertimages = aArg;
605  else if (m_unknown.isEmpty())
606  m_unknown = "--convert-images-to must be followed by an image type";
607  }
608  else if ( aArg.startsWith("-") )
609  {
610  // because it's impossible to filter these options that
611  // are handled in the soffice shell script with the
612  // primitive tools that /bin/sh offers, ignore them here
613  if (
614 #if defined UNX
615  oArg != "record" &&
616  oArg != "backtrace" &&
617  oArg != "strace" &&
618  oArg != "valgrind" &&
619  // for X Session Management, handled in
620  // vcl/unx/generic/app/sm.cxx:
621  oArg != "session=" &&
622 #endif
623  //ignore additional legacy options that don't do anything anymore
624  oArg != "nocrashreport" &&
625  m_unknown.isEmpty())
626  {
627  m_unknown = aArg;
628  }
629  oDeprecatedArg.clear();
630  }
631  else
632  {
633  // handle this argument as a filename
634 
635  // First check if this is an Office URI
636  // This will possibly adjust event for this argument
637  // and put real URI to aArg
638  CommandLineEvent eThisEvent = CheckOfficeURI(aArg, eCurrentEvent);
639 
640  // Now check if this is a Web Query file
641  eThisEvent = CheckWebQuery(aArg, eThisEvent);
642 
643  switch (eThisEvent)
644  {
645  case CommandLineEvent::Open:
646  m_openlist.push_back(aArg);
647  m_bDocumentArgs = true;
648  break;
649  case CommandLineEvent::View:
650  m_viewlist.push_back(aArg);
651  m_bDocumentArgs = true;
652  break;
653  case CommandLineEvent::Start:
654  m_startlist.push_back(aArg);
655  m_bDocumentArgs = true;
656  break;
657  case CommandLineEvent::Print:
658  m_printlist.push_back(aArg);
659  m_bDocumentArgs = true;
660  break;
661  case CommandLineEvent::PrintTo:
662  m_printtolist.push_back(aArg);
663  m_bDocumentArgs = true;
664  break;
665  case CommandLineEvent::ForceNew:
666  m_forcenewlist.push_back(aArg);
667  m_bDocumentArgs = true;
668  break;
669  case CommandLineEvent::ForceOpen:
670  m_forceopenlist.push_back(aArg);
671  m_bDocumentArgs = true;
672  break;
673  case CommandLineEvent::Conversion:
674  case CommandLineEvent::BatchPrint:
675  m_conversionlist.push_back(aArg);
676  break;
677  }
678  }
679 
680  if (!oDeprecatedArg.isEmpty())
681  {
682  OString sArg(OUStringToOString(oDeprecatedArg, osl_getThreadTextEncoding()));
683  fprintf(stderr, "Warning: %s is deprecated. Use -%s instead.\n", sArg.getStr(), sArg.getStr());
684  }
685  }
686  }
687 }
688 
689 void CommandLineArgs::InitParamValues()
690 {
691  m_minimized = false;
692  m_norestore = false;
693 #if HAVE_FEATURE_UI
694  m_invisible = false;
695  m_headless = false;
696 #else
697  m_invisible = true;
698  m_headless = true;
699 #endif
700  m_eventtesting = false;
701  m_quickstart = false;
702  m_noquickstart = false;
703  m_terminateafterinit = false;
704  m_nologo = false;
705  m_nolockcheck = false;
706  m_nodefault = false;
707  m_help = false;
708  m_writer = false;
709  m_calc = false;
710  m_draw = false;
711  m_impress = false;
712  m_global = false;
713  m_math = false;
714  m_web = false;
715  m_base = false;
716  m_helpwriter = false;
717  m_helpcalc = false;
718  m_helpdraw = false;
719  m_helpbasic = false;
720  m_helpmath = false;
721  m_helpimpress = false;
722  m_helpbase = false;
723  m_version = false;
724  m_splashpipe = false;
725  m_bEmpty = true;
726  m_bDocumentArgs = false;
727  m_textcat = false;
728  m_scriptcat = false;
729  m_safemode = false;
730 }
731 
732 bool CommandLineArgs::HasModuleParam() const
733 {
734  return m_writer || m_calc || m_draw || m_impress || m_global || m_math
735  || m_web || m_base;
736 }
737 
738 std::vector< OUString > CommandLineArgs::GetOpenList() const
739 {
740  return translateExternalUris(m_openlist);
741 }
742 
743 std::vector< OUString > CommandLineArgs::GetViewList() const
744 {
745  return translateExternalUris(m_viewlist);
746 }
747 
748 std::vector< OUString > CommandLineArgs::GetStartList() const
749 {
750  return translateExternalUris(m_startlist);
751 }
752 
753 std::vector< OUString > CommandLineArgs::GetForceOpenList() const
754 {
755  return translateExternalUris(m_forceopenlist);
756 }
757 
758 std::vector< OUString > CommandLineArgs::GetForceNewList() const
759 {
760  return translateExternalUris(m_forcenewlist);
761 }
762 
763 std::vector< OUString > CommandLineArgs::GetPrintList() const
764 {
765  return translateExternalUris(m_printlist);
766 }
767 
768 std::vector< OUString > CommandLineArgs::GetPrintToList() const
769 {
770  return translateExternalUris(m_printtolist);
771 }
772 
773 std::vector< OUString > CommandLineArgs::GetConversionList() const
774 {
775  return translateExternalUris(m_conversionlist);
776 }
777 
778 OUString CommandLineArgs::GetConversionOut() const
779 {
780  return translateExternalUris(m_conversionout);
781 }
782 
783 } // namespace desktop
784 
785 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
def Print(s)
std::optional< OUString > m_cwdUrl
Definition: cmdlineargs.cxx:98
long Long
static bool getProcessWorkingDir(OUString &rUrl)
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
Definition: app.cxx:164
sal_uInt32 m_index
virtual std::optional< OUString > getCwdUrl()=0
Mutex aMutex
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
XPropertyListType t
Reference< XOutputStream > stream
bool isActive()
Reference< XComponentContext > getProcessComponentContext()
#define SAL_WARN(area, stream)
sal_uInt32 m_count
Definition: cmdlineargs.cxx:99
virtual bool next(OUString *argument)=0
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo