aboutsummaryrefslogtreecommitdiff
path: root/libbutl/process-io.cxx
blob: c29bbc04bf51c1eea52b8ec23df3e6ae71252421 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// file      : libbutl/process-io.cxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef __cpp_modules_ts
#include <libbutl/process-io.mxx>
#endif

// C includes.

#ifndef __cpp_lib_modules_ts
#include <ostream>

#include <cstring> // strchr()
#endif

// Other includes.

#ifdef __cpp_modules_ts
module butl.process_io;

// Only imports additional to interface.
#ifdef __clang__
#ifdef __cpp_lib_modules_ts
import std.core;
import std.io;
#endif
import butl.process;
#endif

import butl.path-io;
#else
#include <libbutl/path-io.mxx>
#endif

using namespace std;

namespace butl
{
  // process_env
  //
  ostream&
  operator<< (ostream& o, const process_env& env)
  {
    bool first (true);
    const dir_path* cwd (env.cwd);

    if (cwd != nullptr && !cwd->empty ())
    {
      if (cwd->string ().find (' ') != string::npos)
        o << "PWD=\"" << *cwd << '"';
      else
        o << "PWD=" << *cwd;

      first = false;
    }

    if (env.vars != nullptr)
    {
      for (const char* const* ev (env.vars); *ev != nullptr; ++ev)
      {
        if (first)
          first = false;
        else
          o << ' ';

        const char* v (*ev);

        // If there is no `=` in the string, then this is just a name
        // (variable unset) and we print it as the empty string assignment.
        //
        const char* eq (strchr (v, '='));

        // If there is the space character in the string, then we quote the
        // variable value, unless this is the variable name that contains the
        // space character in which case we quote the whole (potentially
        // broken) assignment.
        //
        const char* sp (strchr (v, ' '));

        if (eq != nullptr)             // Variable assignment?
        {
          if (sp == nullptr)           // No space?
          {
            o << v;
          }
          else if (eq < sp)            // Space in the value?
          {
            o.write (v, eq - v + 1);   // Name and '='.
            o << '"' << eq + 1 << '"'; // Quoted value.
          }
          else                         // Space in the name.
            o << '"' << v << '"';
        }
        else                           // Variable unset.
        {
          if (sp == nullptr)           // No space?
            o << v << '=';
          else                         // Space in the name.
            o << '"' << v << "=\"";
        }
      }
    }

    return o;
  }
}