Which C compiler: TC or MS? (200+ lines)

Mark W. Schumann catfood at NCoast.ORG
Thu Oct 4 01:47:52 AEST 1990


In article <151565 at felix.UUCP> asylvain at felix.UUCP (Alvin E. Sylvain) writes:
>>Money is not an issue here, support,
>>and functionality is.                            [...]
>In all the fuss over C compilers for the PC, not much mention is made
>of a small, inexpensive C compiler from a company called MIX, called
>Power C.  Someone besides me must have tried it, and have an opinion!
>I find it *quite* satisfactory.
>If you are willing to shell out a few hundred bucks for a C compiler,
>another 20 won't hurt much.  You might as well try out the cheap one
>before you shell out the BIG bucks.  If you don't like it, consider
>yourself to have bought an *excellent* manual and C tutorial.
>SUPPORT: I reported a bug in an earlier version; they sent me a library
>source code patch for it, since I had purchased the library source code.
 
   I've posted in the past my complaints about some cryptic error
   messages coming out of the Power C compiler/optimizer phase.
   Here's an example of what I'm talking about.  Perhaps someone
   out there in net-land can help me out.  (Or we could establish
   alt.powerc to beat the subject to death?)  I do have to point
   out again that Mix Software's tech people don't seem to be very
   helpful on questions like these.  I am posting this to get some
   assistance with the problem, but also in case it proves unfixable
   to warn others about what can happen if you push Power C too hard.
 
   The situation is this: I am working on an IBM PC-compatible
   screen I/O library, of course using direct screen read/write
   when possible.  To avoid CGA chromablizzard problems, I intend
   to use two sets of read/write functions.  For CGA monitors,
   the functions are called $CgaPeek() and $CgaPoke(); otherwise, I
   want to use $MonoPeek() and $MonoPoke().  To call those functions,
   I use function pointers $Peek() and $Poke(), which are set to the
   CGA functions (when necessary) or the Mono functions.  I plan
   to test for a CGA monitor by calling function $isCGA(), but at
   this point it is a stub function that always returns zero.
 
   My library consists of three source files.  DAZZPRIM.C contains
   the source for the "primitive" functions, whose names begin with
   the dollar sign and which should be called only from functions
   in this library.  DAZZ.C contains higher level functions such as
   clear(), say(), set_attr(), and so on.  Finally, I'm implementing
   an analogue of the Clipper achoice() function in file ACHOICE.C.
 
   I am using a Power C project file named DAZZ.PRJ to compile each
   source file and combine the objects into the library DAZZLIB.MIX.
   Here's what Power C gives me:
 
------------------------------------------------------------------------------
 
D:\DAZZ> PC DAZZ
Power C - Version 2.0.0
(C) Copyright 1989 by Mix Software
Project: dazz.PRJ
No errors detected           <<< compiling dazzprim.c >>>
No errors detected           <<<           dazz.c     >>>
No errors detected           <<<           achoice.c  >>>
New library: dazzlib.MIX
 3027 lines compiled
Optimizing ...
$isCGA       Invalid object tag      <<< What's this??? >>>
achoice  Errors detected
   34 functions optimized in 3 files
 
D:\DAZZ>
 
