Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/bin/cmdtoargs.c
32285 views
/*1* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/242526/*27* Converts a single string command line to the traditional argc, argv.28* There are rules which govern the breaking of the the arguments, and29* these rules are embodied in the regression tests below, and duplicated30* in the jdk regression tests.31*/3233#ifndef IDE_STANDALONE34#include "java.h"35#include "jli_util.h"36#else /* IDE_STANDALONE */37// The defines we need for stand alone testing38#include <stdio.h>39#include <stdlib.h>40#include <Windows.h>41#define JNI_TRUE TRUE42#define JNI_FALSE FALSE43#define JLI_MemRealloc realloc44#define JLI_StringDup _strdup45#define JLI_MemFree free46#define jboolean boolean47typedef struct {48char* arg;49boolean has_wildcard;50} StdArg ;51#endif52static StdArg *stdargs;53static int stdargc;5455static int copyCh(USHORT ch, char* dest) {56if (HIBYTE(ch) == 0) {57*dest = (char)ch;58return 1;59} else {60*((USHORT *)dest) = ch;61return 2;62}63}6465static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) {6667char* src = cmdline;68char* dest = arg;69jboolean separator = JNI_FALSE;70int quotes = 0;71int slashes = 0;7273// "prev"/"ch" may contain either a single byte, or a double byte74// character encoded in CP_ACP.75USHORT prev = 0;76USHORT ch = 0;77int i;78jboolean done = JNI_FALSE;79int charLength;8081*wildcard = JNI_FALSE;82while (!done) {83charLength = CharNextExA(CP_ACP, src, 0) - src;84if (charLength == 0) {85break;86} else if (charLength == 1) {87ch = (USHORT)(UCHAR)src[0];88} else {89ch = ((USHORT *)src)[0];90}9192switch (ch) {93case L'"':94if (separator) {95done = JNI_TRUE;96break;97}98if (prev == L'\\') {99for (i = 1; i < slashes; i += 2) {100dest += copyCh(prev, dest);101}102if (slashes % 2 == 1) {103dest += copyCh(ch, dest);104} else {105quotes++;106}107} else if (prev == L'"' && quotes % 2 == 0) {108quotes++;109dest += copyCh(ch, dest); // emit every other consecutive quote110} else if (quotes == 0) {111quotes++; // starting quote112} else {113quotes--; // matching quote114}115slashes = 0;116break;117118case L'\\':119slashes++;120if (separator) {121done = JNI_TRUE;122separator = JNI_FALSE;123}124break;125126case L' ':127case L'\t':128if (prev == L'\\') {129for (i = 0 ; i < slashes; i++) {130dest += copyCh(prev, dest);131}132}133if (quotes % 2 == 1) {134dest += copyCh(ch, dest);135} else {136separator = JNI_TRUE;137}138slashes = 0;139break;140141case L'*':142case L'?':143if (separator) {144done = JNI_TRUE;145separator = JNI_FALSE;146break;147}148if (quotes % 2 == 0) {149*wildcard = JNI_TRUE;150}151if (prev == L'\\') {152for (i = 0 ; i < slashes ; i++) {153dest += copyCh(prev, dest);154}155}156dest += copyCh(ch, dest);157slashes = 0;158break;159160default:161if (prev == L'\\') {162for (i = 0 ; i < slashes ; i++) {163dest += copyCh(prev, dest);164}165dest += copyCh(ch, dest);166} else if (separator) {167done = JNI_TRUE;168} else {169dest += copyCh(ch, dest);170}171slashes = 0;172}173174if (!done) {175prev = ch;176src += charLength;177}178}179if (prev == L'\\') {180for (i = 0; i < slashes; i++) {181dest += copyCh(prev, dest);182}183}184*dest = 0;185return done ? src : NULL;186}187188int JLI_GetStdArgc() {189return stdargc;190}191192StdArg* JLI_GetStdArgs() {193return stdargs;194}195196void JLI_CmdToArgs(char* cmdline) {197int nargs = 0;198StdArg* argv = NULL;199jboolean wildcard = JNI_FALSE;200char* src = cmdline;201202// allocate arg buffer with sufficient space to receive the largest arg203char* arg = JLI_StringDup(cmdline);204205do {206src = next_arg(src, arg, &wildcard);207// resize to accommodate another Arg208argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg));209argv[nargs].arg = JLI_StringDup(arg);210argv[nargs].has_wildcard = wildcard;211*arg = NULL;212nargs++;213} while (src != NULL);214215stdargc = nargs;216stdargs = argv;217}218219#ifdef IDE_STANDALONE220void doexit(int rv) {221printf("Hit any key to quit\n");222int c = getchar();223exit(rv);224}225226void doabort() {227doexit(1);228}229230class Vector {231public:232char* cmdline;233int argc;234char* argv[10];235boolean wildcard[10];236boolean enabled;237238Vector(){}239// Initialize our test vector with the program name, argv[0]240// and the single string command line.241Vector(char* pname, char* cline) {242argv[0] = pname;243wildcard[0] = FALSE;244cmdline = cline;245argc = 1;246enabled = TRUE;247}248249// add our expected strings, the program name has already been250// added so ignore that251void add(char* arg, boolean w) {252argv[argc] = arg;253wildcard[argc] = w;254argc++;255}256257void disable() {258enabled = FALSE;259}260261// validate the returned arguments with the expected arguments, using the262// new CmdToArgs method.263bool check() {264// "pgmname" rest of cmdline ie. pgmname + 2 double quotes + space + cmdline from windows265char* cptr = (char*) malloc(strlen(argv[0]) + sizeof(char) * 3 + strlen(cmdline) + 1);266_snprintf(cptr, MAX_PATH, "\"%s\" %s", argv[0], cmdline);267JLI_CmdToArgs(cptr);268free(cptr);269StdArg *kargv = JLI_GetStdArgs();270int kargc = JLI_GetStdArgc();271bool retval = true;272printf("\n===========================\n");273printf("cmdline=%s\n", cmdline);274if (argc != kargc) {275printf("*** argument count does not match\n");276printme();277printtest(kargc, kargv);278doabort();279}280for (int i = 0 ; i < argc && retval == true ; i++) {281if (strcmp(argv[i], kargv[i].arg) != 0) {282printf("*** argument at [%d] don't match\n got: %s\n exp: %s\n",283i, kargv[i].arg, argv[i]);284doabort();285}286}287for (int i = 0 ; i < argc && retval == true ; i++) {288if (wildcard[i] != kargv[i].has_wildcard) {289printf("*** expansion flag at [%d] doesn't match\n got: %d\n exp: %d\n",290i, kargv[i].has_wildcard, wildcard[i]);291doabort();292}293}294for (int i = 0 ; i < kargc ; i++) {295printf("k[%d]=%s\n", i, kargv[i].arg);296printf(" [%d]=%s\n", i, argv[i]);297}298return retval;299}300void printtest(int kargc, StdArg* kargv) {301for (int i = 0 ; i < kargc ; i++) {302printf("k[%d]=%s\n", i, kargv[i].arg);303}304}305void printme() {306for (int i = 0 ; i < argc ; i++) {307printf(" [%d]=%s\n", i, argv[i]);308}309}310};311312void dotest(Vector** vectors) {313Vector* v = vectors[0];314for (int i = 0 ; v != NULL;) {315if (v->enabled) {316v->check();317}318v = vectors[++i];319}320}321322#define MAXV 128323int main(int argc, char* argv[]) {324325int n;326for (n=1; n < argc; n++) {327printf("%d %s\n", n, argv[n]);328}329if (n > 1) {330JLI_CmdToArgs(GetCommandLine());331for (n = 0; n < stdargc; n++) {332printf(" [%d]=%s\n", n, stdargs[n].arg);333printf(" [%d]=%s\n", n, stdargs[n].has_wildcard ? "TRUE" : "FALSE");334}335doexit(0);336}337338Vector *vectors[MAXV];339340memset(vectors, 0, sizeof(vectors));341int i = 0;342Vector* v = new Vector(argv[0], "abcd");343v->add("abcd", FALSE);344// v->disable();345vectors[i++] = v;346347348v = new Vector(argv[0], "\"a b c d\"");349v->add("a b c d", FALSE);350// v->disable();351vectors[i++] = v;352353354v = new Vector(argv[0], "a\"b c d\"e");355v->add("ab c de", FALSE);356// v->disable();357vectors[i++] = v;358359360v = new Vector(argv[0], "ab\\\"cd");361v->add("ab\"cd", FALSE);362// v->disable();363vectors[i++] = v;364365366v = new Vector(argv[0], "\"a b c d\\\\\"");367v->add("a b c d\\", FALSE);368// v->disable();369vectors[i++] = v;370371372v = new Vector(argv[0], "ab\\\\\\\"cd");373v->add("ab\\\"cd", FALSE);374// v->disable();375vectors[i++] = v;376377378// Windows tests379v = new Vector(argv[0], "a\\\\\\c");380v->add("a\\\\\\c", FALSE);381// v->disable();382vectors[i++] = v;383384385v = new Vector(argv[0], "\"a\\\\\\d\"");386v->add("a\\\\\\d", FALSE);387// v->disable();388vectors[i++] = v;389390391v = new Vector(argv[0], "\"a b c\" d e");392v->add("a b c", FALSE);393v->add("d", FALSE);394v->add("e", FALSE);395// v->disable();396vectors[i++] = v;397398399v = new Vector(argv[0], "\"ab\\\"c\" \"\\\\\" d");400v->add("ab\"c", FALSE);401v->add("\\", FALSE);402v->add("d", FALSE);403// v->disable();404vectors[i++] = v;405406407v = new Vector(argv[0], "a\\\\\\c d\"e f\"g h");408v->add("a\\\\\\c", FALSE);409v->add("de fg", FALSE);410v->add("h", FALSE);411// v->disable();412vectors[i++] = v;413414415v = new Vector(argv[0], "a\\\\\\\"b c d");416v->add("a\\\"b", FALSE); // XXX "a\\\\\\\"b"417v->add("c", FALSE);418v->add("d", FALSE);419// v->disable();420vectors[i++] = v;421422423v = new Vector(argv[0], "a\\\\\\\\\"g c\" d e"); // XXX "a\\\\\\\\\"b c\" d e"424v->add("a\\\\\g c", FALSE); // XXX "a\\\\\\\\\"b c"425v->add("d", FALSE);426v->add("e", FALSE);427// v->disable();428vectors[i++] = v;429430431// Additional tests432v = new Vector(argv[0], "\"a b c\"\"");433v->add("a b c\"", FALSE);434// v->disable();435vectors[i++] = v;436437438v = new Vector(argv[0], "\"\"a b c\"\"");439v->add("a", FALSE);440v->add("b", FALSE);441v->add("c", FALSE);442// v->disable();443vectors[i++] = v;444445446v = new Vector(argv[0], "\"\"\"a b c\"\"\"");447v->add("\"a b c\"", FALSE);448// v->disable();449vectors[i++] = v;450451452v = new Vector(argv[0], "\"\"\"\"a b c\"\"\"\"");453v->add("\"a", FALSE);454v->add("b", FALSE);455v->add("c\"", FALSE);456// v->disable();457vectors[i++] = v;458459460v = new Vector(argv[0], "\"\"\"\"\"a b c\"\"\"\"\"");461v->add("\"\"a b c\"\"", FALSE);462// v->disable();463vectors[i++] = v;464465466v = new Vector(argv[0], "\"C:\\TEST A\\\\\"");467v->add("C:\\TEST A\\", FALSE);468// v->disable();469vectors[i++] = v;470471472v = new Vector(argv[0], "\"\"C:\\TEST A\\\\\"\"");473v->add("C:\\TEST", FALSE);474v->add("A\\", FALSE);475// v->disable();476vectors[i++] = v;477478479// test if a wildcard is present480v = new Vector(argv[0], "abc*def");481v->add("abc*def", TRUE);482// v->disable();483vectors[i++] = v;484485486v = new Vector(argv[0], "\"abc*def\"");487v->add("abc*def", FALSE);488// v->disable();489vectors[i++] = v;490491492v = new Vector(argv[0], "*.abc");493v->add("*.abc", TRUE);494// v->disable();495vectors[i++] = v;496497498v = new Vector(argv[0], "\"*.abc\"");499v->add("*.abc", FALSE);500// v->disable();501vectors[i++] = v;502503504v = new Vector(argv[0], "x.???");505v->add("x.???", TRUE);506// v->disable();507vectors[i++] = v;508509510v = new Vector(argv[0], "\"x.???\"");511v->add("x.???", FALSE);512// v->disable();513vectors[i++] = v;514515516v = new Vector(argv[0], "Debug\\*");517v->add("Debug\\*", TRUE);518// v->disable();519vectors[i++] = v;520521522v = new Vector(argv[0], "Debug\\f?a");523v->add("Debug\\f?a", TRUE);524// v->disable();525vectors[i++] = v;526527528v = new Vector(argv[0], "Debug\\?a.java");529v->add("Debug\\?a.java", TRUE);530// v->disable();531vectors[i++] = v;532533534v = new Vector(argv[0], "foo *.noexts");535v->add("foo", FALSE);536v->add("*.noexts", TRUE);537// v->disable();538vectors[i++] = v;539540541v = new Vector(argv[0], "X\\Y\\Z");542v->add("X\\Y\\Z", FALSE);543// v->disable();544vectors[i++] = v;545546547v = new Vector(argv[0], "\\X\\Y\\Z");548v->add("\\X\\Y\\Z", FALSE);549// v->disable();550vectors[i++] = v;551552553v = new Vector(argv[0], "a b");554v->add("a", FALSE);555v->add("b", FALSE);556// v->disable();557vectors[i++] = v;558559560v = new Vector(argv[0], "a\tb");561v->add("a", FALSE);562v->add("b", FALSE);563// v->disable();564vectors[i++] = v;565566567v = new Vector(argv[0], "a \t b");568v->add("a", FALSE);569v->add("b", FALSE);570// v->disable();571vectors[i++] = v;572573v = new Vector(argv[0], "*\\");574v->add("*\\", TRUE);575// v->disable();576vectors[i++] = v;577578v = new Vector(argv[0], "*/");579v->add("*/", TRUE);580// v->disable();581vectors[i++] = v;582583v = new Vector(argv[0], ".\\*");584v->add(".\\*", TRUE);585// v->disable();586vectors[i++] = v;587588v = new Vector(argv[0], "./*");589v->add("./*", TRUE);590// v->disable();591vectors[i++] = v;592593v = new Vector(argv[0], ".\\*");594v->add(".\\*", TRUE);595// v->disable();596vectors[i++] = v;597598v = new Vector(argv[0], ".//*");599v->add(".//*", TRUE);600// v->disable();601vectors[i++] = v;602603v = new Vector(argv[0], "..\\..\\*");604v->add("..\\..\\*", TRUE);605// v->disable();606vectors[i++] = v;607608v = new Vector(argv[0], "../../*");609v->add("../../*", TRUE);610// v->disable();611vectors[i++] = v;612613v = new Vector(argv[0], "..\\..\\");614v->add("..\\..\\", FALSE);615// v->disable();616vectors[i++] = v;617618v = new Vector(argv[0], "../../");619v->add("../../", FALSE);620// v->disable();621vectors[i++] = v;622623v= new Vector(argv[0], "a b\\\\ d");624v->add("a", FALSE);625v->add("b\\\\", FALSE);626v->add("d", FALSE);627vectors[i++] = v;628629v= new Vector(argv[0], "\\\\?");630v->add("\\\\?", TRUE);631vectors[i++] = v;632633v= new Vector(argv[0], "\\\\*");634v->add("\\\\*", TRUE);635vectors[i++] = v;636637dotest(vectors);638printf("All tests pass [%d]\n", i);639doexit(0);640}641#endif /* IDE_STANDALONE */642643644