comparison liboctave/system/oct-env.cc @ 31607:aac27ad79be6 stable

maint: Re-indent code after switch to using namespace macros. * build-env.h, build-env.in.cc, Cell.h, __betainc__.cc, __eigs__.cc, __ftp__.cc, __ichol__.cc, __ilu__.cc, __isprimelarge__.cc, __magick_read__.cc, __pchip_deriv__.cc, amd.cc, base-text-renderer.cc, base-text-renderer.h, besselj.cc, bitfcns.cc, bsxfun.cc, c-file-ptr-stream.h, call-stack.cc, call-stack.h, ccolamd.cc, cellfun.cc, chol.cc, colamd.cc, dasrt.cc, data.cc, debug.cc, defaults.cc, defaults.h, det.cc, display.cc, display.h, dlmread.cc, dynamic-ld.cc, dynamic-ld.h, ellipj.cc, environment.cc, environment.h, error.cc, error.h, errwarn.h, event-manager.cc, event-manager.h, event-queue.cc, event-queue.h, fcn-info.cc, fcn-info.h, fft.cc, fft2.cc, file-io.cc, filter.cc, find.cc, ft-text-renderer.cc, ft-text-renderer.h, gcd.cc, gl-render.cc, gl-render.h, gl2ps-print.cc, gl2ps-print.h, graphics-toolkit.cc, graphics-toolkit.h, graphics.cc, gsvd.cc, gtk-manager.cc, gtk-manager.h, help.cc, help.h, hook-fcn.cc, hook-fcn.h, input.cc, input.h, interpreter-private.cc, interpreter-private.h, interpreter.cc, interpreter.h, inv.cc, jsondecode.cc, jsonencode.cc, latex-text-renderer.cc, latex-text-renderer.h, load-path.cc, load-path.h, load-save.cc, load-save.h, lookup.cc, ls-hdf5.cc, ls-mat4.cc, ls-mat5.cc, lsode.cc, lu.cc, mappers.cc, matrix_type.cc, max.cc, mex.cc, mexproto.h, mxarray.h, mxtypes.in.h, oct-errno.in.cc, oct-hdf5-types.cc, oct-hist.cc, oct-hist.h, oct-map.cc, oct-map.h, oct-opengl.h, oct-prcstrm.h, oct-process.cc, oct-process.h, oct-stdstrm.h, oct-stream.cc, oct-stream.h, oct-strstrm.h, octave-default-image.h, ordqz.cc, ordschur.cc, pager.cc, pager.h, pinv.cc, pow2.cc, pr-output.cc, psi.cc, qr.cc, quadcc.cc, rand.cc, regexp.cc, settings.cc, settings.h, sighandlers.cc, sighandlers.h, sparse-xpow.cc, sqrtm.cc, stack-frame.cc, stack-frame.h, stream-euler.cc, strfns.cc, svd.cc, syminfo.cc, syminfo.h, symrcm.cc, symrec.cc, symrec.h, symscope.cc, symscope.h, symtab.cc, symtab.h, sysdep.cc, sysdep.h, text-engine.cc, text-engine.h, text-renderer.cc, text-renderer.h, time.cc, toplev.cc, typecast.cc, url-handle-manager.cc, url-handle-manager.h, urlwrite.cc, utils.cc, utils.h, variables.cc, variables.h, xdiv.cc, __delaunayn__.cc, __init_fltk__.cc, __init_gnuplot__.cc, __ode15__.cc, __voronoi__.cc, audioread.cc, convhulln.cc, gzip.cc, cdef-class.cc, cdef-class.h, cdef-fwd.h, cdef-manager.cc, cdef-manager.h, cdef-method.cc, cdef-method.h, cdef-object.cc, cdef-object.h, cdef-package.cc, cdef-package.h, cdef-property.cc, cdef-property.h, cdef-utils.cc, cdef-utils.h, ov-base-diag.cc, ov-base-int.cc, ov-base-mat.cc, ov-base-mat.h, ov-base-scalar.cc, ov-base.cc, ov-base.h, ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc, ov-bool.cc, ov-builtin.h, ov-cell.cc, ov-ch-mat.cc, ov-class.cc, ov-class.h, ov-classdef.cc, ov-classdef.h, ov-complex.cc, ov-cx-diag.cc, ov-cx-mat.cc, ov-cx-sparse.cc, ov-dld-fcn.cc, ov-dld-fcn.h, ov-fcn-handle.cc, ov-fcn-handle.h, ov-fcn.h, ov-float.cc, ov-flt-complex.cc, ov-flt-cx-diag.cc, ov-flt-cx-mat.cc, ov-flt-re-diag.cc, ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-intx.h, ov-java.cc, ov-lazy-idx.cc, ov-legacy-range.cc, ov-magic-int.cc, ov-mex-fcn.cc, ov-mex-fcn.h, ov-null-mat.cc, ov-perm.cc, ov-range.cc, ov-re-diag.cc, ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc, ov-scalar.cc, ov-str-mat.cc, ov-struct.cc, ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc, ov-usr-fcn.h, ov.cc, ov.h, ovl.h, octave.cc, octave.h, op-b-sbm.cc, op-bm-sbm.cc, op-cs-scm.cc, op-fm-fcm.cc, op-fs-fcm.cc, op-s-scm.cc, op-scm-cs.cc, op-scm-s.cc, op-sm-cs.cc, ops.h, anon-fcn-validator.cc, anon-fcn-validator.h, bp-table.cc, bp-table.h, comment-list.cc, comment-list.h, filepos.h, lex.h, oct-lvalue.cc, oct-lvalue.h, parse.h, profiler.cc, profiler.h, pt-anon-scopes.cc, pt-anon-scopes.h, pt-arg-list.cc, pt-arg-list.h, pt-args-block.cc, pt-args-block.h, pt-array-list.cc, pt-array-list.h, pt-assign.cc, pt-assign.h, pt-binop.cc, pt-binop.h, pt-bp.cc, pt-bp.h, pt-cbinop.cc, pt-cbinop.h, pt-cell.cc, pt-cell.h, pt-check.cc, pt-check.h, pt-classdef.cc, pt-classdef.h, pt-cmd.h, pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h, pt-eval.cc, pt-eval.h, pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h, pt-fcn-handle.cc, pt-fcn-handle.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h, pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h, pt-pr-code.cc, pt-pr-code.h, pt-select.cc, pt-select.h, pt-spmd.cc, pt-spmd.h, pt-stmt.cc, pt-stmt.h, pt-tm-const.cc, pt-tm-const.h, pt-unop.cc, pt-unop.h, pt-walk.cc, pt-walk.h, pt.cc, pt.h, token.cc, token.h, Range.cc, Range.h, idx-vector.cc, idx-vector.h, range-fwd.h, CollocWt.cc, CollocWt.h, aepbalance.cc, aepbalance.h, chol.cc, chol.h, gepbalance.cc, gepbalance.h, gsvd.cc, gsvd.h, hess.cc, hess.h, lo-mappers.cc, lo-mappers.h, lo-specfun.cc, lo-specfun.h, lu.cc, lu.h, oct-convn.cc, oct-convn.h, oct-fftw.cc, oct-fftw.h, oct-norm.cc, oct-norm.h, oct-rand.cc, oct-rand.h, oct-spparms.cc, oct-spparms.h, qr.cc, qr.h, qrp.cc, qrp.h, randgamma.cc, randgamma.h, randmtzig.cc, randmtzig.h, randpoisson.cc, randpoisson.h, schur.cc, schur.h, sparse-chol.cc, sparse-chol.h, sparse-lu.cc, sparse-lu.h, sparse-qr.cc, sparse-qr.h, svd.cc, svd.h, child-list.cc, child-list.h, dir-ops.cc, dir-ops.h, file-ops.cc, file-ops.h, file-stat.cc, file-stat.h, lo-sysdep.cc, lo-sysdep.h, lo-sysinfo.cc, lo-sysinfo.h, mach-info.cc, mach-info.h, oct-env.cc, oct-env.h, oct-group.cc, oct-group.h, oct-password.cc, oct-password.h, oct-syscalls.cc, oct-syscalls.h, oct-time.cc, oct-time.h, oct-uname.cc, oct-uname.h, action-container.cc, action-container.h, base-list.h, cmd-edit.cc, cmd-edit.h, cmd-hist.cc, cmd-hist.h, f77-fcn.h, file-info.cc, file-info.h, lo-array-errwarn.cc, lo-array-errwarn.h, lo-hash.cc, lo-hash.h, lo-ieee.h, lo-regexp.cc, lo-regexp.h, lo-utils.cc, lo-utils.h, oct-base64.cc, oct-base64.h, oct-glob.cc, oct-glob.h, oct-inttypes.h, oct-mutex.cc, oct-mutex.h, oct-refcount.h, oct-shlib.cc, oct-shlib.h, oct-sparse.cc, oct-sparse.h, oct-string.h, octave-preserve-stream-state.h, pathsearch.cc, pathsearch.h, quit.cc, quit.h, unwind-prot.cc, unwind-prot.h, url-transfer.cc, url-transfer.h: Re-indent code after switch to using namespace macros.
author Rik <rik@octave.org>
date Thu, 01 Dec 2022 18:02:15 -0800
parents e88a07dec498
children 597f3ee61a48
comparison
equal deleted inserted replaced
31605:e88a07dec498 31607:aac27ad79be6
67 67
68 OCTAVE_BEGIN_NAMESPACE(octave) 68 OCTAVE_BEGIN_NAMESPACE(octave)
69 69
70 OCTAVE_BEGIN_NAMESPACE(sys) 70 OCTAVE_BEGIN_NAMESPACE(sys)
71 71
72 env::env (void) 72 env::env (void)
73 : m_follow_symbolic_links (true), m_verbatim_pwd (true), 73 : m_follow_symbolic_links (true), m_verbatim_pwd (true),
74 m_current_directory (), m_prog_name (), m_prog_invocation_name (), 74 m_current_directory (), m_prog_name (), m_prog_invocation_name (),
75 m_user_name (), m_host_name () 75 m_user_name (), m_host_name ()
76 { 76 {
77 // Get a real value for the current directory. 77 // Get a real value for the current directory.
78 do_getcwd (); 78 do_getcwd ();
79 79
80 // Etc. 80 // Etc.
81 do_get_user_name (); 81 do_get_user_name ();
82 82
83 do_get_host_name (); 83 do_get_host_name ();
84 } 84 }
85 85
86 env *env::m_instance = nullptr; 86 env *env::m_instance = nullptr;
87 87
88 bool 88 bool
89 env::instance_ok (void) 89 env::instance_ok (void)
90 { 90 {
91 bool retval = true; 91 bool retval = true;
92 92
93 if (! m_instance) 93 if (! m_instance)
94 {
95 m_instance = new env ();
96 singleton_cleanup_list::add (cleanup_instance);
97 }
98
99 return retval;
100 }
101
102 std::string
103 env::polite_directory_format (const std::string& name)
104 {
105 return (instance_ok ())
106 ? m_instance->do_polite_directory_format (name) : "";
107 }
108
109 bool
110 env::absolute_pathname (const std::string& s)
111 {
112 return (instance_ok ())
113 ? m_instance->do_absolute_pathname (s) : false;
114 }
115
116 bool
117 env::rooted_relative_pathname (const std::string& s)
118 {
119 return (instance_ok ())
120 ? m_instance->do_rooted_relative_pathname (s) : false;
121 }
122
123 std::string
124 env::base_pathname (const std::string& s)
125 {
126 return (instance_ok ())
127 ? m_instance->do_base_pathname (s) : "";
128 }
129
130 std::string
131 env::make_absolute (const std::string& s, const std::string& dot_path)
132 {
133 return (instance_ok ())
134 ? m_instance->do_make_absolute (s, dot_path) : "";
135 }
136
137 std::string
138 env::get_current_directory ()
139 {
140 return (instance_ok ())
141 ? m_instance->do_getcwd () : "";
142 }
143
144 std::string
145 env::get_home_directory ()
146 {
147 return (instance_ok ())
148 ? m_instance->do_get_home_directory () : "";
149 }
150
151 std::string
152 env::get_temp_directory ()
153 {
154 return (instance_ok ())
155 ? m_instance->do_get_temp_directory () : "";
156 }
157
158 std::string
159 env::get_user_config_directory ()
160 {
161 return (instance_ok ())
162 ? m_instance->do_get_user_config_directory () : "";
163 }
164
165 std::string
166 env::get_user_data_directory ()
167 {
168 return (instance_ok ())
169 ? m_instance->do_get_user_data_directory () : "";
170 }
171
172 std::string
173 env::get_program_name (void)
174 {
175 return (instance_ok ())
176 ? m_instance->m_prog_name : "";
177 }
178
179 std::string
180 env::get_program_invocation_name (void)
181 {
182 return (instance_ok ())
183 ? m_instance->m_prog_invocation_name : "";
184 }
185
186 void
187 env::set_program_name (const std::string& s)
188 {
189 if (instance_ok ())
190 m_instance->do_set_program_name (s);
191 }
192
193 std::string
194 env::get_user_name (void)
195 {
196 return (instance_ok ())
197 ? m_instance->do_get_user_name () : "";
198 }
199
200 std::string
201 env::get_host_name (void)
202 {
203 return (instance_ok ())
204 ? m_instance->do_get_host_name () : "";
205 }
206
207 std::string
208 env::do_get_temp_directory (void) const
209 {
210 std::string tempd = do_getenv ("TMPDIR");
211
212 #if defined (__MINGW32__) || defined (_MSC_VER)
213
214 if (tempd.empty ())
215 tempd = do_getenv ("TEMP");
216
217 if (tempd.empty ())
218 tempd = do_getenv ("TMP");
219
220 #if defined (P_tmpdir)
221 if (tempd.empty ())
222 tempd = P_tmpdir;
223 #endif
224
225 // Some versions of MinGW and MSVC either don't define P_tmpdir, or
226 // define it to a single backslash. In such cases just use C:\temp.
227 if (tempd.empty () || tempd == R"(\)")
228 tempd = R"(c:\temp)";
229
230 #else
231
232 if (tempd.empty ())
233 tempd = do_getenv ("TMP");
234
235 #if defined (P_tmpdir)
236 if (tempd.empty ())
237 tempd = P_tmpdir;
238 #else
239 if (tempd.empty ())
240 tempd = "/tmp";
241 #endif
242
243 #endif
244
245 return tempd;
246 }
247
248 std::string
249 env::do_get_user_config_directory (void)
250 {
251 std::string cfg_dir;
252
253 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && defined (OCTAVE_USE_WINDOWS_API)
254 wchar_t path[MAX_PATH+1];
255 if (SHGetFolderPathW (nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY,
256 nullptr, SHGFP_TYPE_CURRENT, path) == S_OK)
257 cfg_dir = u8_from_wstring (path);
258 #else
259 cfg_dir = do_getenv ("XDG_CONFIG_HOME");
260 #endif
261
262 if (cfg_dir.empty ())
263 cfg_dir = do_get_home_directory () + sys::file_ops::dir_sep_str ()
264 + ".config";
265
266 return cfg_dir;
267 }
268
269 std::string
270 env::do_get_user_data_directory (void)
271 {
272 std::string data_dir;
273
274 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && defined (OCTAVE_USE_WINDOWS_API)
275 wchar_t path[MAX_PATH+1];
276 if (SHGetFolderPathW (nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY,
277 nullptr, SHGFP_TYPE_CURRENT, path) == S_OK)
278 data_dir = u8_from_wstring (path);
279 #else
280 data_dir = do_getenv ("XDG_DATA_HOME");
281 #endif
282
283 if (data_dir.empty ())
284 data_dir = do_get_home_directory () + sys::file_ops::dir_sep_str ()
285 + ".local" + sys::file_ops::dir_sep_str () + "share";
286
287 return data_dir;
288 }
289
290
291 // FIXME: this leaves no way to distinguish between a
292 // variable that is not set and one that is set to the empty string.
293 // Is this a problem?
294
295 std::string
296 env::getenv (const std::string& name)
297 {
298 return (instance_ok ())
299 ? m_instance->do_getenv (name) : "";
300 }
301
302 void
303 env::putenv (const std::string& name, const std::string& value)
304 {
305 putenv_wrapper (name, value);
306 }
307
308 bool
309 env::have_x11_display (void)
310 {
311 std::string display = getenv ("DISPLAY");
312
313 return ! display.empty ();
314 }
315
316 bool
317 env::chdir (const std::string& newdir)
318 {
319 return (instance_ok ())
320 ? m_instance->do_chdir (newdir) : false;
321 }
322
323 void
324 env::do_set_program_name (const std::string& s)
325 {
326 static bool initialized = false;
327
328 if (! initialized)
329 {
330 // octave_set_program_name_wrapper returns a cleaned up
331 // version of the program name (stripping libtool's "lt-"
332 // prefix, for example).
333
334 // The string passed to gnulib's ::set_program_name function must
335 // exist for the duration of the program so allocate a copy here
336 // instead of passing S.c_str () which only exists as long as the
337 // string object S.
338
339 m_prog_invocation_name
340 = octave_set_program_name_wrapper (strsave (s.c_str ()));
341
342 std::size_t pos
343 = m_prog_invocation_name.find_last_of (sys::file_ops::dir_sep_chars ());
344
345 // Also keep a shortened version of the program name.
346 m_prog_name = (pos == std::string::npos
347 ? m_prog_invocation_name
348 : m_prog_invocation_name.substr (pos+1));
349
350 initialized = true;
351 }
352 }
353
354 // Return a pretty pathname. If the first part of the pathname is the
355 // same as $HOME, then replace that with '~'.
356
357 std::string
358 env::do_polite_directory_format (const std::string& name)
359 {
360 std::string retval;
361
362 std::string home_dir = do_get_home_directory ();
363
364 std::size_t len = home_dir.length ();
365
366 if (len > 1 && home_dir == name.substr (0, len)
367 && (name.length () == len || sys::file_ops::is_dir_sep (name[len])))
368 {
369 retval = "~";
370 retval.append (name.substr (len));
371 }
372 else
373 retval = name;
374
375 return retval;
376 }
377
378 bool
379 env::do_absolute_pathname (const std::string& s) const
380 {
381 std::size_t len = s.length ();
382
383 if (len == 0)
384 return false;
385
386 if (sys::file_ops::is_dir_sep (s[0]))
387 return true;
388
389 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
390 if ((len == 2 && isalpha (s[0]) && s[1] == ':')
391 || (len > 2 && isalpha (s[0]) && s[1] == ':'
392 && sys::file_ops::is_dir_sep (s[2])))
393 return true;
394 #endif
395
396 return false;
397 }
398
399 bool
400 env::do_rooted_relative_pathname (const std::string& s) const
401 {
402 std::size_t len = s.length ();
403
404 if (len == 0)
405 return false;
406
407 if (len == 1 && s[0] == '.')
408 return true;
409
410 if (len > 1 && s[0] == '.' && sys::file_ops::is_dir_sep (s[1]))
411 return true;
412
413 if (len == 2 && s[0] == '.' && s[1] == '.')
414 return true;
415
416 if (len > 2 && s[0] == '.' && s[1] == '.'
417 && sys::file_ops::is_dir_sep (s[2]))
418 return true;
419
420 return false;
421 }
422
423 // Return the 'basename' of the pathname in STRING (the stuff after
424 // the last directory separator). If STRING is not a full pathname,
425 // simply return it.
426
427 std::string
428 env::do_base_pathname (const std::string& s) const
429 {
430 if (! (do_absolute_pathname (s) || do_rooted_relative_pathname (s)))
431 return s;
432
433 std::size_t pos = s.find_last_of (sys::file_ops::dir_sep_chars ());
434
435 if (pos == std::string::npos)
436 return s;
437 else
438 return s.substr (pos+1);
439 }
440
441 // Turn STRING (a pathname) into an absolute pathname, assuming that
442 // DOT_PATH contains the symbolic location of the current directory.
443
444 std::string
445 env::do_make_absolute (const std::string& s,
446 const std::string& dot_path) const
447 {
448 if (dot_path.empty () || s.empty () || do_absolute_pathname (s))
449 return s;
450
451 // Optimization: every time Octave returns to the prompt it calls
452 // make_absolute_filename with '.' as argument.
453 if (s == ".")
454 return dot_path;
455
456 std::string current_dir = dot_path;
457
458 if (! sys::file_ops::is_dir_sep (current_dir.back ()))
459 current_dir.append (sys::file_ops::dir_sep_str ());
460
461 std::size_t i = 0;
462 std::size_t slen = s.length ();
463
464 while (i < slen)
465 {
466 if (s[i] == '.')
94 { 467 {
95 m_instance = new env (); 468 if (i + 1 == slen)
96 singleton_cleanup_list::add (cleanup_instance); 469 break;
470
471 if (sys::file_ops::is_dir_sep (s[i+1]))
472 {
473 i += 2;
474 continue;
475 }
476
477 if (s[i+1] == '.'
478 && (i + 2 == slen
479 || sys::file_ops::is_dir_sep (s[i+2])))
480 {
481 i += 2;
482 if (i != slen)
483 i++;
484
485 pathname_backup (current_dir, 1);
486
487 continue;
488 }
97 } 489 }
98 490
99 return retval; 491 std::size_t sep_pos;
100 } 492 sep_pos = s.find_first_of (sys::file_ops::dir_sep_chars (), i);
101 493
102 std::string 494 if (sep_pos == std::string::npos)
103 env::polite_directory_format (const std::string& name)
104 {
105 return (instance_ok ())
106 ? m_instance->do_polite_directory_format (name) : "";
107 }
108
109 bool
110 env::absolute_pathname (const std::string& s)
111 {
112 return (instance_ok ())
113 ? m_instance->do_absolute_pathname (s) : false;
114 }
115
116 bool
117 env::rooted_relative_pathname (const std::string& s)
118 {
119 return (instance_ok ())
120 ? m_instance->do_rooted_relative_pathname (s) : false;
121 }
122
123 std::string
124 env::base_pathname (const std::string& s)
125 {
126 return (instance_ok ())
127 ? m_instance->do_base_pathname (s) : "";
128 }
129
130 std::string
131 env::make_absolute (const std::string& s, const std::string& dot_path)
132 {
133 return (instance_ok ())
134 ? m_instance->do_make_absolute (s, dot_path) : "";
135 }
136
137 std::string
138 env::get_current_directory ()
139 {
140 return (instance_ok ())
141 ? m_instance->do_getcwd () : "";
142 }
143
144 std::string
145 env::get_home_directory ()
146 {
147 return (instance_ok ())
148 ? m_instance->do_get_home_directory () : "";
149 }
150
151 std::string
152 env::get_temp_directory ()
153 {
154 return (instance_ok ())
155 ? m_instance->do_get_temp_directory () : "";
156 }
157
158 std::string
159 env::get_user_config_directory ()
160 {
161 return (instance_ok ())
162 ? m_instance->do_get_user_config_directory () : "";
163 }
164
165 std::string
166 env::get_user_data_directory ()
167 {
168 return (instance_ok ())
169 ? m_instance->do_get_user_data_directory () : "";
170 }
171
172 std::string
173 env::get_program_name (void)
174 {
175 return (instance_ok ())
176 ? m_instance->m_prog_name : "";
177 }
178
179 std::string
180 env::get_program_invocation_name (void)
181 {
182 return (instance_ok ())
183 ? m_instance->m_prog_invocation_name : "";
184 }
185
186 void
187 env::set_program_name (const std::string& s)
188 {
189 if (instance_ok ())
190 m_instance->do_set_program_name (s);
191 }
192
193 std::string
194 env::get_user_name (void)
195 {
196 return (instance_ok ())
197 ? m_instance->do_get_user_name () : "";
198 }
199
200 std::string
201 env::get_host_name (void)
202 {
203 return (instance_ok ())
204 ? m_instance->do_get_host_name () : "";
205 }
206
207 std::string
208 env::do_get_temp_directory (void) const
209 {
210 std::string tempd = do_getenv ("TMPDIR");
211
212 #if defined (__MINGW32__) || defined (_MSC_VER)
213
214 if (tempd.empty ())
215 tempd = do_getenv ("TEMP");
216
217 if (tempd.empty ())
218 tempd = do_getenv ("TMP");
219
220 #if defined (P_tmpdir)
221 if (tempd.empty ())
222 tempd = P_tmpdir;
223 #endif
224
225 // Some versions of MinGW and MSVC either don't define P_tmpdir, or
226 // define it to a single backslash. In such cases just use C:\temp.
227 if (tempd.empty () || tempd == R"(\)")
228 tempd = R"(c:\temp)";
229
230 #else
231
232 if (tempd.empty ())
233 tempd = do_getenv ("TMP");
234
235 #if defined (P_tmpdir)
236 if (tempd.empty ())
237 tempd = P_tmpdir;
238 #else
239 if (tempd.empty ())
240 tempd = "/tmp";
241 #endif
242
243 #endif
244
245 return tempd;
246 }
247
248 std::string
249 env::do_get_user_config_directory (void)
250 {
251 std::string cfg_dir;
252
253 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && defined (OCTAVE_USE_WINDOWS_API)
254 wchar_t path[MAX_PATH+1];
255 if (SHGetFolderPathW (nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY,
256 nullptr, SHGFP_TYPE_CURRENT, path) == S_OK)
257 cfg_dir = u8_from_wstring (path);
258 #else
259 cfg_dir = do_getenv ("XDG_CONFIG_HOME");
260 #endif
261
262 if (cfg_dir.empty ())
263 cfg_dir = do_get_home_directory () + sys::file_ops::dir_sep_str ()
264 + ".config";
265
266 return cfg_dir;
267 }
268
269 std::string
270 env::do_get_user_data_directory (void)
271 {
272 std::string data_dir;
273
274 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && defined (OCTAVE_USE_WINDOWS_API)
275 wchar_t path[MAX_PATH+1];
276 if (SHGetFolderPathW (nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY,
277 nullptr, SHGFP_TYPE_CURRENT, path) == S_OK)
278 data_dir = u8_from_wstring (path);
279 #else
280 data_dir = do_getenv ("XDG_DATA_HOME");
281 #endif
282
283 if (data_dir.empty ())
284 data_dir = do_get_home_directory () + sys::file_ops::dir_sep_str ()
285 + ".local" + sys::file_ops::dir_sep_str () + "share";
286
287 return data_dir;
288 }
289
290
291 // FIXME: this leaves no way to distinguish between a
292 // variable that is not set and one that is set to the empty string.
293 // Is this a problem?
294
295 std::string
296 env::getenv (const std::string& name)
297 {
298 return (instance_ok ())
299 ? m_instance->do_getenv (name) : "";
300 }
301
302 void
303 env::putenv (const std::string& name, const std::string& value)
304 {
305 putenv_wrapper (name, value);
306 }
307
308 bool
309 env::have_x11_display (void)
310 {
311 std::string display = getenv ("DISPLAY");
312
313 return ! display.empty ();
314 }
315
316 bool
317 env::chdir (const std::string& newdir)
318 {
319 return (instance_ok ())
320 ? m_instance->do_chdir (newdir) : false;
321 }
322
323 void
324 env::do_set_program_name (const std::string& s)
325 {
326 static bool initialized = false;
327
328 if (! initialized)
329 { 495 {
330 // octave_set_program_name_wrapper returns a cleaned up 496 current_dir.append (s, i, sep_pos-i);
331 // version of the program name (stripping libtool's "lt-" 497 break;
332 // prefix, for example).
333
334 // The string passed to gnulib's ::set_program_name function must
335 // exist for the duration of the program so allocate a copy here
336 // instead of passing S.c_str () which only exists as long as the
337 // string object S.
338
339 m_prog_invocation_name
340 = octave_set_program_name_wrapper (strsave (s.c_str ()));
341
342 std::size_t pos
343 = m_prog_invocation_name.find_last_of (sys::file_ops::dir_sep_chars ());
344
345 // Also keep a shortened version of the program name.
346 m_prog_name = (pos == std::string::npos
347 ? m_prog_invocation_name
348 : m_prog_invocation_name.substr (pos+1));
349
350 initialized = true;
351 } 498 }
352 } 499 else if (sep_pos == i)
353
354 // Return a pretty pathname. If the first part of the pathname is the
355 // same as $HOME, then replace that with '~'.
356
357 std::string
358 env::do_polite_directory_format (const std::string& name)
359 {
360 std::string retval;
361
362 std::string home_dir = do_get_home_directory ();
363
364 std::size_t len = home_dir.length ();
365
366 if (len > 1 && home_dir == name.substr (0, len)
367 && (name.length () == len || sys::file_ops::is_dir_sep (name[len])))
368 { 500 {
369 retval = "~"; 501 /* Two separators in a row, skip adding 2nd separator */
370 retval.append (name.substr (len)); 502 i++;
371 } 503 }
372 else 504 else
373 retval = name; 505 {
374 506 current_dir.append (s, i, sep_pos-i+1);
375 return retval; 507 i = sep_pos + 1;
376 } 508 }
377 509 }
378 bool 510
379 env::do_absolute_pathname (const std::string& s) const 511 // Strip any trailing directory separator
380 { 512 if (sys::file_ops::is_dir_sep (current_dir.back ()))
381 std::size_t len = s.length (); 513 current_dir.pop_back ();
382 514
383 if (len == 0) 515 return current_dir;
384 return false; 516 }
385 517
386 if (sys::file_ops::is_dir_sep (s[0])) 518 // Return a string which is the current working directory.
387 return true; 519
520 std::string
521 env::do_getcwd (void)
522 {
523 if (! m_follow_symbolic_links)
524 m_current_directory = "";
525
526 if (m_verbatim_pwd || m_current_directory.empty ())
527 m_current_directory = sys::getcwd ();
528
529 return m_current_directory;
530 }
531
532 // This value is not cached because it can change while Octave is
533 // running.
534
535 std::string
536 env::do_get_home_directory (void)
537 {
538 std::string hd = do_getenv ("HOME");
539
540 #if defined (__MINGW32__) || defined (_MSC_VER)
541 // Maybe we are started directly from cmd.exe.
542 if (hd.empty ())
543 {
544 std::string drv = do_getenv ("HOMEDRIVE");
545 if (drv.empty ())
546 hd = do_getenv ("HOMEPATH");
547 else
548 hd = drv + do_getenv ("HOMEPATH");
549 }
550 #endif
551
552 if (hd.empty ())
553 {
554 sys::password pw = sys::password::getpwuid (sys::getuid ());
555
556 hd = (pw ? pw.dir () : std::string (sys::file_ops::dir_sep_str ()));
557 }
558
559 return hd;
560 }
561
562 std::string
563 env::do_get_user_name (void)
564 {
565 if (m_user_name.empty ())
566 {
567 sys::password pw = sys::password::getpwuid (sys::getuid ());
568
569 m_user_name = (pw ? pw.name () : "unknown");
570 }
571
572 return m_user_name;
573 }
574
575 std::string
576 env::do_get_host_name (void)
577 {
578 if (m_host_name.empty ())
579 {
580 char hostname[1024];
581
582 int status = octave_gethostname_wrapper (hostname, 1023);
583
584 m_host_name = (status < 0) ? "unknown" : hostname;
585 }
586
587 return m_host_name;
588 }
589
590 std::string
591 env::do_getenv (const std::string& name) const
592 {
593 return getenv_wrapper (name);
594 }
595
596 // Do the work of changing to the directory NEWDIR.
597 // Handle symbolic link following, etc.
598
599 bool
600 env::do_chdir (const std::string& newdir)
601 {
602 bool retval = false;
603
604 std::string tmp;
605
606 if (m_follow_symbolic_links)
607 {
608 if (m_current_directory.empty ())
609 do_getcwd ();
610
611 if (m_current_directory.empty ())
612 tmp = newdir;
613 else
614 tmp = do_make_absolute (newdir, m_current_directory);
615
616 // Get rid of trailing directory separator.
617 if (tmp.length () > 1 && sys::file_ops::is_dir_sep (tmp.back ()))
618 tmp.pop_back ();
619
620 if (! sys::chdir (tmp))
621 {
622 m_current_directory = tmp;
623 retval = true;
624 }
625 }
626 else
627 retval = (! sys::chdir (newdir));
628
629 return retval;
630 }
631
632 // Remove the last N directories from PATH.
633
634 void
635 env::pathname_backup (std::string& path, int n) const
636 {
637 if (path.empty ())
638 return;
639
640 std::size_t i = path.length () - 1;
641
642 while (n--)
643 {
644 while (sys::file_ops::is_dir_sep (path[i]) && i > 0)
645 i--;
388 646
389 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) 647 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
390 if ((len == 2 && isalpha (s[0]) && s[1] == ':') 648 // Don't strip file letter part.
391 || (len > 2 && isalpha (s[0]) && s[1] == ':' 649 if (i == 1 && path[i] == ':')
392 && sys::file_ops::is_dir_sep (s[2])))
393 return true;
394 #endif
395
396 return false;
397 }
398
399 bool
400 env::do_rooted_relative_pathname (const std::string& s) const
401 {
402 std::size_t len = s.length ();
403
404 if (len == 0)
405 return false;
406
407 if (len == 1 && s[0] == '.')
408 return true;
409
410 if (len > 1 && s[0] == '.' && sys::file_ops::is_dir_sep (s[1]))
411 return true;
412
413 if (len == 2 && s[0] == '.' && s[1] == '.')
414 return true;
415
416 if (len > 2 && s[0] == '.' && s[1] == '.'
417 && sys::file_ops::is_dir_sep (s[2]))
418 return true;
419
420 return false;
421 }
422
423 // Return the 'basename' of the pathname in STRING (the stuff after
424 // the last directory separator). If STRING is not a full pathname,
425 // simply return it.
426
427 std::string
428 env::do_base_pathname (const std::string& s) const
429 {
430 if (! (do_absolute_pathname (s) || do_rooted_relative_pathname (s)))
431 return s;
432
433 std::size_t pos = s.find_last_of (sys::file_ops::dir_sep_chars ());
434
435 if (pos == std::string::npos)
436 return s;
437 else
438 return s.substr (pos+1);
439 }
440
441 // Turn STRING (a pathname) into an absolute pathname, assuming that
442 // DOT_PATH contains the symbolic location of the current directory.
443
444 std::string
445 env::do_make_absolute (const std::string& s,
446 const std::string& dot_path) const
447 {
448 if (dot_path.empty () || s.empty () || do_absolute_pathname (s))
449 return s;
450
451 // Optimization: every time Octave returns to the prompt it calls
452 // make_absolute_filename with '.' as argument.
453 if (s == ".")
454 return dot_path;
455
456 std::string current_dir = dot_path;
457
458 if (! sys::file_ops::is_dir_sep (current_dir.back ()))
459 current_dir.append (sys::file_ops::dir_sep_str ());
460
461 std::size_t i = 0;
462 std::size_t slen = s.length ();
463
464 while (i < slen)
465 { 650 {
466 if (s[i] == '.') 651 // Keep path separator if present.
467 { 652 i = std::min (i+2, path.length ());
468 if (i + 1 == slen) 653 break;
469 break;
470
471 if (sys::file_ops::is_dir_sep (s[i+1]))
472 {
473 i += 2;
474 continue;
475 }
476
477 if (s[i+1] == '.'
478 && (i + 2 == slen
479 || sys::file_ops::is_dir_sep (s[i+2])))
480 {
481 i += 2;
482 if (i != slen)
483 i++;
484
485 pathname_backup (current_dir, 1);
486
487 continue;
488 }
489 }
490
491 std::size_t sep_pos;
492 sep_pos = s.find_first_of (sys::file_ops::dir_sep_chars (), i);
493
494 if (sep_pos == std::string::npos)
495 {
496 current_dir.append (s, i, sep_pos-i);
497 break;
498 }
499 else if (sep_pos == i)
500 {
501 /* Two separators in a row, skip adding 2nd separator */
502 i++;
503 }
504 else
505 {
506 current_dir.append (s, i, sep_pos-i+1);
507 i = sep_pos + 1;
508 }
509 } 654 }
510 655 #endif
511 // Strip any trailing directory separator 656
512 if (sys::file_ops::is_dir_sep (current_dir.back ())) 657 while (! sys::file_ops::is_dir_sep (path[i]) && i > 0)
513 current_dir.pop_back (); 658 i--;
514 659
515 return current_dir; 660 i++;
516 } 661 }
517 662
518 // Return a string which is the current working directory. 663 path.resize (i);
519 664 }
520 std::string 665
521 env::do_getcwd (void) 666 void
522 { 667 env::error (int err_num) const
523 if (! m_follow_symbolic_links) 668 {
524 m_current_directory = ""; 669 (*current_liboctave_error_handler) ("%s", std::strerror (err_num));
525 670 }
526 if (m_verbatim_pwd || m_current_directory.empty ()) 671
527 m_current_directory = sys::getcwd (); 672 void
528 673 env::error (const std::string& s) const
529 return m_current_directory; 674 {
530 } 675 (*current_liboctave_error_handler) ("%s", s.c_str ());
531 676 }
532 // This value is not cached because it can change while Octave is
533 // running.
534
535 std::string
536 env::do_get_home_directory (void)
537 {
538 std::string hd = do_getenv ("HOME");
539
540 #if defined (__MINGW32__) || defined (_MSC_VER)
541 // Maybe we are started directly from cmd.exe.
542 if (hd.empty ())
543 {
544 std::string drv = do_getenv ("HOMEDRIVE");
545 if (drv.empty ())
546 hd = do_getenv ("HOMEPATH");
547 else
548 hd = drv + do_getenv ("HOMEPATH");
549 }
550 #endif
551
552 if (hd.empty ())
553 {
554 sys::password pw = sys::password::getpwuid (sys::getuid ());
555
556 hd = (pw ? pw.dir () : std::string (sys::file_ops::dir_sep_str ()));
557 }
558
559 return hd;
560 }
561
562 std::string
563 env::do_get_user_name (void)
564 {
565 if (m_user_name.empty ())
566 {
567 sys::password pw = sys::password::getpwuid (sys::getuid ());
568
569 m_user_name = (pw ? pw.name () : "unknown");
570 }
571
572 return m_user_name;
573 }
574
575 std::string
576 env::do_get_host_name (void)
577 {
578 if (m_host_name.empty ())
579 {
580 char hostname[1024];
581
582 int status = octave_gethostname_wrapper (hostname, 1023);
583
584 m_host_name = (status < 0) ? "unknown" : hostname;
585 }
586
587 return m_host_name;
588 }
589
590 std::string
591 env::do_getenv (const std::string& name) const
592 {
593 return getenv_wrapper (name);
594 }
595
596 // Do the work of changing to the directory NEWDIR.
597 // Handle symbolic link following, etc.
598
599 bool
600 env::do_chdir (const std::string& newdir)
601 {
602 bool retval = false;
603
604 std::string tmp;
605
606 if (m_follow_symbolic_links)
607 {
608 if (m_current_directory.empty ())
609 do_getcwd ();
610
611 if (m_current_directory.empty ())
612 tmp = newdir;
613 else
614 tmp = do_make_absolute (newdir, m_current_directory);
615
616 // Get rid of trailing directory separator.
617 if (tmp.length () > 1 && sys::file_ops::is_dir_sep (tmp.back ()))
618 tmp.pop_back ();
619
620 if (! sys::chdir (tmp))
621 {
622 m_current_directory = tmp;
623 retval = true;
624 }
625 }
626 else
627 retval = (! sys::chdir (newdir));
628
629 return retval;
630 }
631
632 // Remove the last N directories from PATH.
633
634 void
635 env::pathname_backup (std::string& path, int n) const
636 {
637 if (path.empty ())
638 return;
639
640 std::size_t i = path.length () - 1;
641
642 while (n--)
643 {
644 while (sys::file_ops::is_dir_sep (path[i]) && i > 0)
645 i--;
646
647 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
648 // Don't strip file letter part.
649 if (i == 1 && path[i] == ':')
650 {
651 // Keep path separator if present.
652 i = std::min (i+2, path.length ());
653 break;
654 }
655 #endif
656
657 while (! sys::file_ops::is_dir_sep (path[i]) && i > 0)
658 i--;
659
660 i++;
661 }
662
663 path.resize (i);
664 }
665
666 void
667 env::error (int err_num) const
668 {
669 (*current_liboctave_error_handler) ("%s", std::strerror (err_num));
670 }
671
672 void
673 env::error (const std::string& s) const
674 {
675 (*current_liboctave_error_handler) ("%s", s.c_str ());
676 }
677 677
678 OCTAVE_END_NAMESPACE(sys) 678 OCTAVE_END_NAMESPACE(sys)
679 OCTAVE_END_NAMESPACE(octave) 679 OCTAVE_END_NAMESPACE(octave)