| Summary: | c89(1) not POSIX compliant (-l lib) and messes up args | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Jens Schweikhardt <schweikh> |
| Component: | bin | Assignee: | Jens Schweikhardt <schweikh> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | CC: | schweikh |
| Priority: | Normal | ||
| Version: | 3.4-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->obrien David is our gcc maintainer. Responsible Changed From-To: obrien->schweikh I'm going to take care of that one; obrien agreed. State Changed From-To: open->closed Fixed in current. |
hello, world\n Problem 1: c89 can't deal with withespace in arguments: schweikh@hal9000:~ 0 $ c89 -o "hello world" hello.c cc: world: No such file or directory Problem 2: gcc does not understand "-l lib", i.e. the space between -l and the library name which POSIX.2 permits. c89 frobs the arg list anyway, so why not transform any "-l lib" to "-llib" to work around the gcc bug. (I submitted a bug report to the gcc maintainers more than a year ago; they answered "it's low priority" and so havn't gotten around to fixing it yet.) schweikh@hal9000:~ 0 $ c89 hello.c -l c Invalid operand usage: c89 [-c] [-D name[=value]] [...] [-E] [-g] [-I directory ...] [-L directory ...] [-o outfile] [-O] [-s] [-U name ...] operand ... Problem 3: The error messages mention cc instead of c89, which is confusing (see problem 1). Problem 4: A buglet in the man page: DESCRIPTION This is the name of the C language compiler as required by the IEEE Std1003.2 (``POSIX.2''). standard. | This dot is a bogon---------+ Fix: Shell programming is known for having problems with white space in arguments. So I decided to write an "almost one-liner" in C to fix problems 1 to 3 mentioned above. I've also written an itsy bitsy Makefile. Both files belong into /usr/src/usr.bin/c89. The BSD style consultants may want to frob a line or two in both of these. I spare you the diff for the man page. Regards, Jens -- Jens Schweikhardt http://www.schweikhardt.net/ SIGSIG -- signature too long (core dumped) ------------------------ PROG = c89 CFLAGS += -Wall MAN1 = c89.1 .include <bsd.prog.mk> ------------------------End of Makefile This is /usr/src/usr.bin/c89.c -- it replaces c89.sh: /* * This is the Posix.2 mandated C compiler. Basically, a hook to the * cc(1) command. Initial /bin/sh version by Joerg Wunsch. Rewritten * in C by Jens Schweikhardt to fix problems with embedded whitespace * in arguments and to make the "-l lib" identical to "-llib". POSIX * allows "-l lib" so the bug is actually with gcc barfing on it. I * already submitted a bug report to the gcc maintainers but they consider * it way low on their priority list. Once they fix it, remove the * 'else' part of the _CC_UNDERSTANDS_L_LIB conditional below. * * Copyright (c) 2000 by Jens Schweikhardt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define CC "/usr/bin/cc" /* The big kahuna doing the actual work */ static void usage (void); int main (int argc, char **argv) { int i, Argc = 0; char **Argv = malloc ((argc + 4) * sizeof *Argv); if (Argv == NULL) { perror ("c89: malloc"); return EXIT_FAILURE; } Argv[Argc++] = argv[0]; Argv[Argc++] = "-ansi"; Argv[Argc++] = "-pedantic"; Argv[Argc++] = "-D_ANSI_SOURCE"; while ((i = getopt (argc, argv, "cD:EgI:l:L:o:OsU:")) != -1) { if (i == '?') usage (); if (i == 'l') { if (argv[optind-1][0] == '-') { /* -llib */ optind -= 1; } else { /* -l lib */ optind -= 2; } break; /* because -llib or -l lib starts the operands */ } } if (argc == optind) { (void)fputs ("c89: missing operand\n", stderr); usage (); } /* XXX: remove this ifdef once gcc understands -l lib */ #ifdef _CC_UNDERSTANDS_L_LIB /* append argv[] to Argv[] */ for (i = 1; i <= argc; ++i) Argv[Argc++] = argv[i]; #else /* append argv[] to Argv[], transforming "-l lib" to "-llib" */ for (i = 1; i < argc; ++i) { if (argv[i] == NULL) continue; /* skip lib in -l lib */ if (strcmp (argv[i], "-l") == 0) { Argv[Argc] = malloc (3 + strlen (argv[i+1])); /* "-l" + argv[i+1] + \0 */ if (Argv[Argc] == NULL) { perror ("c89: malloc"); return EXIT_FAILURE; } (void)strcat (strcpy (Argv[Argc++], "-l"), argv[i+1]); argv[i+1] = NULL; /* skip in next iteration */ } else { Argv[Argc++] = argv[i]; } } Argv[Argc] = NULL; #endif /* _CC_UNDERSTANDS_L_LIB */ if (execv (CC, Argv) == -1) perror ("c89: execv: " CC); return EXIT_FAILURE; } static void usage (void) { (void)fputs ( "usage: c89 [-c] [-D name[=value]] [...] [-E] [-g] [-I directory ...]\n" "\t[-L directory ...] [-o outfile] [-O] [-s] [-U name ...] operand ...\n", stderr); exit (EXIT_FAILURE); } How-To-Repeat: c89 -o "hello world" hello.c c89 hello.c -l c