[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