Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/kwsys/System.c
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
3
#include "kwsysPrivate.h"
4
#include KWSYS_HEADER(System.h)
5
6
/* Work-around CMake dependency scanning limitation.  This must
7
   duplicate the above list of headers.  */
8
#if 0
9
#  include "System.h.in"
10
#endif
11
12
#include <ctype.h>  /* isspace */
13
#include <stddef.h> /* ptrdiff_t */
14
#include <stdlib.h> /* malloc, free */
15
#include <string.h> /* memcpy */
16
17
#include <stdio.h>
18
19
#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T
20
typedef ptrdiff_t kwsysSystem_ptrdiff_t;
21
#else
22
typedef int kwsysSystem_ptrdiff_t;
23
#endif
24
25
static int kwsysSystem__AppendByte(char const* local, char** begin, char** end,
26
                                   int* size, char c)
27
0
{
28
  /* Allocate space for the character.  */
29
0
  if ((*end - *begin) >= *size) {
30
0
    kwsysSystem_ptrdiff_t length = *end - *begin;
31
0
    char* newBuffer = (char*)malloc((size_t)(*size * 2));
32
0
    if (!newBuffer) {
33
0
      return 0;
34
0
    }
35
0
    memcpy(newBuffer, *begin, (size_t)(length) * sizeof(char));
36
0
    if (*begin != local) {
37
0
      free(*begin);
38
0
    }
39
0
    *begin = newBuffer;
40
0
    *end = *begin + length;
41
0
    *size *= 2;
42
0
  }
43
44
  /* Store the character.  */
45
0
  *(*end)++ = c;
46
0
  return 1;
47
0
}
48
49
static int kwsysSystem__AppendArgument(char** local, char*** begin,
50
                                       char*** end, int* size, char* arg_local,
51
                                       char** arg_begin, char** arg_end,
52
                                       int* arg_size)
53
0
{
54
  /* Append a null-terminator to the argument string.  */
55
0
  if (!kwsysSystem__AppendByte(arg_local, arg_begin, arg_end, arg_size,
56
0
                               '\0')) {
57
0
    return 0;
58
0
  }
59
60
  /* Allocate space for the argument pointer.  */
61
0
  if ((*end - *begin) >= *size) {
62
0
    kwsysSystem_ptrdiff_t length = *end - *begin;
63
0
    char** newPointers = (char**)malloc((size_t)(*size) * 2 * sizeof(char*));
64
0
    if (!newPointers) {
65
0
      return 0;
66
0
    }
67
0
    memcpy(newPointers, *begin, (size_t)(length) * sizeof(char*));
68
0
    if (*begin != local) {
69
0
      free(*begin);
70
0
    }
71
0
    *begin = newPointers;
72
0
    *end = *begin + length;
73
0
    *size *= 2;
74
0
  }
75
76
  /* Allocate space for the argument string.  */
77
0
  **end = (char*)malloc((size_t)(*arg_end - *arg_begin));
78
0
  if (!**end) {
79
0
    return 0;
80
0
  }
81
82
  /* Store the argument in the command array.  */
83
0
  memcpy(**end, *arg_begin, (size_t)(*arg_end - *arg_begin));
84
0
  ++(*end);
85
86
  /* Reset the argument to be empty.  */
87
0
  *arg_end = *arg_begin;
88
89
0
  return 1;
90
0
}
91
92
0
#define KWSYSPE_LOCAL_BYTE_COUNT 1024
93
0
#define KWSYSPE_LOCAL_ARGS_COUNT 32
94
static char** kwsysSystem__ParseUnixCommand(char const* command, int flags)
95
0
{
96
  /* Create a buffer for argument pointers during parsing.  */
97
0
  char* local_pointers[KWSYSPE_LOCAL_ARGS_COUNT];
98
0
  int pointers_size = KWSYSPE_LOCAL_ARGS_COUNT;
99
0
  char** pointer_begin = local_pointers;
100
0
  char** pointer_end = pointer_begin;
101
102
  /* Create a buffer for argument strings during parsing.  */
103
0
  char local_buffer[KWSYSPE_LOCAL_BYTE_COUNT];
104
0
  int buffer_size = KWSYSPE_LOCAL_BYTE_COUNT;
105
0
  char* buffer_begin = local_buffer;
106
0
  char* buffer_end = buffer_begin;
107
108
  /* Parse the command string.  Try to behave like a UNIX shell.  */
109
0
  char** newCommand = 0;
110
0
  char const* c = command;
111
0
  int in_argument = 0;
112
0
  int in_escape = 0;
113
0
  int in_single = 0;
114
0
  int in_double = 0;
115
0
  int failed = 0;
116
0
  for (; *c; ++c) {
117
0
    if (in_escape) {
118
      /* This character is escaped so do no special handling.  */
119
0
      if (!in_argument) {
120
0
        in_argument = 1;
121
0
      }
122
0
      if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin, &buffer_end,
123
0
                                   &buffer_size, *c)) {
124
0
        failed = 1;
125
0
        break;
126
0
      }
127
0
      in_escape = 0;
128
0
    } else if (*c == '\\') {
129
      /* The next character should be escaped.  */
130
0
      in_escape = 1;
131
0
    } else if (*c == '\'' && !in_double) {
132
      /* Enter or exit single-quote state.  */
133
0
      if (in_single) {
134
0
        in_single = 0;
135
0
      } else {
136
0
        in_single = 1;
137
0
        if (!in_argument) {
138
0
          in_argument = 1;
139
0
        }
140
0
      }
141
0
    } else if (*c == '"' && !in_single) {
142
      /* Enter or exit double-quote state.  */
143
0
      if (in_double) {
144
0
        in_double = 0;
145
0
      } else {
146
0
        in_double = 1;
147
0
        if (!in_argument) {
148
0
          in_argument = 1;
149
0
        }
150
0
      }
151
0
    } else if (isspace((unsigned char)*c)) {
152
0
      if (in_argument) {
153
0
        if (in_single || in_double) {
154
          /* This space belongs to a quoted argument.  */
155
0
          if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
156
0
                                       &buffer_end, &buffer_size, *c)) {
157
0
            failed = 1;
158
0
            break;
159
0
          }
160
0
        } else {
161
          /* This argument has been terminated by whitespace.  */
162
0
          if (!kwsysSystem__AppendArgument(
163
0
                local_pointers, &pointer_begin, &pointer_end, &pointers_size,
164
0
                local_buffer, &buffer_begin, &buffer_end, &buffer_size)) {
165
0
            failed = 1;
166
0
            break;
167
0
          }
168
0
          in_argument = 0;
169
0
        }
