17745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// Copyright 2014 The Android Open Source Project
27745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner//
37745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// This software is licensed under the terms of the GNU General Public
47745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// License version 2, as published by the Free Software Foundation, and
57745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// may be copied, distributed, and modified under those terms.
67745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner//
77745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// This program is distributed in the hope that it will be useful,
87745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// but WITHOUT ANY WARRANTY; without even the implied warranty of
97745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
107745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner// GNU General Public License for more details.
117745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
127745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner#include "android/utils/win32_cmdline_quote.h"
137745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
147745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner#include <string.h>
157745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
167745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner#include "android/utils/stralloc.h"
177745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner#include "android/utils/system.h"
187745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
197745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turnerchar* win32_cmdline_quote(const char* param) {
207745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  // If |param| doesn't contain any problematic character, just return it as-is.
217745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  size_t n = strcspn(param, " \t\v\n\"");
227745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  if (param[n] == '\0')
237745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      return ASTRDUP(param);
247745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
257745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  // Otherwise, we need to quote some of the characters.
267745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  stralloc_t out = STRALLOC_INIT;
277745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
287745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  // Add initial quote.
297745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  stralloc_add_c(&out, '"');
307745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
317745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  n = 0;
327745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  while (param[n]) {
337745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      size_t num_backslashes = 0;
347745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      while (param[n] == '\\') {
357745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          n++;
367745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          num_backslashes++;
377745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      }
387745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
397745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      if (!param[n]) {
407745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          // End of string, if there are backslashes, double them.
417745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          for (; num_backslashes > 0; num_backslashes--)
427745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner              stralloc_add_str(&out, "\\\\");
437745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          break;
447745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      }
457745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
467745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      if (param[n] == '"') {
477745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          // Escape all backslashes as well as the quote that follows them.
487745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          for (; num_backslashes > 0; num_backslashes--)
497745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner              stralloc_add_str(&out, "\\\\");
507745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          stralloc_add_str(&out, "\\\"");
517745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      } else {
527745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          for (; num_backslashes > 0; num_backslashes--)
537745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner              stralloc_add_c(&out, '\\');
547745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner          stralloc_add_c(&out, param[n]);
557745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      }
567745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner      n++;
577745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  }
587745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
597745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  // Add final quote.
607745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  stralloc_add_c(&out, '"');
617745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner
627745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  char* result = ASTRDUP(stralloc_cstr(&out));
637745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  stralloc_reset(&out);
647745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner  return result;
657745b32edeb9ec1c2763030bb42a8fc0c3e6d8c4David 'Digit' Turner}
66