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