C code in Swift Project - c

I have a C program, that I would like to print its output from swift, and when it scans I can give it input through Swift. Is such thing possible? I tried this with a simple function, and it worked, but how can someone do so with many different functions that call other functions?
I know the question is a bit vague, but can someone point me into the right direction?
Example of code:
int main(int argc, char **argv) {
int i;
int hitme;
char ch;
prelim();
if (argc > 1) { // look for -f option
if (strcmp(argv[1], "-f")== 0) {
coordfixed = 1;
argc--;
argv++;
}
}
if (argc > 1) {
fromcommandline = 1;
line[0] = '\0';
while (--argc > 0) {
strcat(line, *(++argv));
strcat(line, " ");
}
}
else fromcommandline = 0;
while (TRUE) { /* Play a game */
setup();
if (alldone) {
score(0);
alldone = 0;
}
else makemoves();
skip(2);
stars();
skip(1);
if (tourn && alldone) {
printf("Do you want your score recorded?");
if (ja()) {
chew2();
freeze(FALSE);
}
}
printf("Do you want to play again?");
if (!ja()) break;
}
skip(1);
prout("May the Great Bird of the Galaxy roost upon your home planet.");
return 0;
}

Yes.
This is extensively covered in Using Swift with Cocoa and Objective-C. Objective-C is a superset of C, so all the instructions for Objective-C work equally well for C.
The short version is that you just add the C code to your project, import its header in your Objective-C Bridging Header, and then the C functions will be available in Swift (using various automatic translations).
That said, if you really want to read the output (i.e. the results of these printf) calls, that's a bit different problem. I'd avoid it if you can. Otherwise you'd need to do something like build the C program as its own executable and use NSTask within Swift to call it and capture the output, or you'd have to hijack stdout with something like fdopen. It's a pain to do that completely correctly.

I will focus on the second part of your question, how to interact with C code that uses the standard IO facilities:
The obvious choice as Rob Napier pointed out is just compiling the C code into an executable and using something akin to popen(3) to read and write to its standard IO facilities, the same way you would read/write any other FILE*.
Another way would be to seek out places where stdio is used and change these functions. For example you could use
#ifdef STANDALONE
#define print printf
#else
#define print passToSwift
#endif
Then you can change all the printfs to prints and just #define which mode you want your C code to operate in. In case STANDALONE is left undefined, you will have to provide a passToSwift function that will connect your C and Swift functionality.
One more way without having to change all printfs is using funopen(3) or friends, particularly fwopen(3). With fwopen(3) (man fwopen) you can provide a passToSwift function to be called whenever something is written to stdout.
#include <stdio.h>
int passToSwift(void * cookie, const char * buffer, int len)
{
(void)cookie;
// do stuff with the buffer you recieved
return len;
}
int main(void)
{
fflush(stdout);
stdout = fwopen(NULL, passToSwift);
printf("Hey\n");
}
The assignment to stdout is not portable, but works for me on OS X. I am not aware of any other way to achieve it. (dup2 gives EBADF for funopend streams, freopen expects an entry in the filesystem).

I am adressing a quite similar problem.
I have a solution open to discussion on codereview: C hack: replace printf to collect output and return complete string by using a line buffer
Maybe you could use that (or a part of it) for your text game as well ...

The improved version of C hack: replace printf to collect output and return complete string by using a line buffer is now availabe on github as Xcode 7 project swift-C-string-passing (and standalone gcc version).
Especially look at the #define preprocessor statements to make use of the bridge to swift (similar to a3f's answer).
My solution is able to pass strings in and out to the C code. But how are the answers retrieved from the user? I.e. what does the ja() function do?

Related

unix: main() interactive, command line, piping & redirection in C?

