Re: Possible bug in std.path?

2016-06-20 Thread Hugo via Digitalmars-d

On Monday, 20 June 2016 at 12:55:21 UTC, ag0aep6g wrote:

On Monday, 20 June 2016 at 12:38:23 UTC, Hugo wrote:

Not necessarily, cmd.exe is made in C/C++
AFAIK, most other console applications for Windows behave the 
same way too.


As seen on MSDN, it's how "Microsoft C/C++ startup code" does 
it. It's what you get in a C main's argv. Populating a D main's 
args in a different way would be unusual.


Of course you can parse the command line yourself, and do it 
differently then. You can do this in C, in C++, and in D too. 
But the default is the other way, in all of them.


I guess all the console programs I have used for MS products 
(since MS-DOS) have been unusual then according to MSDN. ;)


Re: Possible bug in std.path?

2016-06-20 Thread ag0aep6g via Digitalmars-d

On Monday, 20 June 2016 at 12:38:23 UTC, Hugo wrote:

Not necessarily, cmd.exe is made in C/C++
AFAIK, most other console applications for Windows behave the 
same way too.


As seen on MSDN, it's how "Microsoft C/C++ startup code" does it. 
It's what you get in a C main's argv. Populating a D main's args 
in a different way would be unusual.


Of course you can parse the command line yourself, and do it 
differently then. You can do this in C, in C++, and in D too. But 
the default is the other way, in all of them.


Re: Possible bug in std.path?

2016-06-20 Thread Hugo via Digitalmars-d

On Monday, 20 June 2016 at 10:01:25 UTC, ag0aep6g wrote:
On the other hand, the way D gets the arguments is the same as 
in C/C++. Doing it differently than that would be unusual, too.


Not necessarily, cmd.exe is made in C/C++
AFAIK, most other console applications for Windows behave the 
same way too.


Re: Possible bug in std.path?

2016-06-20 Thread ag0aep6g via Digitalmars-d

On Monday, 20 June 2016 at 02:19:22 UTC, Hugo wrote:
Perhaps I should have said unusual rather than non-standard. 
But if you want to understand better what I mean, try doing 
this in the command line, it works correctly:


cd \
mkdir test
cd test\
mkdir "..\second test\"
cd "..\second test\"


On the other hand, the way D gets the arguments is the same as in 
C/C++. Doing it differently than that would be unusual, too.


Either way, someone is going to be surprised. I would guess that 
you're in the minority here with your expectation. It's better 
then to surprise you than the majority of people who expect the 
same behavior as in C/C++ programs.


Re: Possible bug in std.path?

2016-06-20 Thread Hugo via Digitalmars-d

On Monday, 20 June 2016 at 05:44:53 UTC, Mike Parker wrote:
It shouldn't hurt to use the A variant, as Windows will do the 
necessary conversions under the hood. However, I'd love to know 
what the problem is with converting wchar* to a string type. 
This also prints an address:


auto foo = "I'm a wstring"w.ptr;
writeln(to!wstring(foo));


There was a bug report in std.conv, which was partially fixed in 
master branch (the one I used). Compiling your code with that fix 
produces the expected result. However it seems something is still 
missing.


Regarding GetCommandLineA, I could use it but I believe this 
would exclude several eastern languages, for example.


Re: Possible bug in std.path?

2016-06-19 Thread Mike Parker via Digitalmars-d

On Monday, 20 June 2016 at 05:11:12 UTC, Hugo wrote:

On Sunday, 19 June 2016 at 23:01:26 UTC, Adam D. Ruppe wrote:
One potentially simple option would be to preprocess it by 
doing a .replace(`\"`, `\\"`) then pass to CommandLineToArgvW 
to hack in the extra slash...


The problem with that approach is that replace does not work 
with wchar*. I might convert it to string, replace and then 
typecast as wchar* again because that's what CommandLineToArgvW 
expects, but when I try to convert the output to strings again, 
all I get are memory addresses instead. It seems something is 
lost during conversion or typecast.


FWIW, it seems there's some problem with print wchar* or strings 
converted from wchar*. With these lines:


auto cmdLine = GetCommandLineW();
auto str = to!string(cmdLine);
writeln(str);

Whether I use to!string or to!wstring, whether I print str or 
cmdLine, all I get are addresses. However, replacing 
GetCommandLineW with GetCommandLineA yields the correct result 
(my test is compiled as slash.exe):


