views:

334

answers:

3

I'm using a crude IDE (Microchip MPLAB) with C30 toolchain on Windows XP. The C compiler has a very noisy output that I'm unable to control, and it's very hard to spot actual warnings and errors in output window.

I want to write a python script that would receive arguments for compiler, call the compiler with same arguments, filter results and output them to stdout. Then I can replace the compiler executable with my script in toolchain settings. The IDE calls my script and receives filtered compiler output.

My code for executing the compiler looks like this:

arguments = ' '.join(sys.argv[1:])
cmd = '%s %s' % (compiler_path, arguments)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

The problem is that quotes from arguments are consumed on script execution, so if IDE calls my script with following arguments:

main.c -o"main.o"

the value of arguments is

main.c -omain.o

The most obvious solution is to put whole argument list in quotes, but this would require modification in compiler calling code in IDE. I also tried using batch file, but it can only accept nine parameters (%1 to %9), and compiler is called with 15+ parameters.

Is there a way to forward exactly the same arguments to a process from script?

A: 

Your shell is eating the quotes (the python script never even receives them) so I suppose it's not very easy to get them 'unaltered'.

ChristopheD
If the shell is eating them when Python is called, this isn't a problem. It should also be eating them when using the same args for the compiler alone. So using sys.argv would give you the same result.I do recommend passing the args as a list to Popen, rather than a single string. With the former, you control exactly what each argument to the command is, without having to worry about escaping. (What if any of your commands have spaces?)
AFoglia
Very true remark. Well, i'll leave this answer for completeness sake (and because of the informative comment).
ChristopheD
I'm not certain this answer is even correct. The fact that the asker mentions writing a "batch script" may indicate that he is using Windows — in which case the shell does NOT eat quotation marks; they get passed verbatim for the executable's runtime to process. Which raises a different question: does Python provide any way to look "behind" the "sys.argv" that's artificially constructed by the Windows C runtime, and see the real, verbatim command line that was actually passed to the newly spawned process?
Brandon Craig Rhodes
+2  A: 

As ChristopheD said the shell removes the quotes.

But you don't need to create the string yourself when using Popen: it can handle that for you automatically. You can do this instead:

import sys, subprocess
process = subprocess.Popen(sys.argv[1:], executable=compiler_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

The subprocess module hopefully will pass the arguments correctly for you.

Mark Byers
"The 'executable' argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the 'args' argument." http://docs.python.org/library/subprocess.html
hcs42
+4  A: 

Give the command arguments to Popen as a list:

arguments = sys.argv[1:]
cmd = [compiler_path] + arguments
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
hcs42