Print an NSArray in LLDB - lldb

What's your favorite way to print the contents of an NSArray using LLDB?
A python script?
An inline for loop?
An Objective-C method call?
I know it's easy to print an object by index. I want to print all objects at once.

The description method on NSArray iterates through the objects in the array and does a description on them. No need to invent anything:
po [fooArray description]

What version of Xcode/LLDB are you using?
In the 4.6 release which just went out, you should be able to just expand the NSArray in Xcode and have the contents displayed.
At the command line, doing
frame variable myArray --show-types -d run --ptr-depth 1
should also work.

Related

how to get the file extension in pike

I'm working on a program in pike and looking for a method like the endswith() in python- a method that gives me the extension of a given file.
Can someone help me with that?
thank you
Python's endswith() is something like Pike's has_suffix(string s, string suffix):
has_suffix("index.html", ".html");
Reference:
http://pike.lysator.liu.se/generated/manual/modref/ex/predef_3A_3A/has_suffix.html
extract the end of the string, and compare it with the desired extension:
"hello.html"[<4..] == ".html"
(<4 counts from the end of the string/array)
If you want to see what the extension of a file is, just find the last dot and get the substring after it, e.g. (str/".")[-1]
If you just want to check if the file is of a certain extension, using has_suffix() is a good way, e.g. has_suffix(str, ".html")

Passing an array as an argument from a Perl script to a R script