Command: slash "foo\"
Output: slash  "foo\"

It shouldn't hurt to use the A variant, as Windows will do the 
necessary conversions under the hood. However, I'd love to know 
what the problem is with converting wchar* to a string type. This 
also prints an address:


auto foo = "I'm a wstring"w.ptr;
writeln(to!wstring(foo));





Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

On Sunday, 19 June 2016 at 23:01:26 UTC, Adam D. Ruppe wrote:
One potentially simple option would be to preprocess it by 
doing a .replace(`\"`, `\\"`) then pass to CommandLineToArgvW 
to hack in the extra slash...


The problem with that approach is that replace does not work with 
wchar*. I might convert it to string, replace and then typecast 
as wchar* again because that's what CommandLineToArgvW expects, 
but when I try to convert the output to strings again, all I get 
are memory addresses instead. It seems something is lost during 
conversion or typecast.


Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

On Sunday, 19 June 2016 at 23:01:26 UTC, Adam D. Ruppe wrote:

On Sunday, 19 June 2016 at 15:36:08 UTC, Hugo wrote:
I thought the proper way to call GetCommandLineW was precisely 
through CommandLineToArgvW, now I am lost.


Typically, yes, but you are saying you don't like what 
CommandLineToArgvW does (it is responsible for handling quotes 
and backslash escapes), so I'm saying you can do it some other 
way.


GetCommandLineW will give you a raw string of what the user 
typed. From there, you can treat it all as one argument or 
split it up however you like.


One potentially simple option would be to preprocess it by 
doing a .replace(`\"`, `\\"`) then pass to CommandLineToArgvW 
to hack in the extra slash... or you could do a simple little 
splitter yourself, something along the lines of:


---
bool inQuote;
size_t startIdx;
string[] args;

