Example: Use of Predefined Macros in OS/2

version() is a routine from UnZip that prints as much compilation info as is known, based entirely on predefined compiler macros. Its output looks something like this:
Compiled with emx+gcc 2.5.8 for OS/2 2.x or 3.x (32-bit) on Jan 27 1995.
In the listing below, note that the Borland version numbers are probably wrong; they're based on the MS-DOS version of the compiler, which is why the debugging section is included at the end. The value of the __WATCOM__ variable is unknown, too. (Any and all information appreciated; please mail it to newt@pobox.com.)


OS/2 version() routine:

void version()
{
    int len;
#if defined(__IBMC__) || defined(__WATCOMC__) || defined(_MSC_VER)
    char buf[80];
#endif

    len = sprintf((char *)slide, "Compiled with %s%s for %s%s%s%s.\n\n",

#ifdef __GNUC__
#  ifdef __EMX__  /* __EMX__ is defined as "1" only (sigh) */
      "emx+gcc ", __VERSION__,
#  else
      "gcc/2 ", __VERSION__,
#  endif
#else
#ifdef __IBMC__
      "IBM C Set/2", (sprintf(buf, " %d.%02d", __IBMC__/100,__IBMC__%100), buf),
#else
#ifdef __WATCOMC__
      "Watcom C", (sprintf(buf, " (__WATCOMC__ = %d)", __WATCOMC__), buf),
#else
#ifdef __TURBOC__
#  ifdef __BORLANDC__
      "Borland C++",
#    if (__BORLANDC__ < 0x0200)
        " 1.0",
#    else
#    if (__BORLANDC__ == 0x0200)
        " 2.0",
#    else
#    if (__BORLANDC__ == 0x0400)
        " 3.0",
#    else
#    if (__BORLANDC__ == 0x0410)
        " 3.1",
#    else
#    if (__BORLANDC__ == 0x0452)
        " 4.0",
#    else                    /* these two are guesses based on DOS version */
#    if (__BORLANDC__ == 0x0460)
        " 4.5",
#    else
        " later than 4.5",
#    endif
#    endif
#    endif
#    endif
#    endif
#    endif
#  else
      "Turbo C",
#    if (__TURBOC__ >= 661)
       "++ 1.0 or later",
#    else
#    if (__TURBOC__ == 661)
       " 3.0?",
#    else
#    if (__TURBOC__ == 397)
       " 2.0",
#    else
       " 1.0 or 1.5?",
#    endif
#    endif
#    endif
#  endif
#else
#ifdef MSC
      "Microsoft C ",
#  ifdef _MSC_VER
      (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf),
#  else
      "5.1 or earlier",
#  endif
#else
      "unknown compiler", "",
#endif /* MSC */
#endif /* __TURBOC__ */
#endif /* __WATCOMC__ */
#endif /* __IBMC__ */
#endif /* __GNUC__ */

      "OS/2",

/* GRR:  does IBM C/2 identify itself as IBM rather than Microsoft? */
#if (defined(MSC) || (defined(__WATCOMC__) && !defined(__386__)))
#  if defined(M_I86HM) || defined(__HUGE__)
      " (16-bit, huge)",
#  else
#  if defined(M_I86LM) || defined(__LARGE__)
      " (16-bit, large)",
#  else
#  if defined(M_I86MM) || defined(__MEDIUM__)
      " (16-bit, medium)",
#  else
#  if defined(M_I86CM) || defined(__COMPACT__)
      " (16-bit, compact)",
#  else
#  if defined(M_I86SM) || defined(__SMALL__)
      " (16-bit, small)",
#  else
#  if defined(M_I86TM) || defined(__TINY__)
      " (16-bit, tiny)",
#  else
      " (16-bit)",
#  endif
#  endif
#  endif
#  endif
#  endif
#  endif
#else
      " 2.x or 3.x (32-bit)",
#endif

#ifdef __DATE__
      " on ", __DATE__
#else
      "", ""
#endif
    );

    message(slide, (ulg)len, 0);   /* MSC can't handle huge macro expansions */

    /* temporary debugging code for Borland compilers only */
#ifdef __TURBOC__
    Info(slide, 0, ((char *)slide, "\t(__TURBOC__ = 0x%04x = %d)\n", __TURBOC__,
      __TURBOC__));
#ifdef __BORLANDC__
    Info(slide, 0, ((char *)slide, "\t(__BORLANDC__ = 0x%04x)\n",__BORLANDC__));
#else
    Info(slide, 0, ((char *)slide, "\tdebug(__BORLANDC__ not defined)\n"));
#endif
#ifdef __TCPLUSPLUS__
    Info(slide, 0, ((char *)slide, "\t(__TCPLUSPLUS__ = 0x%04x)\n",
      __TCPLUSPLUS__));
#else
    Info(slide, 0, ((char *)slide, "\tdebug(__TCPLUSPLUS__ not defined)\n"));
#endif
#ifdef __BCPLUSPLUS__
    Info(slide, 0, ((char *)slide, "\t(__BCPLUSPLUS__ = 0x%04x)\n\n",
      __BCPLUSPLUS__));
#else
    Info(slide, 0, ((char *)slide, "\tdebug(__BCPLUSPLUS__ not defined)\n\n"));
#endif
#endif /* __TURBOC__ */

} /* end function version() */


Click here to see UnZip's multi-compiler OS/2 makefile.
Click here to return to the February 1995 Tip o' the Month.
Last modified 12 August 2000 by newt@pobox.com , you betcha.