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
Related
When I use readline function and type control-D to tell my program it reached EOF, ^D is echoed in the terminal.
I would like to remove it or to replace it by another message.
I tried stty -echoctl command but it doesn't work.
I'm using ZSH with Oh My Zsh and iTerm2.
# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<unistd.h>
# include<sys/types.h>
# include<sys/wait.h>
# include<readline/readline.h>
# include<readline/history.h>
int input(void)
{
char *buf;
buf = readline("Please write the argument:\n");
if (buf == NULL)
{
printf("Quitting the program\n");
exit(0);
}
return (0);
}
int main()
{
while (1)
{
if(!input())
continue;
}
return (0);
}
I don't know what I can try now, I checked lots of Stack Overflow threads and didn't find anything.
Although it looks like you are using the readline library, you're actually using a compatibility layer built on top of the BSD libedit library, which is what is provided by default by Mac OS. So you can expect some things to work a bit differently.
Unfortunately, libedit is not well-documented. It appears to be possible to modify the binding of the Ctrl-D key by creating a file name .editrc in your home directory, and inserting the line:
bind ^D ed-end-of-file
That will apply the change to all applications which use the libedit library, which may be a bit drastic. To make it apply only to your program, you can insert the line:
rl_readline_name = "progname";
at the beginning of your program, before the first time you call readline. Change progname to whatever you want to use as a tag for your program. Then you can change the editrc command to the following (using the same tag for progname):
progname:bind ^D ed-end-of-file
At least, that worked on an Ubuntu system.
Another option would be to just install GNU readline on your Mac. According to the GNU readline home page:
MacOS X users may obtain MacOS X packages for readline-8.0 from MacPorts, readline-7.0 from Fink, or readline-8.0 from Homebrew.
Then you'll have to make sure you build your program with GNU readline instead of the libedit shim.
Doing that will make also make the prompt work the way it reads (i.e., the prompt includes a newline). I don't know if that's what you want, though.
What you need to do is basically to have a function that reads AND manually print every character so that you can intercept characters that shouldn't be printed. Here is an idea to get started:
int ch;
char buf[SIZE] = {0};
char *p = buf;
while(1) {
ch = getchar();
if(ch == EOF) {
p[1] = 0;
break;
}
putchar(ch);
*p++ = ch;
}
You would probably like to treat backspace '\b' in a special way. Like decrementing p, but watch out for going out of bounds.
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?
Is it possible to make command like arguments like below?
./exe FROM_FILE=true
Here in this case, how I expect in the program is, when FROM_FILE value is true, I wil take data from file and if false, I can take standard values. The other alternatives I find for the purpose is to use
-options
Simply pass arguments. But in this case I have to worry about the order of arguments.
This one just came to mind when doing a makefile.
$>cat makefile
exe :
echo ${FROM_FILE}
$>make FROM_FILE=true
echo true
true
$>
You can do
FROM_FILE=true ./exe
and then read the FROM_FILE environment variable from inside the app with the environ pointer or getenv(). See http://linux.die.net/man/7/environ
Of course it is possible! Something like this (untested):
int main(int argc, char **argv)
{
int FROM_FILE = 0;
const char *FROM_FILE_key = "FROM_FILE";
int i;
/* Iterate through all the arguments. */
for (i = 1; i < argc; ++i)
{
/* Look for the '='. If not there, skip this argument. */
char *eq = strchr(argv[i], '=');
if (!eq)
continue;
/* Compare the key. If not what we want, skip it. */
if (strncmp(argv[i], FROM_FILE_key, strlen(FROM_FILE_key)) != 0)
continue;
/* Parse the value. You probably want to make this more flexible
(true, 1, yes, y...)*/
if (strcmp(eq+1, "true") == 0)
FROM_FILE = 1;
}
printf("FROM_FILE=%s", FROM_FILE? "true" : "false");
}
Possible? Well, since make apparently does it (I haven't tried it myself), it's obviously possible. It might trip up some people because it's certainly an unusual syntax, though.
What you'd want to do then is probably to iterate over argv[], find any parameters on the form something=something, and do your magic. Maybe even zero them out after you are done with them, and then do something more normal like handing over the grunt work to getopt or a similar library.
One thing to consider, especially if you want this to be generic, is what to do when someone passes a file name to your application that contains a =, expecting that file name to be opened, processed or whatever it is your application does for a living.
EDIT: The more I think about it, the less a good idea it seems to break with common command line interface conventions. maybe you should read this: http://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html
have you tried environment variables?
you can do
FROM_FILE=true ./exe
and in exe.c:
[...]
char *file = getenv("FROM_FILE");
if (file == NULL)
*file = DEFAULT;
[...]
alternatively, for a more GNU-ish approach to command line interfaces, have a look at getopt, or argp. (http://www.gnu.org/software/libc/manual/html_node/Parsing-Program-Arguments.html#Parsing-Program-Arguments)
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).
I need to write a little program in C that parses a string. I wanted to use regular expressions since I've been using them for years, but I have no idea how to do that in C. I can't find any straight forward examples (i.e., "use this library", "this is the methodology").
Can someone give me a simple example?
You can use PCRE:
The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5. PCRE has its own native API, as well as a set of wrapper functions that correspond to the POSIX regular expression API. The PCRE library is free, even for building commercial software.
See pcredemo.c for a PCRE example.
If you cannot use PCRE, POSIX regular expression support is probably available on your system (as #tinkertim pointed out). For Windows, you can use the gnuwin Regex for Windows package.
The regcomp documentation includes the following example:
#include <regex.h>
/*
* Match string against the extended regular expression in
* pattern, treating errors as no match.
*
* Return 1 for match, 0 for no match.
*/
int
match(const char *string, char *pattern)
{
int status;
regex_t re;
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) {
return(0); /* Report error. */
}
status = regexec(&re, string, (size_t) 0, NULL, 0);
regfree(&re);
if (status != 0) {
return(0); /* Report error. */
}
return(1);
}
If forced into POSIX only (no pcre), here's a tidbit of fall back:
#include <regex.h>
#include <stdbool.h>
bool reg_matches(const char *str, const char *pattern)
{
regex_t re;
int ret;
if (regcomp(&re, pattern, REG_EXTENDED) != 0)
return false;
ret = regexec(&re, str, (size_t) 0, NULL, 0);
regfree(&re);
if (ret == 0)
return true;
return false;
}
You might call it like this:
int main(void)
{
static const char *pattern = "/foo/[0-9]+$";
/* Going to return 1 always, since pattern wants the last part of the
* path to be an unsigned integer */
if (! reg_matches("/foo/abc", pattern))
return 1;
return 0;
}
I highly recommend making use of PCRE if its available. But, its nice to check for it and have some sort of fall back.
I pulled the snippets from a project currently in my editor. Its just a very basic example, but gives you types and functions to look up should you need them. This answer more or less augments Sinan's answer.
Another option besides a native C library is to use an interface to another language like Python or Perl. Not having to deal with C's string handling, and the better language support for regex's should make things much easier for you. You can also use a tool like SWIG to generate wrappers for calling the code from C.