While there is an easy way of using both file redirection and piping, as well as interactive user input reading , with main(), as shown in this C code snippet...
#define SIZ 1024
#include <stdio.h>
extern void do_something_with_the_array(float *a[], int *n);
int main(int argc, const char * argv[])
{
float f[SIZ];
int k = 0;
while ((scanf("%f", &f[k]) == 1)&&(k < SIZ)) {
k++;
}
do_something_with_the_array(f, k);
return 0;
}
… I'm not sure if there is a modern UNIX source compatible and easy way of programmatically achieving any of the three possibilities in a main() in C, depending on the context ?
interactive reading of a string of numbers as user input
reading of the same string of numbers as command line arguments
file redirection and piping
I understand piping and redirection "belong" to the shell which intercepts the program before it even starts executing, while command line arguments and interactive reading "belong" to the main() itself and therefore there may not be an easy way of doing this.
I see using stdin or file input or pipe input pretty self-explanatory. However, reading command line arguments is a different story. Here's a demo how I usually code it, but it looks kind of heavy-handed and hacked to me. Also, in more complicated scenarios with options, this could become a pretty messy piece of code. I'm also not sure how fail-safe or fool proof this is...
#define SIZ 1024
#include <stdio.h>
#include <stdlib.h>
extern void do_something_with_the_array(float *, int);
int main(int argc, const char * argv[])
{
float f[SIZ];
int k = 0;
if(argc > 2){
for(k = 0; k < argc - 1; k++)
f[k] = (float)atof(argv[k+1]);
}
else while ((scanf("%f", &f[k]) == 1)&&(k < SIZ))
k++;
do_something_with_the_array(f, k);
return 0;
}
Thanks in advance!
I do not know off-hand of a C library that will make the three specific cases you mentioned look the same (although someone who does, please answer because I'd like to know, too!). I think you're looking for something not unlike the diamond <> operator in Perl, but for individual arguments rather than files containing arguments.
I think #David Hoelzer has the right idea: handle the three cases separately. For example, when processing command-line or file arguments, don't generate "Enter a value" prompts that you might print for interactive input. For command-line processing, getopt is a good place to start.
Now, a challenge to you: Wrap those three operations in a library and make it open-source so the rest of us can benefit! :)
Quite a few programs do care if they're invoked with keyboard input vs. file input, including the shell itself.
Let us take /bin/sh as our first example. If you call it directly, it starts an interactive shell, but if you pipe something into it, it starts as a non-interactive reading shell. The main difference between the two is if it is not interactive, it doesn't display the $ prompt. However just in case it really is interactive, it can be started with the -i option to make it assume its interactive when it would normally decide otherwise.
The magic involved here is isatty(); see man 3 isatty.
In addition, some programs like to receive keyboard input while processing redirected standard input. There are two generally favored ways of doing this; either opening and reading from /dev/tty or reading standard error, depending on context. Most stuff in an interactively started pipeline doesn't have standard error redirected, so this tends to work well (reading a redirected standard error yields an error immediately as the handle isn't open for read). If you want to make it potentially fully automatable, you read standard error, otherwise you read /dev/tty.

Is there a better way to analyze the key which was pressed without printing on the screen in C (eg. Arrow keys and Return)?

Code snippet (Full code here.) :
int Process (void)
{
for (;;)
{
unsigned char Char_Fore = getch();
if (Char_Fore == 0xE0)
{
unsigned char Char_Back = getch();
switch (Char_Back)
{
case 0x48:
Up();
break;
case 0x50:
Down();
break;
}
}
else if (Char_Fore == 0x0D)
Enter();
}
return 0;
}
This code can run properly on some machine, but some can't because of the getch() function.
getch() or _getch() is a function declared in conio.h , and the return value would vary if your keyboard is not IBM set 2, or the different compiler were chosen (not Mingw-gcc).
Is there a better way to analyze the key which was pressed in C without printing on the screen and without using a deprecated function like getch() or _getch() in console?
I know this isn't really an answer, but I don't have enough reputation to comment.
I recall using a header called termios.h, and using it I could turn off echoing of characters, now this was on a UNIX system, but I'd imagine there's a Windows equivalent.
Here's the pressanykey code with windows.h, perhaps you could adjust it to your needs?
http://www.cplusplus.com/forum/articles/7312/#msg33734
Check out curses or ncurses, sounds like kind of thing you want to be using.
PDCurses seems to be the Windows option - Is ncurses available for windows?

How would I scan phrases from the command line?

