[Coco] Microware C Compiler port
John W. Linville
linville at tuxdriver.com
Wed Jan 21 22:11:39 EST 2009
On Wed, Jan 21, 2009 at 06:37:51PM -0700, William Astle wrote:
> John W. Linville wrote:
> > On Thu, Jan 22, 2009 at 10:47:38AM +1000, Bob Devries wrote:
> >> Sent by private email, John.
> >
> > Well, thanks -- that resolved the linking problem. OTOH, the long
> > variables still got printed as zeroes. :-(
> >
> > John
>
> Correct me if I'm wrong, but how does this theory work:
>
> Assumption: long is twice as many bits as int and big-endian byte order,
> both of which should be valid here.
>
> Pretend we have a "long" value of 16. That would get onto the stack as
> the following string of bytes: 00, 00, 00, 10.
>
> Now printf() is looking for an integer so it only grabs 16 bits from the
> stack which gets the bytes: 00 00
>
> Magically, our "long" value turns into a 0.
Yes. FWIW it was not so much a question of the mechanics of why the
longs look like zeroes, but of why it wasn't interpreting the longs
as, well, longs. :-)
> The theory is that the format string being used is only cuing printf()
> to look for an int value but a long int is on the stack.
>
> I'm not overly familiar with the microware C compiler and the C library
> involved but usually "%ld" is used for long ints rather than "%D", is it
> not?
The "%D" was from the orginal Minix sources. The diffs I've shown
change "%6D" to "%6d".
I think integral types get promoted to int in most compilers, and on
nearly all the compilers I've used in the past 15+ years have int
that is the same size as long. So "%d" and "%ld" are the same on
those compilers, hence my overlooking the need to change that. :-)
As indicated in the other post, the combination of pflinit() and the
use of "%ld" seems to be working. :-)
John
P.S. Below is the current diff from the original Minix sources...
--- minix/commands/wc.c 1987-01-02 04:16:15.000000000 -0500
+++ wc.c 2009-01-21 21:55:34.000000000 -0500
@@ -1,9 +1,15 @@
/* wc - count lines, words and characters Author: David Messer */
-#include "stdio.h"
-#define isdigit(c) (c >= '0' && c <= '9)
+#include <stdio.h>
+#define isdigit(c) (c >= '0' && c <= '9')
#define isspace(c) (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r')
+std_err(str)
+char *str;
+{
+ fprintf(stderr, "%s", str);
+}
+
/*
*
* Usage: wc [-lwc] [names]
@@ -48,6 +54,9 @@ char *argv[];
int tflag, files;
int i;
+ /* Library initialization for printing long type. */
+ pflinit();
+
/* Get flags. */
files = argc - 1;
k = 1;
@@ -79,9 +88,9 @@ char *argv[];
/* Check to see if input comes from std input. */
if (k >= argc) {
count();
- if(lflag) printf(" %6D", lcount);
- if(wflag) printf(" %6D", wcount);
- if(cflag) printf(" %6D", ccount);
+ if(lflag) printf(" %6ld", lcount);
+ if(wflag) printf(" %6ld", wcount);
+ if(cflag) printf(" %6ld", ccount);
printf(" \n");
fflush(stdout);
exit(0);
@@ -99,18 +108,18 @@ char *argv[];
} else {
/* Next file has been opened as std input. */
count();
- if(lflag) printf(" %6D", lcount);
- if(wflag) printf(" %6D", wcount);
- if(cflag) printf(" %6D", ccount);
+ if(lflag) printf(" %6ld", lcount);
+ if(wflag) printf(" %6ld", wcount);
+ if(cflag) printf(" %6ld", ccount);
printf(" %s\n", argv[k]);
}
k++;
}
if(tflag) {
- if(lflag) printf(" %6D", ltotal);
- if(wflag) printf(" %6D", wtotal);
- if(cflag) printf(" %6D", ctotal);
+ if(lflag) printf(" %6ld", ltotal);
+ if(wflag) printf(" %6ld", wtotal);
+ if(cflag) printf(" %6ld", ctotal);
printf(" total\n");
}
--
John W. Linville Linux should be at the core
linville at tuxdriver.com of your literate lifestyle.
More information about the Coco
mailing list