home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / portable.c < prev    next >
C/C++ Source or Header  |  1993-01-18  |  16KB  |  632 lines

  1. #if __TCPLUSPLUS__ || __STDC__
  2. # define __NSTDC__  1
  3. #endif
  4.  
  5. /* ---------------------------------------------------------------------- */
  6. /*                   Copyright (C) 1991 by Natuerlich!                    */
  7. /*                      This file is copyrighted!                         */
  8. /*                Refer to the documentation for details.                 */
  9. /* ---------------------------------------------------------------------- */
  10. /* compile and run this file TWICE                                   */
  11. /* Littleendian means  $12345678 -> 12 34 56 78                      */
  12. /* Bigendian    means  $12345678 -> 78 56 34 12                      */
  13. /* this is stylistically pretty outdated, yet helpful                */
  14. #define HAVEFUN   0     /* to test your compiler a bit more set to 1 */
  15.                         /* † <-- Error ??  (see EOF)                 */
  16. #define PHILOSOPHICAL_PROBLEM    1
  17.  
  18. #define IOCHECK   1
  19. #define SIGNAL    1        /* MS-C does not define SIGSEGV properly */
  20. #define STRICT    0
  21. #define STDIO     <stdio.h>
  22.  
  23. #if ! __NSTDC__
  24. # define signed
  25. #endif
  26.  
  27. #ifdef TOS
  28. # define OS               1
  29. #else
  30. # ifdef MSDOS
  31. #  define OS              2
  32. # else
  33. #  ifdef UNIX
  34. #   define OS             3
  35. #  else
  36. #   define OS            -1       /* unknown OS */
  37. #  endif
  38. # endif
  39. #endif
  40.  
  41. #ifdef TOS
  42. # undef TOS
  43. #endif
  44. #define TOS               1
  45. #ifdef MSDOS
  46. # undef MSDOS
  47. #endif
  48. #define MSDOS             2
  49. #ifdef UNIX
  50. # undef UNIX
  51. #endif
  52. #define UNIX              3
  53. #ifdef UNKNOWN
  54. # undef UNKNOWN
  55. #endif
  56. #define UNKNOWN          -1
  57.  
  58. #if OS == TOS
  59. # define Fkreate( p, m)    Fcreate( p, 0)
  60. # define Perror( s)
  61. # if __TURBOC__
  62. #   include <tos.h>
  63. #  else
  64. #   include <osbind.h>
  65. # endif
  66. # define OPEN_W      0
  67. # define OPEN_R      1
  68. # define OPEN_RW     2
  69. # define fbyte_t     long
  70. #else
  71. # include "xosbind.h"
  72. # if OS == MSDOS
  73. #  define Perror( s)
  74. #  ifdef OPEN_W
  75. #   undef OPEN_W
  76. #   undef OPEN_R
  77. #   undef OPEN_RW
  78. #  endif
  79. #  define OPEN_W     O_WRONLY
  80. #  define OPEN_R     O_RDONLY
  81. #  define OPEN_RW    O_RDWR
  82. #  define fbyte_t    long
  83. # endif
  84. # if OS == UNIX
  85. #  include <string.h>
  86. #  define Perror( s) perror( s)
  87. #  ifdef OPEN_W
  88. #   undef OPEN_W
  89. #   undef OPEN_R
  90. #   undef OPEN_RW
  91. #  endif
  92. #  define OPEN_W     O_WRONLY
  93. #  define OPEN_R     O_RDONLY
  94. #  define OPEN_RW    O_RDWR
  95. #  define fbyte_t    unsigned
  96. # endif
  97. # if OS == UNKNOWN
  98. #  define Perror( s)
  99. #  define OPEN_W     1
  100. #  define OPEN_R     0
  101. #  define OPEN_RW    2
  102. #  define fbyte_t    unsigned int
  103. # endif
  104. #endif
  105.  
  106. #include <stddef.h>
  107. #include STDIO          /* Error ? not too bad, reedit OSBINDs in NASM */
  108. #include <errno.h>
  109.  
  110.  
  111. #if __TURBOC__
  112. #  pragma warn -rvl     /* instead of very pretty                      */
  113. #  pragma warn -pia     /* Don't want those if( foo = bar) warnings    */
  114. #  pragma warn -pro     /* Also we don't care about prototypes anymore */
  115. #  pragma warn +sig     /* (used to, but that's all over now)          */
  116. #  pragma warn +use
  117. #  pragma warn +stv
  118. #  pragma warn +amb
  119. #  pragma warn +amp
  120. #endif
  121.  
  122. #if OS == TOS
  123. typedef long   off_t;
  124. #endif
  125.  
  126. #if SIGNAL
  127. # include <signal.h>
  128. # if OS == UNIX || OS == UNKNOWN || defined( __GNUC__)
  129. #  define SIGADR   SIGBUS
  130. # else
  131. #  if OS == MSDOS
  132. #   define SIGADR   SIGSEGV
  133. #  endif
  134. # endif
  135. #endif
  136.  
  137. #if __TURBOC__ && OS == TOS
  138. # include <ext.h>
  139. #endif
  140.  
  141. #if OS == MSDOS
  142. # include <fcntl.h>
  143. # include <sys\stat.h>
  144. #endif
  145.  
  146. #if OS == UNIX
  147. # include <unistd.h>
  148. #else
  149. # if OS == TOS || OS == MSDOS
  150. #  define SEEK_SET 0
  151. #  define SEEK_CUR 1
  152. #  define SEEK_END 2
  153. # endif
  154. #endif
  155.  
  156. #include "localdef.h"
  157.  
  158. /* ---------- FROM HERE ON EVERYTHING SHOULD WORK ---------- */
  159. #define byte   unsigned _BYTE
  160. #define word   unsigned _WORD
  161. #define lword  unsigned _LONG
  162. #define sbyte  signed   _BYTE
  163. #define sword  signed   _WORD
  164. #define slword signed   _LONG
  165.  
  166. #define WRITE( s)   fprintf( stderr, s)
  167.  
  168. /* HP cc can't take this (bastard compiler) so comment it out */
  169. /* Sun cc doesn't cope either */
  170.  
  171. /*
  172. #if __NSTDC__
  173. # undef FOO
  174. # define FOO 1
  175. # ifndef FOO
  176. #  error "Compiler can not handle #define/#undef properly"
  177. # endif
  178. # if ! FOO
  179. #  error "That should not have happened"
  180. # endif
  181. # ifdef BAR
  182. #  error "Throw your compiler away"
  183. # endif
  184. # undef FOO
  185. # ifdef FOO
  186. #  error "Compiler can not handle #define/#undef properly"
  187. # endif
  188. #endif
  189. */
  190.  
  191. /* till here */
  192.  
  193. #undef FOO
  194. #if __NSTDC__
  195. # define FOO( a, b, c)  a ## b ## c
  196. # define BAR( a, b, c)  a##b##c
  197. # define BAZ( a, b, c)  a/**/b/**/c
  198. #else
  199. # define FOO( a, b, c)  a/**/b/**/c
  200. #endif
  201.  
  202. FILE  *fp, *fopen();
  203. int   (*sdf)();
  204.  
  205.  
  206. #if ! HAVEFUN || __NSTDC__
  207. int   even;
  208. #else
  209.       even;          /* Just for fun. This is same as int even; and */
  210.                      /* shouldn't give an error                     */
  211. #endif
  212.  
  213. #if __NSTDC__
  214. # if SIGNAL
  215. void          dofoo( int);
  216. # endif
  217. extern void   exit( int);
  218. void          xcontinue( int);
  219. #else
  220. void          xcontinue();
  221. #endif
  222.  
  223.  
  224. #if SIGNAL
  225. void dofoo( foo)
  226. {
  227.    if( foo == SIGADR)         /* One less warning */
  228.       WRITE( "WORDs must lie on an even address\n");
  229.    else
  230.       WRITE( "FUN! Signal out of nowhere\n");
  231.    even++;
  232.    xcontinue(0);
  233. }
  234. #endif
  235.  
  236. #if ! HAVEFUN
  237. struct bar
  238. {
  239.    lword  a;
  240.    word   b;
  241.    byte  c;
  242. } fx = { 0x55AACC33L, 0x5AC3, 0x5A };
  243. #endif
  244.  
  245. word     x = 0x8000, y;
  246. word     i;
  247. byte     c = 0x80,
  248.          *p,
  249.          *q;
  250. lword    bar;
  251. sbyte    *foo;
  252.  
  253. void xcontinue( fd)
  254. {
  255. #if SIGNAL
  256.    if( ! fd)
  257.    {
  258.       if( ! even)
  259.       {
  260.          WRITE( "WORD access on odd address is OK!\n");
  261.          fprintf( fp, "#ifndef WORD_EVEN\n#define WORD_EVEN 0\n#endif\n\n");
  262.       }
  263.       else
  264.          fprintf( fp, "#ifndef WORD_EVEN\n#define WORD_EVEN 1\n#endif\n\n");
  265.       fclose( fp);
  266.  
  267.       if( signal( SIGADR, (void (*)()) sdf) == SIG_ERR)
  268.          WRITE( "More fun w/SIGNAL\n");
  269.    }
  270. #endif
  271. #if IOCHECK
  272. # if OS == MSDOS
  273.    _fmode = O_BINARY;
  274. # endif
  275.    {
  276. #if HAVEFUN
  277.       struct bar           /* Loser compilers will throw up on this. */
  278.       {                    /* try a static if you like here as well  */
  279.          lword  a;
  280.          word   b;
  281.          byte  c;
  282.       } fx = { 0x55AACC33L, 0x5AC3, 0x5A };
  283. #endif
  284.       byte  y;
  285.       lword  z;
  286.  
  287.       if( (fd = (int) Fkreate("foo.foo", 0644)) < 0)
  288.       {
  289.          WRITE( "Why did the creat fail ?\n");
  290.          Perror( "hint:");
  291.          goto fuckthis;
  292.       }
  293.       close( fd);
  294. fuckthis:
  295.       if( (fd = (int) Fopen("foo.foo", OPEN_W)) < 0)
  296.       {
  297.          WRITE( "Couldn't open foo.foo for writing.. WHY??\n");
  298.          Perror( "hint:");
  299.          goto fuckoff;
  300.       }
  301.       if( Fwrite( fd, (fbyte_t) sizeof( struct bar), &fx) !=
  302.           (fbyte_t) sizeof( struct bar))
  303.       {
  304.          WRITE( "Didn't write correct number of bytes. Mighty peculiar\n");
  305.          goto fuckoff;
  306.       }
  307.       close( fd);
  308.       if( (fd = (int) Fopen("foo.foo", OPEN_R)) < 0)
  309.       {
  310.          WRITE( "Couldn't open foo.foo for reading. Bastard machinery!!\n");
  311.          Perror( "hint:");
  312.          goto fuckoff;
  313.       }
  314.       lseek( fd, (long) 6, SEEK_SET);
  315.       if( Fread( fd, sizeof( byte), &y) != sizeof( byte))
  316.          WRITE( "lseek went the wrong way\n");
  317.       if( y != fx.c)
  318.          WRITE( "Probably lseek incompatibility or structs are\
  319.  higgledy-piggledy [FUN!]\n");
  320.  
  321.       lseek( fd, (long) -7, SEEK_CUR);
  322.       if( Fread( fd, sizeof( lword), &z) != sizeof( lword))
  323.          WRITE( "lseek incompatibility, can't index negatively\n");
  324.       if( z != fx.a)
  325.          WRITE( "Too strange to explain\n");
  326.       close( fd);
  327.    }
  328. #endif
  329. fuckoff:
  330.    bar = (lword) foo;
  331.    if( ! bar)
  332.       WRITE( "Strange conversion problems\n");
  333. #if SIGNAL
  334.    WRITE( "If portable crashes in 10 seconds it doesn't matter\n");
  335. # if __TURBOC__ && ! __PUREC__
  336.    WRITE("It mosty probably will, thanx to TURBO.C");
  337. # endif   
  338.    {
  339.       sword   i = 10;
  340.  
  341.       while( i--)
  342.       {
  343.          sleep( 1);
  344.          fputc( '.', stderr);
  345.          fflush( stderr);
  346.       }
  347.       fputc( '\n', stderr);
  348.    }
  349. #endif
  350.    exit( 0);
  351. }
  352.  
  353.  
  354. main( argc, argv)
  355. sbyte  **argv;
  356. {
  357.    fp  = stdout;    /* done her 'coz of some Amiga cc's lameness */
  358.    i   = x;
  359.    p   = (byte *) &i,
  360.    q   = (byte *) &x;
  361.    foo = (sbyte *) p;
  362.  
  363.    if( argc != 1)
  364.       if( ! (fp = fopen("localdef.h", "w")))
  365.       {
  366.          WRITE( "Sorry couldn't open \"localdef.h\"\n");
  367.          exit(1);
  368.       }
  369.  
  370.    sdf = (int (*)()) main;
  371.    if( (sword) i > 0 || (sbyte) c > 0)
  372.    {
  373.       WRITE( "ERROR: Machine/compiler doesn't use 2's complement\
  374. . Don't worry about this\n the first time.");
  375.    }
  376.  
  377.    for( i = 0; i < 256; i++)
  378.       if( (c = i) != i)
  379.          WRITE( "ERROR: Most probably chars are just 7 bits\n");
  380.  
  381.    c = i;
  382.    if( c)
  383.       WRITE( "ERROR: chars are longer than 8 bit (or abnormal)\n");
  384.  
  385.    y = 2;
  386.    i = 1;
  387.    x = FOO( y-,--i,-1);
  388.    if( x)
  389. #if ! __NSTDC__
  390.       fprintf( fp, "#ifndef CANCONCAT\n#define CANCONCAT 2\n#endif\n\n");
  391.    else
  392.       WRITE( "Comments can't be used to concatenate (impossible to port)\n");
  393. #else
  394.    {
  395.       WRITE( "Compiler can't concatenate token ## token\n");
  396.       y = 2;
  397.       i = 1;
  398.       x = BAR( y-,--i,-1);
  399.       if( x)
  400.       {
  401.          WRITE( "and can't concatenate text##text as well\n");
  402.          y = 2;
  403.          i = 1;
  404.          x = BAZ( y-,--i,-1);
  405.          if( x)
  406.             WRITE( "Even text/**/text doesn't work (impossible to port)\n");
  407.          else
  408.          {
  409.             WRITE( "but text/**/text does it <PHHHEWWWW!>\n");
  410.             fprintf( fp, "#ifndef CANCONCAT\n#define CANCONCAT 0\n#endif\n\n");
  411.          }
  412.       }
  413.       WRITE( "but text##text works <phew>\n");
  414.       fprintf( fp, "#ifndef CANCONCAT\n#define CANCONCAT 1\n#endif\n\n");
  415.    }
  416.    else
  417.    {
  418.       WRITE( "Compiler likes to concatenate with text ## text\n");
  419.       x = 3;
  420.       x = BAR( x-,--1,-1);
  421.       if( x)
  422.       {
  423.          WRITE( "But it can't concatenate text##text (which NASM uses)\n");
  424.          i = 1;
  425.          x = 3;
  426.          x = BAZ( x-,--i,-1);
  427.          if( x)
  428.          {
  429.             WRITE( "And text/**/text doesn't work either. You should set\n\
  430. -DSUN in the CFLAGS definition of \"makefile.nix\"\n");
  431.             putc( 7, stderr);
  432.             fflush( stderr);
  433.             sleep( 5);
  434.          }
  435.          else
  436.          {
  437.             WRITE( "But text/**/text does it <PHHHEWWWW!>\n");
  438.             fprintf( fp, "#ifndef CANCONCAT\n#define CANCONCAT 0\n#endif\n\n");
  439.          }
  440.       }
  441.       else
  442.       {
  443.          WRITE( "And text##text does work! GREAT!\n");
  444.          fprintf( fp, "#ifndef CANCONCAT\n#define CANCONCAT 1\n#endif\n\n");
  445.       }
  446.    }
  447. #endif
  448.  
  449.       /* If this kills your compiler, that's because it thinks that  */
  450.       /* casting a pointer doesn't make it an lvalue any more.       */
  451.       /* [which from my point of view is WRONG, but maybe according  */
  452.       /* to ANSI. &%$* ANSI as I might add.]                         */
  453. #if ! PHILOSOPHICAL_PROBLEM
  454.    {
  455.       char  d[4];
  456.       long  *c = (long *) d;
  457.  
  458.       *((char *) c)++ = 0;
  459.       if( ((char *) c - 1) != (void *) d)
  460.          WRITE( "Philosophical problem, Casting before ++ doesn't work\n");
  461.  
  462.       c = (long *) d;
  463.       *(char *)c++ = 0;
  464.       if( ((char *) c - sizeof( long)) != (char *) d)
  465.          WRITE( "Casting before ++ works, where it shouldn't have\n");
  466.    }
  467. #endif
  468.  
  469.    {
  470. #define BYTES  (sizeof( long) << 2)
  471.       char  x[ BYTES];
  472.       long  *p = (long *) x;
  473.       int   i;
  474.  
  475.       for( i = 0; i < BYTES; x[i++] = 0xFF);
  476.       *p = *p++ = *p++ = *p++ = 0;
  477.       for( i = 0; i < BYTES; i++)
  478.          if( x[i])
  479.          {
  480.             WRITE( "Compiler has it's own ideas where it should ++\n");
  481.             fprintf( fp, "#ifndef LATEPLUSPLUS\n#define LATEPLUSPLUS 1\n#endif\n\n");
  482.             WRITE( "Set LATEPLUSPLUS to 1\n");
  483.             goto fooble;
  484.          }
  485.       fprintf( fp, "#ifndef LATEPLUSPLUS\n#define LATEPLUSPLUS 0\n#endif\n\n");
  486.  
  487. fooble:
  488.       if( i == BYTES)
  489.       {
  490.          i = 1;
  491.          if( p++, i--)
  492.             WRITE( "Compiler does --,++ as expected\n");
  493.          else
  494.             WRITE( "Compiler does --,++ not quite as\
  495.  expected (but it doesn't matter for NASM)\n");
  496.       }
  497.    }
  498.  
  499.    {
  500.       unsigned long     x = ~0;
  501.       unsigned int      y = ~0;
  502.       unsigned short    z = ~0;
  503.       unsigned int      i, j, k, l;
  504.  
  505.       if( sizeof( size_t) == 2)
  506.       {
  507.          fprintf( stderr, "AHH!! PC detected. **BARF,RETCH**\n");
  508.          fprintf( fp, "#define FUCKING_STOOPID_KLUDGE_SHIT 1\n\n");
  509.       }
  510.       for( i = 0; x; x >>= 1, i++);
  511.       fprintf( stderr, "Unsigned longs have apparently %d bits\n", i);
  512.       for( j = 0; y; y >>= 1, j++);
  513.       fprintf( stderr, "Unsigned ints  have apparently %d bits\n", j);
  514.       for( k = 0; z; z >>= 1, k++);
  515.       fprintf( stderr, "Unsigned shorts have apparently %d bits\n", k);
  516.       y = (byte) -1;
  517.       for( l = 0; y; y >>= 1, l++);
  518.       fprintf( stderr, "Unsigned chars have apparently %d bits\n", l);
  519.       if( k == 16)
  520.          fprintf( fp, "#define _WORD short\n");
  521.       else
  522.          if( j == 16)
  523.             fprintf( fp, "#define _WORD int\n");
  524.          else
  525.             WRITE( "ERROR: No 16bit data type in sight (use bitfields??)\n");
  526.  
  527.       if( j == 32)
  528.          fprintf( fp, "#define _LONG  int\n");
  529.       else
  530.          if( i == 32)
  531.             fprintf( fp, "#define _LONG long\n");
  532.          else
  533.             WRITE( "ERROR: No 32bit data type in sight (use bitfields??)\n");
  534.  
  535.       if( l == 8)
  536.          fprintf( fp, "#define _BYTE char\n");
  537.       else
  538.          if( k == 8)
  539.             fprintf( fp, "#define _BYTE long\n");
  540.          else
  541.             WRITE( "ERROR: No 8bit data type in sight (use bitfields??)\n");
  542.    }
  543.  
  544.    WRITE( "If you got ERRORs above, or if the data types aren't set correctly\
  545.  yet\nthen diagnostics may be incorrect\n\n");
  546.  
  547. #ifdef __NSTDC__
  548. # if __NSTDC__
  549.    WRITE( "ANSI Compiler. ALL RIGHT!!\n");
  550. # else
  551.    WRITE( "ANSI Compiler ? Then why isn't __STDC__ 1 ?\n");
  552. # endif
  553. #endif
  554.    i = 0x1234;
  555.    p = (byte *) &i;
  556.    if( *p == 0x12 && p[1] == 0x34)
  557.    {
  558.       WRITE( "Computer is LITTLE-ENDIAN (Lilliput)\n");
  559.       fprintf( fp, "\n#ifndef LITTLEENDIAN\n#define LITTLEENDIAN 1\n#endif\n\n");
  560.    }
  561.    else
  562.       if( *p == 0x34 && p[1] == 0x12)
  563.       {
  564.          WRITE( "Computer is BIG-ENDIAN (Blefuscu)\n");
  565.          fprintf( fp, "\n#ifndef BIGENDIAN\n#define BIGENDIAN 1\n#endif\n\n");
  566.       }
  567.       else
  568.       {
  569.          WRITE( "Computer is weird (Brobdignang (sp?))\n");
  570.          fprintf( stderr, "I expected $12 $34 or $34 $12 but got\
  571.  $%02X $%02X\n",
  572.                     (word) *p, (word) p[1]);
  573.       }
  574.    i = -10000;
  575.    x = i;
  576.    if( *p != *q || p[1] != q[1])
  577.    {
  578.       WRITE( "Conversion takes place between int and unsigned\n");
  579.       x = (word) i;
  580.       if( *p != *q || p[1] != q[1])
  581.          WRITE( "Which can be suppressed with casting\n");
  582.    }
  583. #if SIGNAL
  584.    if( (sdf = (int (*)()) signal( SIGADR, dofoo)) == (int (*)()) SIG_ERR)
  585.    {
  586.       WRITE( "Signal could not be set\n");
  587.       goto over;
  588.    }
  589.    else
  590.    {
  591.       slword  i;
  592.       sword   *p = (sword *) ((char *) &i + 1);
  593.       register sword  x = (sword) 0x1234;
  594.  
  595.       *p = x;  /* TOS TURBO-C crashes here, cause they do signalling wrong */
  596.    }           /* therefore we call continue from dofoo                    */
  597. #endif
  598.    xcontinue( 0);
  599. #if SIGNAL
  600. over:
  601.    xcontinue( 1);
  602. #endif
  603. }
  604.  
  605. /* † Did the little cross (ASCII==187) produce an error ? Can your compiler
  606.      only grok 7bit ASCII ?  NO PROBLEM. You can filter out any ASCII
  607.      character over 127 w/o compromising source integrity.
  608.  
  609.      --- never tested nor compiled ---
  610.  
  611.      #include <stdio.h>
  612.      main( argc, argv)
  613.      char   *argv[];
  614.      {
  615.         register FILE   *fp, *fq;
  616.         register int    c;
  617.  
  618.         fp = fopen( argv[1], "r");
  619.         fq = fopen( argv[2], "w");
  620.  
  621.         while( (c = (int) getc( fp)) != EOF)
  622.            if( (char) c >= 0)
  623.               putc( c, fq);
  624.      }
  625.  
  626.      ACKs & REFs
  627.  
  628.      Danny Cohen   ON HOLY WARS AND A PLEA FOR PEACE    (IEN 137 ??)
  629.      Patrick Hayes COMPUTER ARCHITECTURE AND ORGANIZATION
  630.  */
  631.  
  632.