foreach(idx, ch; your_command_line) {
   if(ch == '"')
  inQuote = !inQuote;
   else if(ch == ' ') {
 if(!inQuote) {
args ~= to!string(your_command_line[startIdx .. idx];
startIdx = idx + 1;
 }
   }
}

if(startIdx != your_command_line.length)
  args ~= to!string(your_command_line[startIdx .. $];
---

or something along those lines, I didn't actually test that.

(btw the to!string is optional, you could just leave them as 
wstrings)



But the idea is to just split on space unless you are inside 
quotes, doing nothing special on backslashes. That'd be what 
you want (I think).


Thanks for the ideas, actually I was trying to do a function 
similar to your splitter (but still having some problems with it):


void cleanArgs(in string cmdline, ref string[] args) {
  uint argc = 0;
  bool inQuotedMode = false;
  bool lastCharIsBlank = false;
  foreach(char c; cmdline) {
if(c == '"') inQuotedMode = !inQuotedMode;
if(inQuotedMode || (!inQuotedMode && c!=' ')) args[argc] ~= c;
if(!inQuotedMode && c==' ' && !lastCharIsBlank) {
argc++;
lastCharIsBlank = true;
}
  }
}



Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

On Sunday, 19 June 2016 at 23:12:10 UTC, ag0aep6g wrote:

On 06/20/2016 12:38 AM, Hugo wrote:

What you suggest is non-standard in Windows,


I don't buy this. MSDN says about "Parsing C++ Command-Line 
Arguments" [1]:


> A double quotation mark preceded by a backslash (\") is
interpreted as a literal double quotation mark character (").


Perhaps I should have said unusual rather than non-standard. But 
if you want to understand better what I mean, try doing this in 
the command line, it works correctly:


cd \
mkdir test
cd test\
mkdir "..\second test\"
cd "..\second test\"

While it's true that you can also do this, it's not typical:

mkdir "\third test\\"
cd "\third test\\"



Re: Possible bug in std.path?

2016-06-19 Thread ag0aep6g via Digitalmars-d

On 06/20/2016 12:38 AM, Hugo wrote:

What you suggest is non-standard in Windows,


I don't buy this. MSDN says about "Parsing C++ Command-Line Arguments" [1]:

> A double quotation mark preceded by a backslash (\") is interpreted 
as a literal double quotation mark character (").


As we've seen, that's also how Windows' own CommandLineToArgvW function 
behaves. I don't see how you can consider this "non-standard", when 
Windows provides a nice function for it, while there doesn't seem to be 
one for your way, or at least it's harder to find.



[1] https://msdn.microsoft.com/en-us/library/17w5ykft.aspx


Re: Possible bug in std.path?

2016-06-19 Thread Adam D. Ruppe via Digitalmars-d

On Sunday, 19 June 2016 at 15:36:08 UTC, Hugo wrote:
I thought the proper way to call GetCommandLineW was precisely 
through CommandLineToArgvW, now I am lost.


Typically, yes, but you are saying you don't like what 
CommandLineToArgvW does (it is responsible for handling quotes 
and backslash escapes), so I'm saying you can do it some other 
way.


GetCommandLineW will give you a raw string of what the user 
typed. From there, you can treat it all as one argument or split 
it up however you like.


One potentially simple option would be to preprocess it by doing 
a .replace(`\"`, `\\"`) then pass to CommandLineToArgvW to hack 
in the extra slash... or you could do a simple little splitter 
yourself, something along the lines of:


---
bool inQuote;
size_t startIdx;
string[] args;

foreach(idx, ch; your_command_line) {
   if(ch == '"')
  inQuote = !inQuote;
   else if(ch == ' ') {
 if(!inQuote) {
args ~= to!string(your_command_line[startIdx .. idx];
startIdx = idx + 1;
 }
   }
}

if(startIdx != your_command_line.length)
  args ~= to!string(your_command_line[startIdx .. $];
---

or something along those lines, I didn't actually test that.

(btw the to!string is optional, you could just leave them as 
wstrings)



But the idea is to just split on space unless you are inside 
quotes, doing nothing special on backslashes. That'd be what you 
want (I think).


Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

On Sunday, 19 June 2016 at 17:49:55 UTC, ag0aep6g wrote:
I don't know if you can solve this with regex alone. May depend 
on what exact behavior you want. Maybe just write a little 
function instead that splits the command line, handling quotes 
and such as you want. If you're not comfortable writing this, 
then maybe you're in over your head here.


Of course, all this wouldn't be necessary if you could change 
the command line instead to conform with the usual syntax. If 
the weird behavior you're going for is just personal 
preference, and there's no actual need, I'd suggest to just 
write the command lines in the normal way with escape sequences 
(i.e. "foo\\" to get a trailing backlash instead of a trailing 
quote).


What you suggest is non-standard in Windows, and besides I might 
not be the only user of the application.


I was thinking in doing pecisely what you suggest, writing a 
little function.


I like programming little apps now and then as a hobby, but 
giving up every time I encounter a difficulty is not for me. I 
was just asking in case some of the experienced D programmer here 
could recommend an efficient and preferably simple way to do it. 
;)


Re: Possible bug in std.path?

2016-06-19 Thread ag0aep6g via Digitalmars-d

On 06/19/2016 06:21 PM, Hugo wrote:

What would be the efficient way to talke this then? I tried regex:


[...]


However it doesn't quite work will all cases (besides I fear in this
case a regexp could offer an unnecessary entry point for an exploit):


I don't know if you can solve this with regex alone. May depend on what 
exact behavior you want. Maybe just write a little function instead that 
splits the command line, handling quotes and such as you want. If you're 
not comfortable writing this, then maybe you're in over your head here.


Of course, all this wouldn't be necessary if you could change the 
command line instead to conform with the usual syntax. If the weird 
behavior you're going for is just personal preference, and there's no 
actual need, I'd suggest to just write the command lines in the normal 
way with escape sequences (i.e. "foo\\" to get a trailing backlash 
instead of a trailing quote).


Re: Possible bug in std.path?

2016-06-19 Thread ag0aep6g via Digitalmars-d

On 06/19/2016 05:36 PM, Hugo wrote:

I thought the proper way to call GetCommandLineW was precisely through
CommandLineToArgvW, now I am lost.


It may be the proper way, but you don't want the proper way then. I 
don't know if there's a Windows function for the behavior you want. If 
there isn't, you may have to implemented it yourself.


Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

On Sunday, 19 June 2016 at 14:29:27 UTC, ag0aep6g wrote:
You're calling Windows' CommandLineToArgvW here. I don't think 
that's what Adam meant by "process it yourself". If you don't 
like how CommandLineToArgvW parses the command line, don't use 
it.


What would be the efficient way to talke this then? I tried regex:

import std.stdio, std.file, std.path;
version (Windows) {
  import core.sys.windows.windows, std.conv, std.regex;
  pragma(lib, "shell32.lib");
}

enum EXIT_SUCCESS = 0;
enum EXIT_FAILURE = 1;

int main(string[] originalargs) {
  string[] args;
  version (Windows) {
SetConsoleOutputCP(65001);
static re = regex(`\s+`, "g");
auto wargs = GetCommandLineW();
if (wargs) {
  args = split(text(wargs), re);
  debug writefln("'%s'", text(wargs));
} else {
  writeln("Error getting command line arguments.");
  return EXIT_FAILURE;
}
  } else args = originalargs;
  foreach(uint i, string a; args) writefln("Argument %d: '%s'", 
i, a);

  return EXIT_SUCCESS;
}

However it doesn't quite work will all cases (besides I fear in 
this case a regexp could offer an unnecessary entry point for an 
exploit):


mytestapp dir1 ..\ "another dir\"

Argument 0: 'mytestapp'
Argument 1: 'dir1'
Argument 2: '..\'
Argument 3: '"another'
Argument 4: 'dir\"'



Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

On Sunday, 19 June 2016 at 14:29:27 UTC, ag0aep6g wrote:

[...]
 auto wargs = CommandLineToArgvW(GetCommandLineW(), 
&wargc);


You're calling Windows' CommandLineToArgvW here. I don't think 
that's what Adam meant by "process it yourself". If you don't 
like how CommandLineToArgvW parses the command line, don't use 
it.


I thought the proper way to call GetCommandLineW was precisely 
through CommandLineToArgvW, now I am lost.


Re: Possible bug in std.path?

2016-06-19 Thread ag0aep6g via Digitalmars-d

On 06/19/2016 02:23 PM, Hugo wrote:

On Friday, 20 May 2016 at 17:41:22 UTC, Adam D. Ruppe wrote:

[...]

Use GetCommandLine to fetch the original thing the user typed, then
process it yourself.

[...]


Then why doesn't the following code produce the expected output?


[...]

 auto wargs = CommandLineToArgvW(GetCommandLineW(), &wargc);


You're calling Windows' CommandLineToArgvW here. I don't think that's 
what Adam meant by "process it yourself". If you don't like how 
CommandLineToArgvW parses the command line, don't use it.


Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

Further, notice what happens if I remove the buildNormalizedPath:

mytestapp dir1 ..\ "another dir\"

Argument 0: 'mytestapp '
Argument 1: 'dir'
Argument 2: '..\'
Argument 3: 'another dir"'

Apparently the backslash is still being interpreted as an escape 
when followed by a double quote, even if the arguments come from 
GetCommandLineW.


Re: Possible bug in std.path?

2016-06-19 Thread Hugo via Digitalmars-d

On Friday, 20 May 2016 at 17:41:22 UTC, Adam D. Ruppe wrote:

[...]

Use GetCommandLine to fetch the original thing the user typed, 
then process it yourself.


[...]


Then why doesn't the following code produce the expected output?

import std.stdio, std.file, std.path;
version (Windows) {
  import core.sys.windows.windows, std.conv;
  pragma(lib, "shell32.lib");
}

enum EXIT_SUCCESS = 0;
enum EXIT_FAILURE = 1;

int main(string[] originalargs) {
  string[] args;
  version (Windows) {
SetConsoleOutputCP(65001);
int wargc;
auto wargs = CommandLineToArgvW(GetCommandLineW(), &wargc);
if (wargs) {
  for(uint i; i < wargc; i++) args ~= 
buildNormalizedPath(text(wargs[i]));

} else {
  writeln("Error getting command line arguments.");
  return EXIT_FAILURE;
}
  } else args = originalargs;
  foreach(uint i, string a; args) writefln("Argument %d: '%s'", 
i, a);

  return EXIT_SUCCESS;
}

Test from Windows:
mytestapp dir1 dir2 "..\my parent dir\"
(all valid arguments)

Output:
Argument 0: 'mytestapp'
Argument 1: 'dir1'
Argument 2: 'dir2'
Argument 3: '..\my parent dir"'

Notice: I had to use std.conv from master branch because 
otherwise text() wouldn't dereference wargs (of type wchar**).


PS. Please forgive me the delay.


Re: Possible bug in std.path?

2016-05-21 Thread Hugo via Digitalmars-d

On Friday, 20 May 2016 at 17:41:22 UTC, Adam D. Ruppe wrote:

On Friday, 20 May 2016 at 15:18:39 UTC, Hugo wrote:
On the other hand, regular console commands and many console 
applications for Windows work as expected, so there must be a 
way to deal with this properly


It is pretty easy to handle, but must happen at a higher level 
than buildNormalizedPath.


Use GetCommandLine to fetch the original thing the user typed, 
then process it yourself.


https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156%28v=vs.85%29.aspx

But buildNormalizedPath cannot do this itself because its 
argument doesn't necessarily come from the command line.


Your main() function could use it to get the string you pass to 
the other functions though. That's probably what most the 
Windows built in things do when they need to.


Thank you all.


Re: Possible bug in std.path?

2016-05-20 Thread Adam D. Ruppe via Digitalmars-d

On Friday, 20 May 2016 at 15:18:39 UTC, Hugo wrote:
On the other hand, regular console commands and many console 
applications for Windows work as expected, so there must be a 
way to deal with this properly


It is pretty easy to handle, but must happen at a higher level 
than buildNormalizedPath.


Use GetCommandLine to fetch the original thing the user typed, 
then process it yourself.


https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156%28v=vs.85%29.aspx

But buildNormalizedPath cannot do this itself because its 
argument doesn't necessarily come from the command line.


Your main() function could use it to get the string you pass to 
the other functions though. That's probably what most the Windows 
built in things do when they need to.


Re: Possible bug in std.path?

2016-05-20 Thread Hugo via Digitalmars-d

On Friday, 20 May 2016 at 03:40:23 UTC, Walter Bright wrote:

On 5/19/2016 6:35 PM, Hugo wrote:

I assumed the
function would deal with the trailing backslash.


And it can. It just never received a trailing backslash because 
that was removed by the Windows argument processing.


Yes, I can see the problem.

On the other hand, regular console commands and many console 
applications for Windows work as expected, so there must be a way 
to deal with this properly, and IMHO this would be usefull in 
buildNormalizedPath, instead of leaving the programmer the task 
to find a (perhaps sub-optimal) woraround.




Re: Possible bug in std.path?

2016-05-20 Thread Kagamin via Digitalmars-d
On Thursday, 19 May 2016 at 19:40:16 UTC, Vladimir Panteleev 
wrote:
The fact that some standard Windows utilities do not obey this 
convention is more likely a historical artifact from DOS days.


Escaping makes sense for free text arguments, but not for path 
arguments, hence funny heuristics. That said one can use forward 
slashes as folder separators on windows.


Re: Possible bug in std.path?

2016-05-19 Thread Walter Bright via Digitalmars-d

On 5/19/2016 6:35 PM, Hugo wrote:

I assumed the
function would deal with the trailing backslash.


And it can. It just never received a trailing backslash because that was removed 
by the Windows argument processing.




Re: Possible bug in std.path?

2016-05-19 Thread Hugo via Digitalmars-d

On Thursday, 19 May 2016 at 22:44:06 UTC, Walter Bright wrote:

On 5/19/2016 3:41 PM, Adam D. Ruppe wrote:
So indeed, the OP stumbled upon a weird case of Windows 
command line, but it is

really just this one weird case.


It's not at all weird. It's just garden variety double quoted 
string behavior. Linux has its own quoting scheme on the 
command line, too.


I must confess I was a bit misled then by this portion of the 
unittest:


assert (buildNormalizedPath(`c:\foo\.\bar/..\\baz\`) == 
`c:\foo\baz`);


Since I saw somewhere D could use different quoting styles, I 
assumed the function would deal with the trailing backslash.


Re: Possible bug in std.path?

2016-05-19 Thread Walter Bright via Digitalmars-d

On 5/19/2016 3:41 PM, Adam D. Ruppe wrote:

So indeed, the OP stumbled upon a weird case of Windows command line, but it is
really just this one weird case.


It's not at all weird. It's just garden variety double quoted string behavior. 
Linux has its own quoting scheme on the command line, too.


Re: Possible bug in std.path?

2016-05-19 Thread Adam D. Ruppe via Digitalmars-d

On Thursday, 19 May 2016 at 22:13:36 UTC, Walter Bright wrote:

Windows command line processing has special handling for " and 
\. The \ is used to escape the next character, which here is a 
". You can see the resulting argument is [my test"]. Note the 
quote.


Not exactly... it treats \" as a special case, not \ in general.

https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391%28v=vs.85%29.aspx

Quote:

CommandLineToArgvW has a special interpretation of backslash 
characters when they are followed by a quotation mark character 
("), as follows:


2n backslashes followed by a quotation mark produce n 
backslashes followed by a quotation mark.
(2n) + 1 backslashes followed by a quotation mark again 
produce n backslashes followed by a quotation mark.
n backslashes not followed by a quotation mark simply produce 
n backslashes.




So indeed, the OP stumbled upon a weird case of Windows command 
line, but it is really just this one weird case.


Re: Possible bug in std.path?

2016-05-19 Thread Walter Bright via Digitalmars-d

On 5/18/2016 8:49 PM, Hugo wrote:

mytest "my dir\"

I should get "OK", but instead I get:
Error: 'my test"' is not a valid directory path.


Windows command line processing has special handling for " and \. The \ is used 
to escape the next character, which here is a ". You can see the resulting 
argument is [my test"]. Note the quote.




If the trailing backslash is removed it works as intended, but IMHO
buildNormalizedPath should have worked.


buildNormalizedPath is passed [my test"]. It cannot possibly do as you suggest.



In any case, notice the double quote in the output. To me this suggests the
backslash is acting not as a path terminator but as an escape sequence.


This is happening because of how standard Windows programs deal with " and
\ on the command line.


Re: Possible bug in std.path?

2016-05-19 Thread Vladimir Panteleev via Digitalmars-d

On Thursday, 19 May 2016 at 15:25:02 UTC, Kagamin wrote:
On Thursday, 19 May 2016 at 14:53:21 UTC, Steven Schveighoffer 
wrote:
Then complain to Microsoft :) This is Microsoft's command 
shell sending that parameter to your program.


This is how CommandLineToArgvW behaves, which is called by 
druntime to parse the command line. For example, xcopy parses 
the command line correctly, e.g. this works as expected:

xcopy file "..\"


As far as I know, CommandLineToArgvW is *the* correct way to 
parse command-line arguments on Windows. If you do not use it, 
then your program will not work correctly when invoked by other 
programs which assume you use it, and this includes most programs 
which use libraries that accept program arguments as an array 
(which is the correct abstraction for program arguments anyway).


The fact that some standard Windows utilities do not obey this 
convention is more likely a historical artifact from DOS days.




Re: Possible bug in std.path?

2016-05-19 Thread Kagamin via Digitalmars-d
On Thursday, 19 May 2016 at 16:02:27 UTC, Steven Schveighoffer 
wrote:
The reason for this (as spelled out in the comments) is to get 
around the poor handling of utf8 by Windows.


One receives unicode arguments by declaring wmain function. 
AFAIK, mingw and msvc do it fine, not sure about dmc.


Re: Possible bug in std.path?

2016-05-19 Thread Steven Schveighoffer via Digitalmars-d

On 5/19/16 12:02 PM, Steven Schveighoffer wrote:

On 5/19/16 11:25 AM, Kagamin wrote:

On Thursday, 19 May 2016 at 14:53:21 UTC, Steven Schveighoffer wrote:

Then complain to Microsoft :) This is Microsoft's command shell
sending that parameter to your program.


This is how CommandLineToArgvW behaves, which is called by druntime to
parse the command line. For example, xcopy parses the command line
correctly, e.g. this works as expected:
xcopy file "..\"


Thanks for correcting, this is a difference from posix that I forgot about.

The reason for this (as spelled out in the comments) is to get around
the poor handling of utf8 by Windows.

I think if you write a C program in Windows, your argv/argc will contain
.."

You'd have to do the same acrobatics D does to get the original, so I
don't think this is a problem that we need to solve. Use those low-level
functions if you wish.


For reference to OP, here is the code that accesses original command 
line, which you can model for your desired behavior:


https://github.com/dlang/druntime/blob/master/src/rt/dmain2.d#L356

-Steve


Re: Possible bug in std.path?

2016-05-19 Thread Steven Schveighoffer via Digitalmars-d

On 5/19/16 11:25 AM, Kagamin wrote:

On Thursday, 19 May 2016 at 14:53:21 UTC, Steven Schveighoffer wrote:

Then complain to Microsoft :) This is Microsoft's command shell
sending that parameter to your program.


This is how CommandLineToArgvW behaves, which is called by druntime to
parse the command line. For example, xcopy parses the command line
correctly, e.g. this works as expected:
xcopy file "..\"


Thanks for correcting, this is a difference from posix that I forgot about.

The reason for this (as spelled out in the comments) is to get around 
the poor handling of utf8 by Windows.


I think if you write a C program in Windows, your argv/argc will contain .."

You'd have to do the same acrobatics D does to get the original, so I 
don't think this is a problem that we need to solve. Use those low-level 
functions if you wish.


-Steve


Re: Possible bug in std.path?

2016-05-19 Thread Kagamin via Digitalmars-d
On Thursday, 19 May 2016 at 14:53:21 UTC, Steven Schveighoffer 
wrote:
Then complain to Microsoft :) This is Microsoft's command shell 
sending that parameter to your program.


This is how CommandLineToArgvW behaves, which is called by 
druntime to parse the command line. For example, xcopy parses the 
command line correctly, e.g. this works as expected:

xcopy file "..\"


Re: Possible bug in std.path?

2016-05-19 Thread Steven Schveighoffer via Digitalmars-d

On 5/19/16 9:49 AM, Hugo wrote:

On Thursday, 19 May 2016 at 05:06:44 UTC, Vladimir Panteleev wrote:

Here you can see the final string value of the program argument in
your program.

The correct invocation is: mytest "my dir\\"


What you suggest is non-standard in Windows, and would require
distributing the application with some form of comment saying you have
to use double backslashes, which is unprofessional. Software should
serve the user and not the other way round.


Then complain to Microsoft :) This is Microsoft's command shell sending 
that parameter to your program.



Notice I am not debating the escape character, but the inconsistency of
buildNormalizedPath, which IMHO should have worked and fixed the
trailing backslash.


buildNormalizedPath is being send the string `my dir"`, what is it 
supposed to do with that?


-Steve


Re: Possible bug in std.path?

2016-05-19 Thread Hugo via Digitalmars-d
On Thursday, 19 May 2016 at 05:06:44 UTC, Vladimir Panteleev 
wrote:
Here you can see the final string value of the program argument 
in your program.


The correct invocation is: mytest "my dir\\"


What you suggest is non-standard in Windows, and would require 
distributing the application with some form of comment saying you 
have to use double backslashes, which is unprofessional. Software 
should serve the user and not the other way round.


Notice I am not debating the escape character, but the 
inconsistency of buildNormalizedPath, which IMHO should have 
worked and fixed the trailing backslash.



In the future, consider posting to the learn group.


I did not post there because I thought this was not necessarily a 
newbie question. My apologies.


Re: Possible bug in std.path?

2016-05-18 Thread Vladimir Panteleev via Digitalmars-d

On Thursday, 19 May 2016 at 03:49:36 UTC, Hugo wrote:


mytest "my dir\"


Here, your backslash is used to escape the second " character.


Error: 'my test"' is not a valid directory path.


Here you can see the final string value of the program argument 
in your program.


The correct invocation is: mytest "my dir\\"

In the future, consider posting to the learn group.


Possible bug in std.path?

2016-05-18 Thread Hugo via Digitalmars-d

I am having a problem on Windows with the following code:

module mytest;

import std.stdio, std.file, std.path;

enum EXIT_SUCCESS = 0;
enum EXIT_FAILURE = -1;

int main(string[] args) {
  string appdir;
  switch(args.length-1) {
case 0:
  writeln("You must provide an argument with a valid 
directory path.");

  break;
case 1:
  appdir = buildNormalizedPath(args[1]);
  if(appdir.exists && appdir.isDir) break;
default:
  writefln("Error: '%s' is not a valid directory path.", 
appdir);

  return EXIT_FAILURE;
  }
  writeln("OK");
  return EXIT_SUCCESS;
}

Suppose I compiled this unit on current dir and then executed 
these commands:


mkdir "my dir"
mytest "my dir\"

I should get "OK", but instead I get:
Error: 'my test"' is not a valid directory path.

If the trailing backslash is removed it works as intended, but 
IMHO buildNormalizedPath should have worked.


In any case, notice the double quote in the output. To me this 
suggests the backslash is acting not as a path terminator but as 
an escape sequence.