CP/M get running program name - c

For a hobby project I'm porting the Standard C Library to the Digital Research CP/M.
Inside CRT0.S (this is the code that runs before your main() C function is called) I have no trouble parsing the tail of the command line arguments from the lower memory, but I'm unable to get the running program name i.e. if I type
memdump 0xfc00 100
I'd like to obtain memdump or memdump.com from CP/M in a nice way so that I can set my args to (pseudo code) correctly
argv[0] = "memdump.com";
argv[1] = "0xfc00";
argv[2] = "100";

Related

How is it possible that Cygwin seemingly manages to bypass the MS C Runtime library enabling a C program to get its argv like a Linux machine would?

How is it possible that Cygwin seemingly manages to bypass the MS C Runtime library enabling a C program to get its argv like a Linux machine would?
I'll explain what I mean.
On Windows I understand that a C program has the choice of calling GetCommandLine() or of using argv.
And I understand that a windows implementation of C compiler would make C programs implicitly call the MS C Runtime Library, which will take the command line (perhaps outputted by GetCommandLine()), that isn't separated into arguments, and it'll take that as input and parse it, putting it into argv. This link mentions about that https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=msvc-170
And from what I understand, on Linux, what's written after the command at the command line, goes straight from the shell to argv. No external library doing the parsing. The shell calls a POSIX function called execv and figures out what the arguments are and passes them to execv which passes them to the program's argv.
I use these programs for some tests
C:\blah>type w.c
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[]) {
printf(GetCommandLine());
return 0;
}
C:\blah>w.exe "asdf" erw
w.exe "asdf" erw
C:\blah>
C:\blah>type w2.c
#include <stdio.h>
int main(int argc, char *argv[]) {
int i = 0;
while (argv[i]) {
printf("argv[%d] = %s\n", i, argv[i]);
i++;
}
return 0;
}
C:\blah>w2 abc "def"
argv[0] = w2
argv[1] = abc
argv[2] = def
C:\blah>
And w2.c can be run from linux too
root#ubuntu:~# ./w2 abc "def"
argv[0] = ./w2
argv[1] = abc
argv[2] = def
root#ubuntu:~#
I notice that there are some cases where the MS C Runtime gives a different parsing, to Linux. (Linux of course wouldn't be using the MS C Runtime)
For example, this link https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=msvc-170 mentions this command line input a\\\b d"e f"g h and expected outputs.
C:\blah>w2 a\\\b d"e f"g h
argv[0] = w2
argv[1] = a\\\b
argv[2] = de fg
argv[3] = h
C:\blah>
Whereas on Linux, one gets
root#ubuntu:~# ./w2 a\\\b d"e f"g h
argv[0] = ./w2
argv[1] = a\b
argv[2] = de fg
argv[3] = h
So now the interesting test was, what would Cygwin do
user#comp /cygdrive/c/blah
$ ./w2 a\\\b d"e f"g h
argv[0] = C:\blah\w2.exe
argv[1] = a\b
argv[2] = de fg
argv[3] = h
Cygwin manages to get the result that a linux machine would give.
But it's running an EXE file that was compiled on Windows and that i'd have thought must be using the MS C Runtime library. And when running the EXE file from CMD outside cygwin, then it does look like it's using the MS C Runtime Library. So how is Cygwin seemingly managing to bypass that to lead the program to give the result that a linux machine would give.
How is this possible?! What is going on?!
I conversed with somebody that knows about cygwin.. They said that cygwin can detect whether an executable is a windows executable, or a cygwin executable. And the ldd command can do so. And a cygwin executable will be linked to cygwin1.dll. A program like sysinternals process explorer can show what DLLs are linked to a running process e.g. it shows that bash.exe is linked to cygwin1.dll. But the ldd command is more useful here as it shows also for commands that aren't kept open. $ ldd /bin/bash.exe showed some NT related DLLs, but also cygwin1.dll. Whereas $ldd ./w.exe showed just NT related Dlls, no cygwin1.dll.
And they said that this file winsup/cygwin/winf.cc is very relevant to that. I have it on my system https://gist.github.com/gartha1/4a2871b7f22ef85b5c8c0b08674b6f57 I see it has stuff about argv
Some comments and C guys I conversed with have indicated to me, and from my understanding of what they said, that Linux has some compiler specific C runtime libraries. And when people say C runtime libraries, they tend to mean to include also POSIX functions like execv, that is technically not part of the C standard, but part of the POSIX standard. And the runtime libraries apply before main starts and after end finishes.
I was looking at it from the point of view is, this is the command line, i've typed, and what is then sent to argv, and how. But another perspective is, looking at what's sent to argv, and taking a step back and what's the value at GetCommandLine() that'd produce that. And also I think, looking at the command line typed, and seeing what it sends or would send to GetCommandLine().
The MS C Runtime, starts with GetCommandLine() then calls GetCommandLineToArgs() https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-getcommandlinea "GetCommandLine as an alias which automatically selects the ANSI or Unicode version of this function" and "To convert the command line to an argv style array of strings, pass the result from GetCommandLineA to CommandLineToArgW." What is the difference between the `A` and `W` functions in the Win32 API? "The A functions use Ansi (not ASCII) strings as input and output, and the W functions use Unicode string instead .."
So, what MS C Runtime sees when it does GetCommandLine() is very significant. And I think Cygwin's linux shell e.g. bash , does its parsing.. which is described by info bash and includes "word splitting"(separating arguments), and quote removal.
calc.exe is useful because it stays open so I can look at the command line with WMIC. That's clearer than using w.exe(from cmd), to determine what the command line is.
To use some simple examples with calc.exe trying calling it with command line of
calc "abc"
calc a\a
In the case of calc "abc", what gets into argv in Cygwin and plain cmd is the same. And what gets seen by GetCommandLine() won't really need any adjustment, though cygwin sanitises what it makes available to GetCommandLine() a bit.
Looking with CMD, we see
C:\>w calc abc
w calc abc
C:\>w calc "abc"
w calc "abc"
C:\>w2 calc abc
argv[0] = w2
argv[1] = calc
argv[2] = abc
C:\>w2 calc "abc"
argv[0] = w2
argv[1] = calc
argv[2] = abc
So a value from GetCommandLine() of calc "abc" or calc abc are equivalent
I'm using wmiccalc.exe which runs the line wmic process where caption="calc.exe" get commandline | calc "abc"
C:\>calc "abc" <ENTER>
C:\>wmiccalc.bat<ENTER>
calc "abc"
Now see what happens if I run calc from cygwin, what the command line is
$ calc "abc" &
$ ./wmiccalc.bat
C:\Windows\System32\calc.exe abc
It is using a slightly sanitised command line that won't change anything in terms of what is sent to argv(what it gives the runtime to send to argv), relative to what the pure cmd call of calc.exe will end up (via the runtime), sending through to argv.
In both cases it'd be the MS C Runtime. That gets run.
What Cygwin did was it took the "abc" and said, well, bash will want abc in argv, so it constructed a command line that (when sent through the MS C Runtime), would/will send abc to argv.
Now let's look at this example
2. calc a\a
This is slightly different to the first example. 'cos not just what is sent (via the MS C runtime), to argv in the cygwin case and the cmd case are different..
What is produced by the MS C Runtime, is different.
Cygwin sends what it wants to send, to produce the output that bash wants produced.
C:\>calc a\a
C:\>wmiccalc.bat
calc a\a
From Windows, that's the command line
And from that command line, The MS C Runtime will send the following to argv
>w2 a\a
argv[0] = w2
argv[1] = a\a
If though an executable in linux gets a command line like a\a , it treats the backslash as an escape character.. so it wouldn't have a\a going to an argv.
$ echo a\a
aa
So if I do
$ calc a\a &
$ ./wmiccalc.bat
C:\Windows\System32\calc.exe aa
So cygwin will use a very different command line.. a command line of aa not a\a
$ ./w2 a\a
argv[0] = ......\w2.exe
argv[1] = aa
And that makes sense, because if we look at CMD, a command line a\a gets what we'd want if having that command line on windows.
>w2 a\a
argv[0] = w2
argv[1] = a\a
>
Whereas a command line of aa i.e. the MS C Runtime seeing a GetCommandLine() result of aa, gets what we'd want in argv if running it from linux or bash
>w2 aa
argv[0] = w2
argv[1] = aa
>
So, if you run the executable on windows plain CMD not cygwin, you get what it should show for Windows.
And if you run the executable from Cygwin, cygwin's shell e.g. bash shell, parses it constructs the windows call to the program so that it gives MS C Runtime the command line so that Ms C Runtime will put the right things into argv to give what a linux machine would show. So it's not bypassing MS C Runtime. It's using it cleverly. It's saying "Having parsed the output given to me by the linux shell e.g. bash, I know what argv values I want, so i'll put together a command line that takes into account how MS C Runtime parses things, so as to get the argv values I want"
By the way
One of the comments corrects one of the things I wrote in my question.. I wrote
And from what I understand, on Linux, what's written after the command
at the command line, goes straight from the shell to argv. No external
library doing the parsing. The shell calls a POSIX function called
execv and figures out what the arguments are and passes them to execv
which passes them to the program's argv.
But actually, there's a C Runtime used by compilers on linux.. The POSIX function execv would be considered to be part of that. If somebody didn't want to call it C Runtime, they could call it C/POSIX runtime.
Also some comments to the question helped correct some misconceptions in areas of lack of clarity in the question e.g.
To the question of "And am I correct in thinking that the shell passes the command line or some function of it, to the Runtime, which puts the command line into argv?"
this comment explained how what the shell wants the arguments to be, will eventually get to main(And thus argv). Never going straight there, and not even from the shell straight to the runtime.. From shell to OS to runtime.
"
#barlop: The shell passes the command line to the operating system, probably by calling CreateProcess (one of arguments of that function is the command line). The operating sytem then creates a new process, which causes the C run-time library to take control. The run-time library will probably call the Windows API function GetCommandLine and will use the returned information to set argc and argv, before it calls main. –
Andreas Wenzel"
Consider that the shell (bash?) in Cygwin does its own parsing of the command line before any Windows function is called to launch the application. Since this shell is more compatible to a Linux shell, I'd expect the same outcome, in contrast to the parsing of CMD. –
the busybee
"
Anyhow, I think this addresses what is happening.. How the command line typed into cygwin is transformed to a string seen by GetCommandLine() and gets the result using the MS C Runtime library.
I used two simple examples but they would explain it for the case given in the question too.

Read a line of c code from file and execute in a c program

I have a C program which calculates f(x) for some x values (main.c). I need to get a line of c code from file and that code is my function to execute (function.dot). For example function.dot will contain:
pow((1-x), 0.333);
I need to read this file, get that function and execute in my code (main.c). How can I do that?
Basic steps would be:
Read the line from the file.
Generate a new source file which wraps the line of code inside appropriate code.
Invoke a compiler to compile that code into a shared object/dll.
Load the library.
Call the function in the library.
If the single line of code in the file could be any language, it would be far easier to use something like Lua that can be linked into your main executable.
I will provide some options:
Switch to another interpreted language including python, ruby, perl, ...
If you are working on small project, I recommend this option.
Implement your own interpreter in C.
Parse your input, analyze it, execute it. You might find open source implementations: one choice is slang
http://www.jedsoft.org/slang/doc/html/slang.html
Call C compiler and dynamically link it.
It depends on your operating system but system or exec functions help you to call your compiler to handle your input file. If you are using Linux, dlsym can open a shared-object compiled from your input file.
You might need to convert your input file into C program.
Very slow to compile but fastest to run.
You have several options I can think of:
1) Switch to any number of interpreted langauges (python, perl, etc.) which support this as an easy mechanism. (Example: in python
data = open("function.dot").read()
x = 5
eval(data) #note that this is unsafe if you can't trust data, and you might also need to play with environment
)
2) You could wrap the code in it's own c file... something like (but with more error checking etc... you probably don't want to do this)
void generate_c_program(char *line)
{
FILE *fp = fopen("myfile.c","wt");
fprintf(fp,"#include <math.h>\nint main(char *argv, int argc) {\n double x = atof(argv[1]); printf(\"%f\",(%s));}\n");",line); //this is also unsafe if you can't trust data
fclose(fp);
//now execute gcc myfile.c
//now execute a.out
//optionally cleanup by deleting a.out and myfile.c
}
3) Effectively write your own compiler / parser (which may be fairly easy IF you've done this before and the number of functions / operations you need to support is small or may be a much bigger deal and will rather not fit in this answer)... the extensible way would be to use LEX/YACC or similar)

Command Line Argument Counting

This is a simple C program that prints the number of command line argument passed to it:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%d\n", argc);
}
When I give the input
file_name *
It prints 623 instead of 2 in my pc (operating system Windows 7). But it gives the correct output in other cases. Is * a reserved character for command line arguments?
Note this program gives correct output for the following input:
file_name *Rafi
Output = 2
On a Unix command line, the shell is responsible for handling wildcards. yourapp * will run yourapp, and pass the name of ALL of the non-hidden files in the current directory as arguments. In your case, that's 622 files (623 = 622 files + name of the program).
On Windows, applications are responsible for wildcard parsing, so argc is 2, 1 for the name of the program (argv[0]) and 1 for the wildcard (argv[1] = *);
That * gets expanded by the shell or the runtime library (the former on *nixes, the latter on Windowses), and instead of literal * you get the names of all the files in the current working directory.
As others have mentioned, you're getting the 'shell wildcard expansion' or 'globbing' where the * is used as a wildcard to match file names to place in the argv array.
On Unix systems this is performed by the shell and has nothing (or little) to do with the C runtime.
On Windows systems, this functionality is not performed by the shell (unless possibly if you're using some Unix-like shell replacement like Cygwin). The globbing functionality may or may not be performed by the C runtime's initialization depending on what tools and/or linker options you use:
if you're using Microsoft's compiler, the C runtime will not perform globbing by default, and you would get an argc value of 2 in your example. However, if you ask the linker to link in setargv.obj (or wsetargv.obj if you have a Unicode build), then globbing is added to the runtime initialization and you'll get behavior similar to Unix's. setargv.obj has been distributed with MSVC for as long as I can remember, but it's still little known. I believe that most Windows programs perform their own wildcard expansion.
if you're using the MinGW/GCC tool chain, the C runtime will perform globbing before calling main() (at least it does for MinGW 4.6.1 - I suspect it's been in MinGW for a long time). I think MinGW might not perform globbing for GUI programs. You can disable MinGW's globbing behavior with one of the following:
define a global variable named _CRT_glob and initialize it to 0:
int _CRT_glob = 0;
link in the lib/CRT_noglob.o object file (I think this might be order dependent - you may need to place it before any libraries):
gcc c:/mingw/lib/CRT_noglob.o main.o -o main.exe
The problem is that the shell expands * into all the file names (that don't start with a .) in the current directory. This is all about the shell and very little to do with the C program.
The value of argc includes 1 for the program's own name, plus one for each argument passed by the shell.
Try:
filename *
filename '*'
The first will give you 623 (give or take - but it is time you cleaned up that directory!). The second will give you 2.

Using popen() to open a program in command line?

Is it possible to open a program using another program? For example:
I want to make a command line application in C that will prompt the user to type in the name of a program (lets say Microsoft Word.app), and that program will launch. Would I do something like this:
#include <stdio.h>
#include <time.h>
int main (int argc, const char * argv[]) {
char programName[1000];
printf("Type in the name of the program you would like to open: ");
scanf("%s", programName);
popen(programName);
}
However, popen() asks me for another char. How would I go about using popen() to open the program?
EDIT: The following code works!
#include <stdio.h>
#include <time.h>
int main (int argc, const char * argv[]) {
char programName[1000];
char app[100] = ".app";
char openApp[100] = "open /Applications/";
printf("Type in the name of the program you would like to open: ");
scanf("%s", programName);
strcat(openApp, programName);
strcat(openApp, app);
system(openApp);
}
popen lets you launch a program and get a file descriptor to its input or output, much like fopen works for files. For instance, if you wanted to read the output of your program, you'd use popen("program", "r"). On the other hand, if you want to write to its input, you would use popen("program", "w"). Mac OS X also allows for r+, which lets you read the output and write to the input but this capability isn't standard and shouldn't be relied on for cross-platform code.
If you just want to launch a program, you might as well use the system function, which does that and waits until the program exits, at which point it returns the status code. system actually invokes the shell to work, so arguments will undergo expansion (environment variables, ~, etc).
EDIT Following your comment that system("Microsoft Word.app") doesn't work as you'd expect: there are several reasons for this, actually. Starting with the message you get: this is because what you wrote is equivalent to opening a terminal window and typing Microsoft Word.app. In other words, it tries to find a program called "Microsoft", then pass it the argument "Word.app". You would need to either quote the program name or escape spaces to have the shell understand it's a whole program name and not a program name then an argument: system("Microsoft\ Word.app")
Now, this should complain saying that the shell can't find the program "Microsoft Word.app", which is already a step forward.
This is because on Mac OS, app files aren't executable files: they're folders that the Finder displays as a single file. You can verify that by ctrl+clicking (or right-clicking) an app and selecting "Show package contents" (this will open the app folder). The actual executable for Microsoft Word.app must be somewhere along the path of Microsoft Word.app/Contents/MacOS/Microsoft Word.
As you can see, this is getting kind of complex. Luckily enough, Apple provides the open executable, which can use a bunch of OS services to figure out those details. It allows to launch applications in the following fashion:
open -a Microsoft\ Word
This should launch Word. (Notice how you still need to escape the spaces.) In pure C code, that would get you something like this:
system("open -a Microsoft\\ Word");
If you choose to use Objective-C and Cocoa, however, there is a very simple way to open applications:
NSString* appName = #"Microsoft Word"; // no escape!
[[NSWorkspace sharedWorkspace] launchApplication:appName];
NSString objects can be created from C string easily enough:
NSString* appName = [[NSString alloc] initWithCString:programName encoding:NSUTF8StringEncoding];
[[NSWorkspace sharedWorkspace] launchApplication:appName];
[appName release];
It would be better to use system(3) for this purpose.
The popen(3) function establishes a pipeline that can be read or written by the caller. But GUI applications do not use standard input and standard output, they connect to the graphical interface server, sometimes called the "window server". This server is already running and already has decided what its keyboard input will be, and it is always writing its output to the video device.
To start a .app you should actually run the open(1) program, so try something like:
system("open /Applications/MacVim.app");

Linux C: Shell-like environment - for individual execution - of C commands? (C interpreter)

Sorry if the question is worded wrong - I don't know the right word for what I'm asking for! :)
Say, you have some simple C program like:
#include <stdio.h>
int main()
{
int a=2;
printf("Hello World %d\n", a);
return 0;
}
Typically, this would have to be saved in a file (say, hello.c); then we run gcc on the source file and obtain executable file - and if we compiled in debug information, then we can use gdb on the executable, to step through lines of code, and inspect variables.
What I would like to have, is basically some sort of a "C" shell - similar to the Python shell; in the sense that I can have a sequence of Python commands in a file (a script) - or I can just paste the same commands in the shell, and they will execute the same. In respect to the simple program above, this is what I'd like to be able to do (where C> represents the imagined prompt):
C> #include <stdio.h>
(stdio.h included)
C> int a=2;
C> printf("Hello World %d\n", a);
Hello World 2
C>
In other words, I'd like to be able to execute individual C commands interactively (I'm guessing this would represent on-the-fly compilation of sorts?). Initially I was misled by the name of the C shell (csh) - but I don't think it will be able to execute C commands on the fly.
So, first and foremost, I'd like to know if it is possible somehow to persuade, say, gdb to perform in this manner? If not, is there anything else that would allow me to do something similar (some special shell, maybe)?
As for the context - I have some code where I have problems troubleshooting pointers between structs and such; here the way gdb can printout structs works very well - however, to isolate the problem, I have to make new source files, paste in data, compile and debug all over again. In this case, I'd much rather have the possibility to paste several structs (and their initialization commands) in some sort of a shell - and then, inspect using printf (or even better, something akin to gdb's print) typed directly on the shell.
Just for the record - I'm not really persuaded something like this really exists; but I thought I'd ask anyways :)
Thanks in advance for any answers,
Cheers!
EDIT: I was a bit busy, so haven't had time to review all answers yet for accept (sorry :) ); just wanted to add a little comment re:"interpreted vs. machine code"; or as mentioned by #doron:
The problem with running C /C++ source interactively is that
the compiler is not able to perform line by line interpretation of the code.
I am fully aware of this - but let's imagine a command line application (could even be an interpreted one), that gives you a prompt with a command line interface. At start, let's assume this application generates this simple "text file" in memory:
##HEADER##
int main()
{
##MAIN##
return 0;
}
Then, the application simply waits for a text to be entered at the prompt, and ENTER to be pressed; and upon a new line:
The application checks:
if the line starts with #define or #include, then it is added below the ##HEADER## - but above the int main() line - in the temp file
anything else, goes below ##MAIN## line - but above return 0; line - in the temp file
the temp file is stripped of ##HEADER## and ##MAIN## lines, and saved to disk as temp.c
gcc is called to compile temp.c and generate temp.out executable
if fail, notify user, exit
gdb is called to run the temp.out executable, with a breakpoint set at the return 0; line
if fail, notify user, exit
execution is returned to the prompt; the next commands the user enters, are in fact passed to gdb (so the user can use commands like p variable to inspect) - until the user presses, say, Ctrl+1 to exit gdb
Ctrl+1 - gdb exits, control is returned to our application - which waits for the next code line all over again.. etc
(subsequent code line entries are kept in the temp file - placed below the last entry from the same category)
Obviously, I wouldn't expect to be able to paste the entire linux kernel code into an application like this, and expect it to work :) However, I would expect to be able to paste in a couple of structs, and to inspect the results of statements like, say:
char dat = (char) (*(int16_t*)(my->structure->pdata) >> 32 & 0xFF) ^ 0x88;
... so I'm sure in what is the proper syntax to use (which is usually what I mess up with) - without the overhead of rebuilding and debugging the entire software, just to figure out whether I should have moved a right parenthesis before or after the asterisk sign (in the cases when such an action doesn't raise a compilation error, of course).
Now, I'm not sure of the entire scope of problems that can arise from a simplistic application architecture as above. But, it's an example, that simply points that something like a "C shell" (for relatively simple sessions/programs) would be conceptually doable, by also using gcc and gdb - without any serious clashes with the, otherwise, strict distinction between 'machine code' and 'interpreted' languages.
There are C interpreters.
Look for Ch or CINT.
Edit: found a new (untested) thing that appears to be what the OP wants
c-repl
Or just use it [...] like driving a Ferarri on city streets.
Tiny C Compiler
[... many features, including]
C script supported : just add '#!/usr/local/bin/tcc -run' at the first line of your C source, and execute it directly from the command line.
When your CPU runs a computer program, it runs something called machine code. This is a series of binary instructions that are specific to the CPU that you are using. Since machine code is quite hard to hand code, people invented higher level languages like C and C++. Unfortunately the CPU only understands machine code. So what happens is that we run a compiler that converts the high-level source language into machine code. Computer languages in this class are compiled language like C and C++. These languages are said to run natively since the generated machine code is run by the CPU without any further interpretation.
Now certain languages like Python, Bash and Perl do not need to be compiled beforehand and are rather interpreted. This means that the source file is read line by line by the interpreter and the correct task for the line is performed. This gives you the ability run stuff in an interactive shell as we see in Python.
The problem with running C /C++ source interactively is that the compiler is not able to perform line by line interpretation of the code. It is designed solely to generate corresponding machine code and therefore cannot run your C / C++ source interactively.
#buddhabrot and #pmg - thank you for your answers!
For the benefit of n00bery, here is a summary of the answers (as I couldn't immediately grasp what is going on): what I needed (in OP) is handled by what is called a "C Interpreter" (not a 'C shell'), of which the following were suggested:
CINT | ROOT - Ubuntu: install as sudo apt-get install root-system-bin (5.18.00-2.3ubuntu4 + 115MB of additional disk space)
c-repl (c-repl README)- Ubuntu: install as sudo apt-get install c-repl (c-repl_0.0.20071223-1_i386.deb + 106kB of additional disk space)
Ch standard edition - standard edition is freeware for windows/Unix
For c-repl - there is a quick tutorial on c-repl homepage as an example session; but here is how the same commands behave on my Ubuntu Lucid system, with the repository version (edit: see Where can I find c-repl documentation? for a better example):
$ c-repl
> int x = 3
> ++x
> .p x
unknown command: p
> printf("%d %p\n", x, &x)
4 0xbbd014
> .t fprintf
repl is ok
> #include <unistd.h>
<stdin>:1:22: warning: extra tokens at end of #include directive
> getp
p getp
No symbol "getp" in current context.
> printf("%d\n", getpid())
10284
> [Ctrl+C]
/usr/bin/c-repl:185:in `readline': Interrupt
from /usr/bin/c-repl:185:in `input_loop'
from /usr/bin/c-repl:184:in `loop'
from /usr/bin/c-repl:184:in `input_loop'
from /usr/bin/c-repl:203
Apparently, it would be best to build c-repl from latest source.
For cint it was a bit difficult to find something relateed to it directly (the webpage refers to ROOT Tutorials instead), but then I found "Le Huy: Using CINT - C/C++ Interpreter - Basic Commands"; and here is an example session from my system:
(Note: if cint is not available on your distribution's package root-system-bin, try root instead.)
$ cint
cint : C/C++ interpreter (mailing list 'cint#root.cern.ch')
Copyright(c) : 1995~2005 Masaharu Goto (gotom#hanno.jp)
revision : 5.16.29, Jan 08, 2008 by M.Goto
No main() function found in given source file. Interactive interface started.
'?':help, '.q':quit, 'statement','{statements;}' or '.p [expr]' to evaluate
cint> L iostream
Error: Symbol Liostream is not defined in current scope (tmpfile):1:
*** Interpreter error recovered ***
cint> {#include <iostream>}
cint> files
Error: Symbol files is not defined in current scope (tmpfile):1:
*** Interpreter error recovered ***
cint> {int x=3;}
cint> {++x}
Syntax Error: ++x Maybe missing ';' (tmpfile):2:
*** Interpreter error recovered ***
cint> {++x;}
(int)4
cint> .p x
(int)4
cint> printf("%d %p\n", x, &x)
4 0x8d57720
(const int)12
cint> printf("%d\n", getpid())
Error: Function getpid() is not defined in current scope (tmpfile):1:
*** Interpreter error recovered ***
cint> {#include <unistd.h>}
cint> printf("%d\n", getpid())
10535
(const int)6
cint> .q
Bye... (try 'qqq' if still running)
In any case, that is exactly what I needed: ability to load headers, add variables, and inspect the memory they will take! Thanks again, everyone - Cheers!
Python and c belongs to different kinds of language. Python is interpreted line by line when running, but c should compile, link and generate code to run.

Resources