170
0
      }
171
0
    } else {
172
      /* This character belong to an argument.  */
173
0
      if (!in_argument) {
174
0
        in_argument = 1;
175
0
      }
176
0
      if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin, &buffer_end,
177
0
                                   &buffer_size, *c)) {
178
0
        failed = 1;
179
0
        break;
180
0
      }
181
0
    }
182
0
  }
183
184
  /* Finish the last argument.  */
185
0
  if (in_argument) {
186
0
    if (!kwsysSystem__AppendArgument(
187
0
          local_pointers, &pointer_begin, &pointer_end, &pointers_size,
188
0
          local_buffer, &buffer_begin, &buffer_end, &buffer_size)) {
189
0
      failed = 1;
190
0
    }
191
0
  }
192
193
  /* If we still have memory allocate space for the new command
194
     buffer.  */
195
0
  if (!failed) {
196
0
    kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
197
0
    newCommand = (char**)malloc((size_t)(n + 1) * sizeof(char*));
198
0
  }
199
200
0
  if (newCommand) {
201
    /* Copy the arguments into the new command buffer.  */
202
0
    kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
203
0
    memcpy(newCommand, pointer_begin, sizeof(char*) * (size_t)(n));
204
0
    newCommand[n] = 0;
205
0
  } else {
206
    /* Free arguments already allocated.  */
207
0
    while (pointer_end != pointer_begin) {
208
0
      free(*(--pointer_end));
209
0
    }
210
0
  }
211
212
  /* Free temporary buffers.  */
213
0
  if (pointer_begin != local_pointers) {
214
0
    free(pointer_begin);
215
0
  }
216
0
  if (buffer_begin != local_buffer) {
217
0
    free(buffer_begin);
218
0
  }
219
220
  /* The flags argument is currently unused.  */
221
0
  (void)flags;
222
223
  /* Return the final command buffer.  */
224
0
  return newCommand;
225
0
}
226
227
char** kwsysSystem_Parse_CommandForUnix(char const* command, int flags)
228
0
{
229
  /* Validate the flags.  */
230
0
  if (flags != 0) {
231
0
    return 0;
232
0
  }
233
234
  /* Forward to our internal implementation.  */
235
0
  return kwsysSystem__ParseUnixCommand(command, flags);
236
0
}