I'm willing to use an interactive language to test some C code from a legacy project. I know a little Forth, but I haven't ever used it in a real world project. I'm looking at pForth right now.
Is it reasonable to use an interactive Forth interpreter to test the behavior of some function in a C program? This C code has lots of structs, pointers to structs, handles and other common structures found in C.
I suppose I'll have to write some glue code to handle the parameter passing and maybe some struct allocation in the Forth side. I want an estimate from someone with experience in this field. Is it worth it?
If you want interactive testing and are targeting embedded platforms, then Forth is definitely a good candidate. You'll always find a Forth implementation that runs on your target platform. Writing one is not even hard either if need be.
Instead of writing glue code specific to your immediate needs, go for a generic purpose Forth to C interface. I use gforth's generic C interface which is very easy to use. For structure handling in Forth, I use an MPE style implementation which is very flexible when it comes to interfacing with C (watch out for proper alignment though, see gforth %align / %allot / nalign).
The definition of generic purpose structure handling words takes about 20 lines of Forth code, same for single linked lists handling or hash tables.
Since you cannot use gforth (POSIX only), write an extension module for your Forth of choice that implements a similar C interface. Just make sure that your Forth and your C interface module uses the same malloc() and free() than the C code you want to test.
With such an interface, you can do everything in Forth by just defining stub words (i.e. map Forth words to C functions and structures).
Here's a sample test session where I call libc's gettimeofday using gforth's C interface.
s" structs.fs" included also structs \ load structure handling code
clear-libs
s" libc" add-lib \ load libc.so. Not really needed for this particular library
c-library libc \ stubs for C functions
\c #include <sys/time.h>
c-function gettimeofday gettimeofday a a -- n ( struct timeval *, struct timezone * -- int )
end-c-library
struct timeval \ stub for struct timeval
8 field: ->tv_sec \ sizeof(time_t) == 8 bytes on my 64bits system
8 field: ->tv_usec
end-struct
timeval buffer: tv
\ now call it (the 0 is for passing NULL for struct timezone *)
tv 0 gettimeofday . \ Return value on the stack. output : 0
tv ->tv_sec # . \ output : 1369841953
Note that tv ->tv_sec is in fact the equivalent of (void *)&tv + offsetof(struct timeval, tv_sec) in C, so it gives you the address of the structure member, so you have to fetch the value with #. Another issue here: since I use a 64 bits Forth where the cell size is 8 bytes, storing/fetching an 8 bytes long is straightforward, but fetching/storing a 4 bytes int will require some special handling. Anyhow, Forth makes this easy: just define special purpose int# and int! words for that.
As you can see, with a good generic purpose C interface you do not need to write any glue code in C, only the Forth stubs for your C functions and structures are needed, but this is really straightforward (and most of it could be automatically generated from your C headers).
Once you're happy with your interactive tests, you can move on to automated tests:
Copy/paste the whole input/output from your interactive test session to a file named testXYZ.log
strip the output (keeping only the input) from your session log and write this to a file named testXYZ.fs
To run the test, pipe testXYZ.fs to your forth interpreter, capture the output and diff it with testXYZ.log.
Since removing output from an interactive session log can be somewhat tedious, you could also start by writing the test script testXYZ.fs then run it and capture the output testXYZ.log, but I prefer starting from an interactive session log.
Et voilĂ !
For reference, here's the structure handling code that I used in the above example :
\ *****************************************************************************
\ structures handling
\ *****************************************************************************
\ Simple structure definition words. Structure instances are zero initialized.
\
\ usage :
\ struct foo
\ int: ->refCount
\ int: ->value
\ end-struct
\ struct bar
\ int: ->id
\ foo struct: ->foo
\ 16 chars: ->name
\ end-struct
\
\ bar buffer: myBar
\ foo buffer: myFoo
\ 42 myBar ->id !
\ myFoo myBar ->foo !
\ myBar ->name count type
\ 1 myBar ->foo # ->refCount +! \ accessing members of members could use a helper word
: struct ( "name" -- addr 0 ; named structure header )
create here 0 , 0
does>
# ;
\ <field-size> FIELD <field-name>
\ Given a field size on the stack, compiles a word <field-name> that adds the
\ field size to the number on the stack.
: field: ( u1 u2 "name" -- u1+u2 ; u -- u+u2 )
over >r \ save current struct size
: r> ?dup if
postpone literal postpone +
then
postpone ;
+ \ add field size to struct size
; immediate
: end-struct ( addr u -- ; end of structure definition )
swap ! ;
: naligned ( addr1 u -- addr2 ; aligns addr1 to alignment u )
1- tuck + swap invert and ;
\ Typed field helpers
: int: cell naligned cell postpone field: ; immediate
: struct: >r cell naligned r> postpone field: ; immediate
: chars: >r cell naligned r> postpone field: ; immediate
\ with C style alignment
4 constant C_INT_ALIGN
8 constant C_PTR_ALIGN
4 constant C_INT_SIZE
: cint: C_INT_ALIGN naligned C_INT_SIZE postpone field: ; immediate
: cstruct: >r C_PTR_ALIGN naligned r> postpone field: ; immediate
: cchars: >r C_INT_ALIGN naligned r> postpone field: ; immediate
: buffer: ( u -- ; creates a zero-ed buffer of size u )
create here over erase allot ;
Related
I know yosys has limited tri-state support, but I'm looking for a possible workaround.
The following circuit:
module TBUF2
(
inout SALIDA1,
inout SALIDA2,
input OE,
output C);
assign SALIDA1=OE ? 1'b0 : 1'bZ;
assign SALIDA2=OE ? 1'b0 : 1'bZ;
wire e;
assign e=SALIDA1 & SALIDA2;
assign C=e;
endmodule
Is interpreted as:
TBUF2 parsed tree
Note that when OE is 0 C=SALIDA1 and SALIDA2.
During the opt pass, the opt_merge pass removes $2 mux and generates:
TBUF2 optimized
This breaks the circuit (when OE is 0 then C=SALIDA1). I realize this is because yosys/ABC doesn't really understand the consequences of the "1'z" input.
Is it possible to keep muxes that meet the following criteria?:
1) At least one input is 1'Z
2) Its output drives an inout pin
Here is the script to reproduce it:
read_verilog tbuf2.v
proc
show -format dot -prefix tbuf2_01
opt
show -format dot -prefix tbuf2_02
Convert the tristate buffer $mux cells to $tribuf cells by running the tribuf command after proc and before running any opt commands.
I want to save the output of a program to a variable.
I use the following approach ,but fail.
$ PIPE RUN TEST | DEFINE/JOB VALUE #SYS$PIPE
$ x = f$logical("VALUE")
I got an error:%DCL-W-MAXPARM, too many parameters - reenter command with fewer parameters
\WORLD\
reference :
How to assign the output of a program to a variable in a DCL com script on VMS?
The usual way to do this is to write the output to a file and read from the file and put that into a DCL symbol (or logical). Although not obvious, you can do this with the PIPE command was well:
$ pipe r 2words
hello world
$ pipe r 2words |(read sys$pipe line ; line=""""+line+"""" ; def/job value &line )
$ sh log value
"VALUE" = "hello world" (LNM$JOB_85AB4440)
$
IF you are able to change the program, add some code to it to write the required values into symbols or logicals (see LIB$ routines)
If you can modify the program, using LIB$SET_SYMBOL in the program defines a DCL symbol (what you are calling a variable) for DCL. That's the cleanest way to do this. If it really needs to be a logical, then there are system calls that define logicals.
I was wondering if it is possible to access debug information in a running application that has been compiled with /DEBUG (Pascal and/or C), in order to retrieve information about structures used in the application.
The application can always ask the debugger to do something using SS$_DEBUG. If you send a list of commands that end with GO then the application will continue running after the debugger does its thing. I've used it to dump a bunch of structures formatted neatly without bothering to write the code.
ANALYZE/IMAGE can be used to examine the debugger data in the image file without running the application.
Although you may not see the nice debugger information, you can always look into a running program's data with ANALYZE/SYSTEM .. SET PROCESS ... EXAMINE ....
The SDA SEARCH command may come in handy to 'find' recognizable morcels of date, like a record that you know the program must have read.
Also check out FORMAT/TYPE=block-type, but to make use of data you'll have to compile your structures into .STB files.
When using SDA, you may want to try run the program yourself interactively in an other session to get sample sample addresses to work from.... easier than a link map!
If you programs use RMS a bunch (mine always do :-), then SDA> SHOW PROC/RMS=(FAB,RAB) may give handy addresses for record and key buffers, allthough those may also we managed by the RTL's and thus not be meaningful to you.
Too long for a comment ...
As far as I know, structure information about elements is not in the global symbol table.
What I did, on Linux, but that should work on VMS/ELF files as well:
$ cat tests.c
struct {
int ii;
short ss;
float ff;
char cc;
double dd;
char bb:1;
void *pp;
} theStruct;
...
$ cc -g -c tests.c
$ ../extruct/extruct
-e-insarg, supply an ELF object file.
Usage: ../extruct/extruct [OPTION]... elf-file variable
Display offset and size of members of the named struct/union variable
extracted from the dwarf info in the elf file.
Options are:
-b bit offsets and bit sizes for all members
-lLEVEL display level for nested structures
-n only the member names
-t print base types
$ ../extruct/extruct -t ./tests.o theStruct
size of theStruct: 0x20
offset size type name
0x0000 0x0004 int ii
0x0004 0x0002 short int ss
0x0008 0x0004 float ff
0x000c 0x0001 char cc
0x0010 0x0008 double dd
0x0018 0x0001 char bb:1
0x001c 0x0004 pp
$
When writing new functions with Vim I always seem to have to do a bit of "manual" work.
x = Cursor position
If I start typing a function and insert a couple of curly braces and the end
function Apples() {x}
Then hit Enter, it obviously looks like this
function Apples() {
x}
Which results in me having to ESC,O in order to shift the closing curlybrace down.
While this may seem like a trivial matter, doing this over the last 5 months is getting bothersome, and I know there are plenty like me out there who knows there should be an elegant solution to this. I am open to plugin-suggestions.
You can use a simple mapping like this one (there are dozens of variants floating around SO and the web):
inoremap {} {<CR>}<C-o>O
You can also search www.vim.org for a dedicated plugin.
But I strongly recommend you to try a snippet-expansion plugin like Snipmate or UltiSnips. Both plugins follow the same model but they have slightly different snippet syntaxes and features. It works like that:
you type a trigger:
fun
you hit <Tab> and you get the following with function_name in select mode:
function [function_name]() {
}
you type your desired name:
function Apples|() {
}
you hit <Tab> to place the cursor between the parentheses:
function Apples(|) {
}
you hit <Tab> again to place the cursor on the line below with the correct indentation:
function Apples() {
|
}
With lh-bracket (in C or C++ mode), when you hit enter whilst in between two brackets, the newlines you are expecting are inserted.
The idea is to test for: getline(".")[col(".")-2:col(".")-1]=="{}" and execute/insert "\<cr>\<esc>O" when the condition is true, or "\<cr>" otherwise.
Within lh-bracket, I have the following into a C-ftplugin:
call lh#brackets#enrich_imap('<cr>',
\ {'condition': 'getline(".")[col(".")-2:col(".")-1]=="{}"',
\ 'action': 'Cpp_Add2NewLinesBetweenBrackets()'},
\ 1,
\ '\<cr\>'
\ )
function! Cpp_Add2NewLinesBetweenBrackets()
return "\<cr>\<esc>O"
endfunction
I guess (code not tested) it would (*) translate into:
" put it into ftplugin/{yourfiltetype, javascript?}.vim
inoremap <buffer> <silent> <expr> <cr> s:SmartCR()
function s:SmartCR()
return getline(".")[col(".")-2:col(".")-1]=="{}"
\ ? "\<cr>\<esc>O"
\ : "\<cr>"
endfunction
(*) Actually, lh#brackets#enrich_imap does a few other things (the mapping is compatible with LaTeXSuite's IMAP.vim presence ; the mapping can be toggled on/off along with all the other mappings from lh-brackets)
I am working on an iPhone app. I am a full-time Java developer and I am used to using Eclipse where I can put a breakpoint in and stop the process. Then, I can type in any expression that I want and Eclipse will evaluate it using the values from that point in the process.
Is there a way to do that in Xcode? I want to be able to stop at a breakpoint and then enter some code to evaluate it. The gdb console will let me do po (print-object), but it is really limited. Any help?
In XCode 4.0 this is sort of hidden in the GUI. When you're at a breakpoint you can probably see the Variables View inside the Debug Area; it's the pane which shows local variables and such. Right-click on the Variables View and select "Add Expression..."
I realize this is an old thread but it's still a top Google hit so I thought it worth answering.
My practice:
po [NSUserDefaults standardUserDefaults]
displays: <NSUserDefaults: 0x6143040>
po [[NSUserDefaults standardUserDefaults] stringForKey:#"Currency"]
displays: "CHF"
Use the "expression" command in the debugger. Using it is relatively simple. Just type the command expression and press enter. You will then be prompted enter an expression. Here is an example
(lldb) expression
Enter expressions, then terminate with an empty line to evaluate:
2+2
(int) $2 = 4
I also attached the help info for the expression command below. Hope this helps.
Evaluate a C/ObjC/C++ expression in the current program context, using user
defined variables and variables currently in scope. This command takes
'raw' input (no need to quote stuff).
Syntax: expression --
Command Options Usage:
expression [-f ] [-G ] [-a ] [-d ] [-t ] [-u ] --
expression [-o] [-a ] [-d ] [-t ] [-u ] --
expression
-G <gdb-format> ( --gdb-format <gdb-format> )
Specify a format using a GDB format specifier string.
-a <boolean> ( --all-threads <boolean> )
Should we run all threads if the execution doesn't complete on one
thread.
-d <boolean> ( --dynamic-value <boolean> )
Upcast the value resulting from the expression to its dynamic type
if available.
-f <format> ( --format <format> )
Specify a format to be used for display.
-o ( --object-description )
Print the object description of the value resulting from the
expression.
-t <unsigned-integer> ( --timeout <unsigned-integer> )
Timeout value for running the expression.
-u <boolean> ( --unwind-on-error <boolean> )
Clean up program state if the expression causes a crash, breakpoint
hit or signal.
Timeouts:
If the expression can be evaluated statically (without runnning code) then it will be.
Otherwise, by default the expression will run on the current thread with a short timeout:
currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted
and resumed with all threads running. You can use the -a option to disable retrying on all
threads. You can use the -t option to set a shorter timeout.
User defined variables:
You can define your own variables for convenience or to be used in subsequent expressions.
You define them the same way you would define variables in C. If the first character of
your user defined variable is a $, then the variable's value will be available in future
expressions, otherwise it will just be available in the current expression.
Examples:
expr my_struct->a = my_array[3]
expr -f bin -- (index * 8) + 5
expr unsigned int $foo = 5
expr char c[] = "foo"; c[0]
IMPORTANT NOTE: Because this command takes 'raw' input, if you use any
command options you must use ' -- ' between the end of the command options
and the beginning of the raw input.
Not answering question about Xcode, but JetBrains' AppCode does this in the standard IDE way most of us know from other platforms.