Sublime build exec command array - sublimetext2

I am confused as to why Sublime Text 2 build systems tend to put the exec command as an array. Though this is suggested in the docs (and works), just putting the command as a string works just as well, and is (in my opinion) more straightforward.

The Sublime Text build system uses subprocess.Popen, which recommends the usage of an array. Otherwise the interpretation is platform-dependent.
Cited from the python 2 subprocess documentation:
args should be a sequence of program arguments or else a single string. By default, the program to execute is the first item in args if args is a sequence. If args is a string, the interpretation is platform-dependent (...). Unless otherwise stated, it is recommended to pass args as a sequence.
Additional important cite (thanks #Dimpl for pointing that out):
The shell argument (which defaults to False) specifies whether to use the shell as the program to execute. If shell is True, it is recommended to pass args as a string rather than as a sequence.
The shell argument is set True if you use the shell_cmd and False for cmd. Hence based on the cites I would suggest to use an array for cmd and a string for shell_cmd.

Related

Variable substitution in TCL inside curly brace

I am trying to perform a variable substitution within curly braces which I understand is not feasible directly in TCL.
The code I am trying:
interface code -clip {$x1 $y1 $x2 $y2}
The interface code is a third party TCL function that has an option called clip which reads x1,y1,x2,y2 coordinates within curly braces.
I need to feed in the values of x1,y2 within the curly braces.
In Tcl, the {…} syntax technically means “do no substitutions at all on this”. The command that the value gets passed to might do its own thing with those characters, and those things might look a lot like substitution (e.g., if it is evaluating the word as a script, which is what if and for and while and … do), but Tcl's core syntax just leaves them alone and passes them through.
To get what you want, there's a few alternatives. You can do the substitutions before passing the value in — the command literally can't see that you've done this if you choose to do it — or you can get the command to do the substitutions (not a useful suggestion if it's third-party code, of course).
To do the substitutions yourself, you might do one of these:
interface code -clip [list $x1 $y1 $x2 $y2]
interface code -clip "$x1 $y1 $x2 $y2"
interface code -clip [subst {$x1 $y1 $x2 $y2}]
The first option is good if the command takes a list (which your case looks like; it appears to be a coordinate list). The second option is good if the command takes a string. The third option is good when things are getting complicated! It's usually a good idea to try to avoid very complicated stuff; programs are difficult enough to write and read without deliberately making them even harder to understand.

Tcl: Is parameter evaluation guaranteed to be left-to-right?

I have a Tcl program where I often find expressions of the following kind:
proc func {} {...}
...
lappend arr([set v [func]]) $v
The intended meaning of the last line is
set v [func]
lappend arr($v) $v
It obviously works. What I would like to know: Does it work "by accident", or does Tcl guarantee, that the first parameter passed to lappend is evaluated before the second?
Tcl is always evaluated from left to right as you can read on the documentation, I quote the part:
Substitutions take place from left to right, and each substitution is evaluated completely before attempting to evaluate the next. Thus, a sequence like:
set y [set x 0][incr x][incr x]
will always set the variable y to the value, 012.
Agreed with Jerry. Adding some flavor in it.
Tcl commands are evaluated in two steps : parsing & execution.
First the Tcl interpreter parses the command string into words, performing substitutions along the way.
Then a command procedure processes the words to produce a result string. Each command has a separate command procedure.
Let us consider the following code.
%set input "The cat in the hat"
The cat in the hat
%string match "*at in*" $input
1
In the parsing step the Tcl interpreter applies the rules described in this chapter to divide the command up into words and perform substitutions.
Parsing is done in exactly the same way for every command. During the parsing step the Tcl interpreter does not apply any meaning to the values of the words. Tcl just performs a set of simple string operations such as replacing the characters $a with the string stored in variable a. Tcl does not know or care whether a or the resulting word is a number or the name of a widget or anything else.
In the execution step meaning is applied to the words of the command. Tcl treats the first word as a command name, checking to see if the command is defined and locating a command procedure to carry out its function. If the command is defined then the Tcl interpreter invokes its command procedure, passing all of the words of the command to the command procedure. The command procedure is free to interpret the words in any way that it pleases, and different commands apply very different meanings to their arguments.
Major rule to remember here
Tcl parses a command and makes substitutions in a single pass from left to right. Each character is scanned exactly once.
At most a single layer of substitution occurs for each character; the result of one substitution is not scanned for further
substitutions.
Reference : Tcl and the Tk Toolkit

Converting Tcl to C++