------------------------------------------------------------------------------
 
   My question for the Mix people, and now for you, is:
 
      1. What's an object tag?
      2. Why is it invalid?
      3. What can I do to fix it?  (If I have to modify
          the source, that's okay.)
 
   The source of ACHOICE.C, with blank lines omitted, is as follows:
 
------------------------------------------------------------------------------
 
#include "dazz.h"
#include <bios.h>
#include <conio.h>
#include <stdarg.h>
#include <stddef.h>
char userkeys[] = {ESCAPE, LEFT, RIGHT, HOME, END, ENTER, 0};
/*=======================================================================
achoice--
  Clipper-style Achoice() function.
=======================================================================*/
int achoice (
    int win_top,
    int win_lft,
    int win_btm,
    int win_rgt,                  /* Window top-bottom-left-right */
    char *options[],              /* Null-terminated string array */
    unsigned int argflag, ... )   /* 1 = toggles follow; 2 = userfunc */
{
int win_hgt, win_wid;
int start = 0, current = 0, m = 0;
register int k;
unsigned count;
INDICATOR flag = repaint;
ATTRIB cursor_color = REVERSED;
ATTRIB normal_color = $GetAttrib();
/* Optional arguments */
va_list argptr;
int *toggles;
USERFUNC UserFunc;
char s[80];
toggles = NULL;
UserFunc = NULL;
  /* Get the optional arguments */
  va_start (argptr, options);
  if (argflag & 0x01) toggles = va_arg (argptr, int);
  if (argflag & 0x02) UserFunc = va_arg (argptr, USERFUNC);
  /* Count the array elements */
  for (count = 0; options[count] != NULL; count++);
  /* Get window height and width */
  win_hgt = win_btm - win_top + 1;
  win_wid = win_rgt - win_lft + 1;
  while (flag == none || flag == repaint) {
    if (flag == repaint) {
      /* bang top of window */
      if (current < start) {
        start = current; /* cursor to top of window */
        if (UserFunc != NULL)
          flag = $UserFunc (UserFunc, 1, options, &current, start, k);
        }
      /* bang bottom of window */
      else if (current >= start + win_hgt - 1) {
        start = current - win_hgt + 1;
        if (UserFunc != NULL)
          flag = $UserFunc (UserFunc, 2, options, &current, start, k);
        }
        { register int i;
      /* repaint the window */
      for (i = 0; i < win_hgt; i++) {
        if (options[i] == NULL) break;
          clear_attr (win_top + i, win_lft, win_top + i,
             win_rgt, global_colors.standard);
          say_attr (win_top + i, win_lft, options[start+i],
           (toggles == NULL || toggles[start+i] ?
           global_colors.standard : global_colors.unselected));
        flag = none;
        } }
    highlight (current - start + win_top, win_lft, win_wid);
    /* Keyboard is idle for a sec */
    flag = $UserFunc (UserFunc, 0, options, &current, start, k);
    k = $Inkey();
    if (UserFunc == NULL && isalpha (k))
      m = $ScanChoice (options, current, k);
    else if (UserFunc == NULL)
      switch (k) {
        case UP:        m--;    break;
        case DOWN:      m++;    break;
        case HOME:
        /* case CPAGEUP: */  m = 0;    break;
        case END:
        /* case CPAGEDN: */  m = count - 1;  break;
        case PAGEUP:    m -= win_hgt;  break;
        case PAGEDOWN:  m += win_hgt;  break;
        case ENTER:     flag = chosen;  break;
        case ESCAPE:
        case LEFT:
        case RIGHT:     flag = quit;  break;
        }
    /* Keystroke exception: User-function called with `3' argument */
    else if (isalpha (k) || (strchr (userkeys, k) != NULL))
      flag = $UserFunc (UserFunc, 3, options, &current, start, k);
    else switch (k) {
      case UP:
        m--;
        break;
      case DOWN:
        m++;
        break;
      case PAGEUP:
        m -= win_hgt;
        break;
      case PAGEDOWN:
        m += win_hgt;
        break;
      }
    if ((flag == none) || (flag == repaint)) {
      /* My submission to the obfuscated code contest...           */
      /* Purpose: 1) flag set to repaint if outside current window */
      /*          2) m set within range 0 to count -1 inclusive    */
      flag = (m <= start || m >= start + win_hgt - 1) ? repaint : none;
      m = (m < 0) ? 0 : (m >= count) ? count - 1 : m;
      /* Now unhighlight what was formerly the `current' item. */
      if (m != current) {
        unhighlight (current - start + win_top, win_lft, win_wid);
        current = m;
        }
      m = current;
      }
    }
  switch (flag) {
    case chosen:  return current;    break;
    case quit:    return -1;         break;
    case error:   return -1;         break;
    default:      return -1;         break;
    }
  }
}
/*=======================================================================*/
INDICATOR $UserFunc (
      int (* UserFunc)(),
      int status,
      char **array,
      int *current,
      int start,
      int lastkey )
{
  if (UserFunc == NULL)
     return none;
  else {
    switch (UserFunc (1, current, current - start)) {
      case 0:  /* abort selection, returning zero */
        return quit;
        break;
      case 1:  /* return current value */
        return chosen;
        break;
      case 2:  /* continue selection process */
        return none;
        break;
      case 3:  /* go to the next item whose first        */
        /* character matches the last key pressed */
        current = $ScanChoice (array, current, lastkey);
        return none;
        break;
      default:  /* error: user function should return only */
            /* zero, one, two, or three!               */
        return error;
      }
    }
  }
/*=======================================================================*/
int $ScanChoice (char **array, int begin_point, int keyvalue)
{
int x;
  x = begin_point;
  do {
    x++;
    if (array[x] == NULL) x = 0;    
    if (toupper (array[x][0]) == toupper (keyvalue))
      return x;
    } while (x != begin_point);
  return begin_point;
  }
/*=======================================================================*/
 
 
   That's all.  If anyone can help with this (which sure looks like
   a compiler bug), please post or e-mail me.  Thanks to all.
 
----------------------------------------------------------------
 Mark W. Schumann\3111 Mapledale Avenue\Cleveland OH 44109 USA
 UUCP: ...!mailrus!usenet.ins.cwru.edu!ncoast!catfood
 Internet: catfood at ncoast.org
 "The AS/400 is for people who move their lips when they type."
----------------------------------------------------------------
-- 
============================================================
Mark W. Schumann  3111 Mapledale Avenue, Cleveland 44109 USA
Domain: catfood at ncoast.org
UseNet: ...usenet.ins.cwru.edu!ncoast!catfood
============================================================



More information about the Comp.lang.c mailing list