I am currently trying to get my program to work the way I want. I am currently at the point where I can open up any text file from the command line (an unlimited amount) and display them. I'd like to expand on this and have users enter phrases that format the displayed text. I have previously posted a similar question and I've gotten some great answers, but I cannot use getopt(). How else would it be possible to scan the command line for a "-w" and a number, so "-w5" and a "-s" with no number. Those are the only two things I'd like to be able to detect. I don't mind if statements, I was hoping for the shortest program in my friends, but at this point, I'd just like to get it done. Any ideas? Multiple if-statements was my friend's idea, I personally think this is unneeded, but if that's what I have to do... If anyone else has any ideas, that would be really useful. I just want my program to detect those two characters from the command line. I'm fairly new to C (I've only made a few programs), but I'm edger to learn and I have tried googling and trying this on my own, but being new to C, trying to find what I need through all the other text and jargon is difficult.
Anything will be useful, thanks.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int l = 1;
while(l != argc)
{
FILE *fp;
fp = fopen(argv[l], "rb");
l++;
if (fp != NULL)
{
int i = 1;
do
{
i = fgetc(fp);
printf("%c",i);
printf(" ");
}
while(i!=-1);
fclose(fp);
}
else
{
printf("Error.\n");
}
}
}
void scanningForWS(int argc, char **argv)
{
}
You should look at plan9's ARGBEGIN and ARGEND macros in their libc.h file (at the very end of the file), to see how it's done (for an example of its usage, see arg(3)).
Alernatively, you can check the suckless implementation of this mechanism, which is very nice (I have re-implemented a version of it which parses arguments even after incorrect flags have been found, but it's not published anywhere. I can publish it if you need that).
The command line arguments are in argv, and since argv is an array, the only way to find a specific element inside of it is to iterate through, checking each element until you get the one you want. If you don't want to write all that yourself, it looks like C has a method called 'lfind' in search.h that does this. Here is an example of how to use it. Hope that helps :3.
Also, the GNU documentation for it

getopt.h: Compiling Linux C-Code in Windows

I am trying to get a set of nine *.c files (and nine related *.h files) to compile under Windows.
The code was originally designed in Linux to take command line arguments using the standard GNU-Linux/C library "getopt.h". And that library does not apply to building the C-code in Windows.
I want to ignore what my code does right now and ask the following question. For those of you familiar with this C-library "getopt.h": will it be possible to build and run my code in Windows if it depends on POSIX-style command-line arguments? Or will I have to re-write the code to work for Windows, passing input files differently (and ditching the "getopt.h" dependency)?
getopt() is actually a really simple function. I made a github gist for it, code from here is below too
#include <string.h>
#include <stdio.h>
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(int nargc, char * const nargv[], const char *ostr)
{
static char *place = EMSG; /* option letter processing */
const char *oli; /* option letter list index */
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)printf("illegal option -- %c\n", optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)printf("option requires an argument -- %c\n", optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}
You are correct. getopt() is POSIX, not Windows, you would generally have to re-write all command-line argument parsing code.
Fortunately, there is a project, Xgetopt, that is meant for Windows/MFC classes.
http://www.codeproject.com/Articles/1940/XGetopt-A-Unix-compatible-getopt-for-MFC-and-Win32
If you can get this working in your project, it should save you a fair bit of coding and prevent you from having to rework all parsing.
Additionally, it comes with a nice GUI-enabled demo app that you should find helpful.
Good luck!
There is a possibilty to use code from MinGW runtime (by Todd C. Miller):
http://sourceforge.net/apps/trac/mingw-w64/browser/trunk/mingw-w64-crt/misc
I have created a small library with these files and CMake script (can generate a VS project):
https://github.com/alex85k/wingetopt
I did compile the getopt code under windows.
I did this as I wanted to explicilty use its command line parsing functionality in a windows (command line) app.
I successfully did this using VC2010.
As far as I remember I ran into no significant issues doing so.
getopt.c getoptl.c
if you just want getopt to be used in visual c++ without other dependences, I have port the getopt.c from latest gnu libc 2.12, with all new features.The only difference is you have to use TCHAR instead of char,but This is very common in windows.
simply download the source, make, copy libgetopt.lib and getopt.h getopt_int.h to your project.
you can also make it using CMakeList.txt in the root dir.
download the source from github
You might try looking into glib-2.0 as an alternative. It would be a bit large for just needing an option parser. The up side would be having access to all the other wonderful toys in the glib.
Just to be honest, I haven't tried getting this to work (I stick mostly to Linux), so YMMV.
Getting glib to work in windows: HowTo
Oh, you might explore using mingw for the build environment, and visual studio for your IDE.
Glib for Win32: HowTo
Anywho, hope this helps.
From my reading of the documentation the header file getopt.h is specific to the GNU C library as used with Linux (and Hurd). The getopt function itself has been standardised by POSIX which says it should be declared, along with optind optarg etc. in unistd.h
I can't try this on Visual Studio myself but it would be worth checking if unistd.h exists and declares this function as Visual Studio does provides some other POSIX functions.
If not, then I'd definitely grab an implementation of getopt rather than re-write the argument parsing to work without it. Getopt was written to make things easier for the programmer and more consistent for user of programs with command line arguments. Do check the license, though.
From what I remember of getopt.h, all it does is provide a handy parser for processing argv from your main function:
int main(int argc, char * argv[])
{
}
Windows console programs still have a main method, so you can simply loop through your argv array and parse the parameters yourself. e.g.
for ( int i = 1; i < argc; i++ )
{
if (!strcmp(argv[i], "-f"))
filename = argv[++i];
}
The getopt.h exists in git, I have download it and it works for me:
https://gist.github.com/ashelly/7776712

How can I write commands to the vxworks shell with a c program

If I wanted to run a shell command in linux with a c program, I would use
system("ls");
Is there a way I can accomplish this in Wind River vxworks?
I found the below example but I'm wondering do I need to include vxworks header files for this to work? I assume I do, but how do I figure out which one?
Example:
// This function runs a shell command and captures the output to the
// specified file
//
extern int consoleFd;
typedef unsigned int (*UINTFUNCPTR) ();
extern "C" int shellToFile(char * shellCmd, char * outputFile)
{
int rtn;
int STDFd;
int outFileFd;
outFileFd = creat( outputFile, O_RDWR);
printf("creat returned %x as a file desc\n",outFileFd);
if (outFileFd != -1)
{
STDFd=ioGlobalStdGet(STD_OUT);
ioGlobalStdSet(STD_OUT,outFileFd);
rtn=execute(shellCmd);
if (rtn !=0)
printf("execute returned %d \n",outFileFd);
ioGlobalStdSet(STD_OUT,STDFd);
}
close(outFileFd);
return (rtn);
}
I found the code segment below worked for me. For some reason changing the globalStdOut didn't work. Also the execute function did not work for me. But my setting the specific task out to my file, I was able to obtain the data I needed.
/* This function directs the output from the devs command into a new file*/
int devsToFile(const char * outputFile)
{
int stdTaskFd;
int outputFileFd;
outputFileFd = creat( outputFile, O_RDWR);
if (outputFileFd != ERROR)
{
stdTaskFd = ioTaskStdGet(0,1);
ioTaskStdSet(0,1,outputFileFd);
devs();
ioTaskStdSet(0,1,stdTaskFd);
close(outputFileFd);
return (OK);
}
else
return (ERROR);
}
If this is a target/kernel shell (i.e. running on the target itself), then remember that all the shell commands are simply translated to function calls.
Thus "ls" really is a call to ls(), which I believe is declared in dirLib.h
I think that the ExecCmd function is what you are looking for.
http://www.dholloway.com/vxworks/6.5/man/cat2/ExecCmd.shtml
As ever, read the documentation. ioLib.h is required for most of the functions used in that example, and stdio.h of course for printf().
As to the general question of whether you need to include any particular headers for any code to compile, you do need to declare all symbols used, and generally that means including appropriate headers. The compiler will soon tell you about any undefined symbols, either by warning or error (in C89/90 undefined functions are not an error, just a bad idea).

Resources