I am trying to convert some tcl script into a C++ program. I don't have much experience with tcl and am hoping someone could explain what some of the following things are actually doing in the tcl script:
1) set rtn [true_test_sfm $run_dir]
2) cd [glob $run_dir]
3) set pwd [pwd]
Is the first one just checking if true_test_sfm directory exists in run_dir?
Also, I am programming on a windows machine. Would the system function be the equivalent to exec statements in tcl? And if so how would I print the result of the system function call to stdout?
In Tcl, square brackets indicate "evaluate the code between the square brackets". The result of that evaluation is substituted for the entire square-bracketed expression. So, the first line invokes the function true_test_sfm with a single argument $run_dir; the result of that function call is then assigned to the variable rtn. Unfortunately, true_test_sfm is not a built-in Tcl function, which means it's user-defined, which means there's no way we can tell you what the effect of that function call will be based on the information you've provided here.
glob is a built-in Tcl function which takes a file pattern as an argument and then lists files that match that pattern. For example, if a directory contains files "foo", "bar" and "baz", glob b* would return a list of two files, "bar" and "baz". Therefore the second line is looking for any files that match the pattern given by $run_dir, then using the cd command (another Tcl built-in) to change to the directory found by glob. Probably $run_dir is not actually a file pattern, but an explicit file name (ie, no globbing characters like * or ? in the string), otherwise this code may break unexpectedly. On Windows, some combination of FindFirstFile/FindNextFile in C++ could be used as a substitute for glob in Tcl, and SetCurrentDirectory could substitute for cd.
pwd is another built-in Tcl function which returns the process current working directory as an absolute path. So the last line is querying the current working directory and saving the result in a variable named pwd. Here you could use GetCurrentDirectory as a substitute for pwd.

Break on namespace function in gdb (llvm)

I'm trying to step through llvm's opt program (for an assignment) and the instructor suggested setting a breakpoint at runOnFunction. I see this in one of the files:
bool InstCombiner::runOnFunction(Function &F) { /* (Code removed for SO) */ }
but gdb does not seem to find the runOnFunction breakpoint. It occurred to me that the problem might be namespaces? I tried this but gdb never breaks, it just creates the fooOpt.s file:
(gdb) b runOnFunction
Function "runOnFunction" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (runOnFunction) pending.
(gdb) r -S -instcombine -debug -o ~/Desktop/fooOpt.s ~/Desktop/foo.s
I'm on a Mac so I don't have objdump but otool produces 5.6 million lines, wading through that for a starting point does not seem reasonable as runOnFunction appears more than once there.
Gdb has several builtin commands to find name of such functions. First is info functions, which can be used with optional regexp argument to grep all available functions, https://sourceware.org/gdb/current/onlinedocs/gdb/Symbols.html
info functions regexp
Print the names and data types of all defined functions whose names contain a match for regular expression regexp. Thus, ‘info fun step’ finds all functions whose names include step; ‘info fun ^step’ finds those whose names start with step. If a function name contains characters that conflict with the regular expression language (e.g. ‘operator*()’), they may be quoted with a backslash.
So, you can try info functions runOnFunction to get the name. Sometimes it can be useful to add quotes around name when doing break command.
The other way is to use rbreak command instead of break (b). rbreak will do regexp search in functions names and may define several breakpoints: https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Breaks.html#Set-Breaks
rbreak regex
Set breakpoints on all functions matching the regular expression regex. This command sets an unconditional breakpoint on all matches, printing a list of all breakpoints it set. ...
The syntax of the regular expression is the standard one used with tools like grep. Note that this is different from the syntax used by shells, so for instance foo* matches all functions that include an fo followed by zero or more os. There is an implicit .* leading and trailing the regular expression you supply, so to match only functions that begin with foo, use ^foo.
(or even rbreak file:regex to limit search to single source file)
PS: if you want, you can turn on or off C++ function name demangling with set print demangle on or off (https://sourceware.org/gdb/current/onlinedocs/gdb/Debugging-C-Plus-Plus.html#Debugging-C-Plus-Plus). With demangling turned off it will be easier to copy function name to break command.

How to keep commands quiet in TCL?

How to execute set command without printing output on the screen? I want to read a file without displaying the contents on the screen.
set a [open "giri.txt" r]
set b [read $ifile]
What you're observing is just the standard behaviour of an interactive Tcl shell: each Tcl command returns a result value, and a return code. If the Tcl shell is interactive (that is, its input and output streams are connected to a terminal), after executing each command, the string representation of the result value the command returned is printed, and then the prompt is shown again. If the shell is not interactive, no results are printed and no prompt is shown.
(On a side note, such behaviour is ubiquitous with interpreters — various Unix shells, Python and Ruby interpreters do the same thing.)
If you want to inhibit such printouts in an interactive session (comes in handy from time to time), a simple hack to achieve that is to chain the command you want to "silence" with a "silent" command (producing a value whose string representation is an empty string), for instance:
set a [open "giri.txt" r]; list
Here, the list returned by the list command having no arguments is an empty list whose string representation is an empty string. In an interactive shell, this chain of commands will output literally nothing.
It bears repeating that such a hack might only ever be needed in an interactive session — do not use it in scripts.
In Mentor ModelSim Tcl it is possible to do:
quietly set answer 42
Also in Mentor Questa:
help quietly
The quietly command turns off transcript echoing for the specified command.
You can turn this off in an interactive tclsh
set tcl_interactive false
but that will also turn off the prompt.