I am new to R and I have a Perl Script in which I want to call a R Script, which calculates something for me (not important what in this context). I want to give as arguments an input file, an array which contains some numbers and a number for a total number of clusters. medoid.r is the name of my R Script.
my $R_out;
$R_out = qx{./script/medoid.r $output #cluster $NUMBER_OF_CLUSTERS}
My current R code looks like this. Right now I just print cluster to see what is inside.
args <- commandArgs(TRUE)
filename = args[1]
cluster = as.vector(args[2])
number_of_cluster = args[3]
matrix = read.table(filename, sep='\t', header=TRUE, row.names=1, quote="")
print(cluster)
Is it possible to give an array as an argument? How can I save it in R? Right now only the first number of the array is stored and printed, but I would like to have every number in a vector or something similar.
If you do this in Perl
$R_out = qx{./script/medoid.r $output #cluster $NUMBER_OF_CLUSTERS};
your command line will look similar to this
./scriptmedoid.r output 111 222 333 3
assuming that $output is 'output' and #clusters = (111, 222, 333).
If you want to read that in R, you need to assign all elements after the first one in args to cluster but the last one, and the last one to number_of_cluster. In Perl you can use shift and pop for that.
my #args = #_;
my $output = shift #args;
my $number = pop #args;
# now #args only contains the clusters
I don't know if those operators exist in R.
You cannot pass a full data structure unless you serialize it in some way.
In perl, qx will expect a string as an argument. You may certainly use an array to generate that string, but ultimately it will still be a string. You cannot "pass an array" to a system call, you can only pass command-line text/arguments.
Keep in mind, you are executing a system call running Rscript as a child process. The way you're describing the issue, there is no inter-process communication beyond the command line. Think of it this way: how would you type an array on the command line? You may have some textual way of representing an array, but you can't type an array on the command line. Arrays are stored and accessed in memory differently by various different languages, and thus are not really portable between two languages like you're suggesting.
One solution: all that said, there may be a simple solution for you. You haven't provided any information on the type of data you want to pass in your array. If it is simple enough, you may try passing it on the command line as delimited text, and then break it up to use in your Rscript.
Here is an Rscript that shows you what I mean:
args = commandArgs(trailingOnly=TRUE)
filename = args[1]
cluster <- c(strsplit(args[2],"~"))
sprintf("Filename: %s",filename)
sprintf("Cluster list: %s",cluster)
print("Cluster:")
cluster
sprintf("First Item: %s",cluster[[1]][1])
Save it as "test.r" and try executing it with "Rscript test.r test.txt one~two" and you'll get the following output (tested on Rscript 46084, OpenBSD):
[1] "Filename: test.txt"
[1] "Cluster list: c(\"one\", \"two\")"
[1] "Cluster:"
[[1]]
[1] "one" "two"
[1] "First Item: one"
So, all you'd have to do on the perl side of things is join() your array using "~" or any other delimiter- it is highly dependent on your data, and you haven't provided it.
Summary: re-think how you want to communicate between perl and Rscript. Consider sending the data as a delimited string (if it's the right size) and breaking it up on the other side. Look into IPC if that won't work, consider environment variables or other options. There is no way to send an array reference on the command-line.
Note: you may want to read up on security risks of different system calls in perl.

How to use function `write-region`?

I try to make a new file, according to this question and answer: How to create an empty file by elisp?
I copied the code
(write-region "" nil custom-file)
into a new emacs file and wanted to execute it by C-x C-e. But all i get is
Wrong type argument: stringp, nil
So what am i doing wrong here ? Im pretty new to emacs and have tried finding a solution by googling it but had no success.
Sounds like the value of custom-file is nil. It should be a string (that names a file).
If you set variable debug-on-error to t then you'll get a backtrace that will show you which arg that was expected as a string is actually nil.
Try wrapping your (relative) file name in expand-file-name, like this:
(write-region "" nil (expand-file-name "new_file"))
Now it should create the file in the current default-directory.
It also makes a difference where your cursor is, when executing C-x C-e. Put it at the end of the document.

How do you extract data from gdb

How do you extract data from gdb so you can examine it in another program?
I am using gdb to debug a program. To see what is in array udata, I have created a source file called printudata with the following contents:
print udata[0]
print udata[1]
print udata[2]
...
print udata[143]
From within gdb I can execute that using source command and get output like this:
(gdb) source printudata
$399 = 1
$400 = 2.5
$401 = .3-10
...
$542 = <number>
So far, that is the best I can do for examining memory.
The only thing I can think of to do with this is (learn regular expressions and) strip off everything up to the equal sign so I can paste this into a spreadsheet which will tell me whether it's correct.
Is this the really the best way to get output from gdb? I am learning all this on my own and only have the basic, free tools that come with Linux (and am a beginner with all the above listed technologies)
You can print an array if it is really an array like this:
p udata
But, if udata is really a pointer, then you can use a cast to make gdb print it like an array.
p *(double(*)[144])udata
If you really want the line at a time output of your current "script", you can define a function and use a loop:
define print_udata
set $i=0
while ($i < 144)
p udata[$i]
set $i=$i+1
end
end
To log the output to a file, you can enable/disable logging:
set logging on
...gdb commands...
set logging off
The output will be in a file called gdb.txt.
In addition to the above, gdb has the "output" and "printf" commands. These don't enter the value into the value history, and they let you control the output much more precisely.
gdb has built-in scripting in both its own scripting language and in python. You can even script GDB from within a python program. You can use any of those options to write the data to a file.
More information about python & gdb here.

File pointers in an array

Very raw with C. I'm writing a program that takes files as it's arguments, but this is rather annoying for debugging (GDB). Rather than have to re-type the file list each time that I start off in GDB, I'd rather store the file names in an array and modify the program to read this array rather than the argv[] values.
I started out with
FILE*[5] inpFiles;
inpFiles[0] = &file1.txt;
but this is all wrong. I need to get some sort of reference to each of the input files so that I can get its memory address.
How can I do this? Thanks.
You can define a GDB command in .gdbinit so you don't need to modify your production code.
For example, add the following lines in your ~/.gdbinit or .gdbinit in your working directory.
define do
run file1.txt file2.txt file3.txt file4.txt file5.txt
end
Then, in GDB, just type the command do, and GDB runs run file1.txt file2.txt file3.txt file4.txt file5.txt for you.
You can parse your input files, containing each of your files, by reading on the standard file stream 0.
so that you could do this:
./your_program < your_input_file
and in gdb,
run/r < your_input_file
but if you want to keep your args method, you can also do this:
./your_program `cat your_input_file`
Hope this helps.
An array of FILE * would be written:
FILE *inpFiles[5];
This can store the values returned from fopen() or a similar functions; it does not store file names.
You might store the file pointer into the structure that &file1 represents, or you might create a new structure that stores the name and the opened file pointer (though you may need to specify a mode; presumably "r" or "rb" by default).
So, clarify to yourself what exactly you want to do. You can create an array of file pointers, or an array of structures containing, amongst other things, a file pointer. But you have to decide how you're going to use it and what the semantics are going to be.
This presumes that modifying the program is a better idea than using GDB better. If you can learn to use the facilities of GDB more powerfully, then that's a better idea.
For example, can you make it easy to specify the files by using a metacharacter:
run debug?.txt
where your files are debug0.txt, debug1.txt, ...?
The other answers also suggest alternatives.

Resources