home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / cfuncs / icall.h < prev    next >
C/C++ Source or Header  |  2001-05-31  |  7KB  |  199 lines

  1. /*
  2. ############################################################################
  3. #
  4. #    File:     icall.h
  5. #
  6. #    Subject:  Definitions for external C functions
  7. #
  8. #    Author:   Gregg M. Townsend
  9. #
  10. #    Date:     May 31, 2001
  11. #
  12. ############################################################################
  13. #
  14. #   This file is in the public domain.
  15. #
  16. ############################################################################
  17. #
  18. #   These definitions assist in writing external C functions for use with
  19. #   Version 9 of Icon.
  20. #
  21. ############################################################################
  22. #   From Icon, loadfunc(libfile, funcname) loads a C function of the form
  23. #     int func(int argc, descriptor argv[])
  24. #   where "descriptor" is the structure type defined here.  The C
  25. #   function returns -1 to fail, 0 to succeed, or a positive integer
  26. #   to report an error.  Argv[1] through argv[argc] are the incoming
  27. #   arguments; the return value on success (or the offending value
  28. #   in case of error) is stored in argv[0].
  29. #   In the macro descriptions below, d is a descriptor value, typically
  30. #   a member of the argv array.  IMPORTANT: many macros assume that the
  31. #   C function's parameters are named "argc" and "argv" as noted above.
  32. #
  33. ############################################################################
  34. #   IconType(d) returns one of the characters {cfinprsCILRST} indicating
  35. #   the type of a value according to the key on page 247 of the Red Book.
  36. #   The character I indicates a large (multiprecision) integer.
  37. #   Only a few of these types (i, r, f, s) are easily manipulated in C.
  38. #   Given that the type has been verified, the following macros return
  39. #   the value of a descriptor in C terms:
  40. #     IntegerVal(d)    value of a integer (type 'i') as a C long
  41. #     RealVal(d)    value of a real (type 'r') as a C double
  42. #     FileVal(d)    value of a file (type 'f') as a C FILE pointer
  43. #     FileStat(d)    status field of a file
  44. #     StringVal(d)    value of a string (type 's') as a C char pointer
  45. #             (copied if necessary to add \0 for termination)
  46. #     StringAddr(d)    address of possibly unterminated string
  47. #     StringLen(d)    length of string
  48. #   These macros check the type of an argument, converting if necessary,
  49. #   and returning an error code if the argument is wrong:
  50. #     ArgInteger(i)        check that argv[i] is an integer
  51. #     ArgReal(i)        check that argv[i] is a real number
  52. #     ArgString(i)        check that argv[i] is a string
  53. #
  54. #   Caveats:
  55. #      Allocation failure is not detected.
  56. #
  57. ############################################################################
  58. #   These macros return from the C function back to Icon code:
  59. #     Return            return argv[0] (initially &null)
  60. #     RetArg(i)        return argv[i]
  61. #     RetNull()        return &null
  62. #     RetInteger(i)        return integer value i
  63. #     RetReal(v)        return real value v
  64. #     RetFile(fp,status,name)    return (newly opened) file
  65. #     RetString(s)        return null-terminated string s
  66. #     RetStringN(s, n)    return string s whose length is n
  67. #     RetAlcString(s, n)    return already-allocated string
  68. #     RetConstString(s)    return constant string s
  69. #     RetConstStringN(s, n)    return constant string s of length n
  70. #     Fail            return failure status
  71. #     Error(n)        return error code n
  72. #     ArgError(i,n)        return argv[i] as offending value for error n
  73. #
  74. ############################################################################
  75.  */
  76.  
  77. #include <stdio.h>
  78. #include <limits.h>
  79.  
  80. #if INT_MAX == 32767
  81. #define WordSize 16
  82. #elif LONG_MAX == 2147483647L
  83. #define WordSize 32
  84. #else
  85. #define WordSize 64
  86. #endif
  87.  
  88. #if WordSize <= 32
  89. #define F_Nqual    0x80000000        /* set if NOT string qualifier */
  90. #define F_Var      0x40000000        /* set if variable */
  91. #define F_Ptr      0x10000000        /* set if value field is pointer */
  92. #define F_Typecode 0x20000000        /* set if dword includes type code */
  93. #else
  94. #define F_Nqual    0x8000000000000000    /* set if NOT string qualifier */
  95. #define F_Var      0x4000000000000000    /* set if variable */
  96. #define F_Ptr      0x1000000000000000    /* set if value field is pointer */
  97. #define F_Typecode 0x2000000000000000    /* set if dword includes type code */
  98. #endif
  99.  
  100. #define D_Typecode    (F_Nqual | F_Typecode)
  101.  
  102. #define T_Null         0        /* null value */
  103. #define T_Integer     1        /* integer */
  104. #define T_Real         3        /* real number */
  105. #define T_File         5        /* file, including window */
  106.  
  107. #define D_Null        (T_Null     | D_Typecode)
  108. #define D_Integer    (T_Integer  | D_Typecode)
  109. #define D_Real        (T_Real     | D_Typecode | F_Ptr)
  110. #define D_File        (T_File     | D_Typecode | F_Ptr)
  111.  
  112. #define Fs_Read        0001        /* file open for reading */
  113. #define Fs_Write    0002        /* file open for writing */
  114. #define Fs_Pipe        0020        /* file is a [popen] pipe */
  115. #define Fs_Window    0400        /* file is a window */
  116.  
  117.  
  118. typedef long word;
  119. typedef struct { word dword, vword; } descriptor;
  120. typedef struct { word title; double rval; } realblock;
  121. typedef struct { word title; FILE *fp; word stat; descriptor fname; } fileblock;
  122.  
  123. char *alcstr(char *s, word len);
  124. realblock *alcreal(double v);
  125. fileblock *alcfile(FILE *fp, int stat, descriptor *name);
  126. double getdbl(descriptor *d);
  127.  
  128. extern descriptor nulldesc;        /* null descriptor */
  129.  
  130.  
  131. #define IconType(d) ((d).dword>=0 ? 's' : "niIrcfpRL.S.T.....C"[(d).dword&31])
  132.  
  133.  
  134. #define IntegerVal(d) ((d).vword)
  135.  
  136. #define RealVal(d) getdbl(&(d))
  137.  
  138. #define FileVal(d) (((fileblock *)((d).vword))->fp)
  139. #define FileStat(d) (((fileblock *)((d).vword))->stat)
  140.  
  141. #define StringAddr(d) ((char *)(d).vword)
  142. #define StringLen(d) ((d).dword)
  143.  
  144. #define StringVal(d) \
  145. (*(char*)((d).vword+(d).dword) ? cnv_c_str(&(d),&(d)) : 0, (char*)((d).vword))
  146.  
  147.  
  148. #define ArgInteger(i) do { if (argc < (i)) Error(101); \
  149. if (!cnv_int(&argv[i],&argv[i])) ArgError(i,101); } while (0)
  150.  
  151. #define ArgReal(i) do { if (argc < (i)) Error(102); \
  152. if (!cnv_real(&argv[i],&argv[i])) ArgError(i,102); } while (0)
  153.  
  154. #define ArgString(i) do { if (argc < (i)) Error(103); \
  155. if (!cnv_str(&argv[i],&argv[i])) ArgError(i,103); } while (0)
  156.  
  157.  
  158. #define RetArg(i) return (argv[0] = argv[i], 0)
  159.  
  160. #define RetNull() return (argv->dword = D_Null, argv->vword = 0)
  161.  
  162. #define RetInteger(i) return (argv->dword = D_Integer, argv->vword = i, 0)
  163.  
  164. #define RetReal(v) return (argv->dword=D_Real, argv->vword=(word)alcreal(v), 0)
  165.  
  166. #define RetFile(fp,stat,name) \
  167. do { descriptor dd; dd.vword = (word)alcstr(name, dd.dword = strlen(name)); \
  168.    argv->dword = D_File; argv->vword = (word)alcfile(fp, stat, &dd); \
  169.    return 0; } while (0)
  170.  
  171. #define RetString(s) \
  172. do { word n = strlen(s); \
  173. argv->dword = n; argv->vword = (word)alcstr(s,n); return 0; } while (0)
  174.  
  175. #define RetStringN(s,n) \
  176. do { argv->dword = n; argv->vword = (word)alcstr(s,n); return 0; } while (0)
  177.  
  178. #define RetConstString(s) return (argv->dword=strlen(s), argv->vword=(word)s, 0)
  179.  
  180. #define RetConstStringN(s,n) return (argv->dword=n, argv->vword=(word)s, 0)
  181.  
  182. #define RetAlcString(s,n) return (argv->dword=n, argv->vword=(word)s, 0)
  183.  
  184.  
  185. #define Fail return -1
  186. #define Return return 0
  187. #define Error(n) return n
  188. #define ArgError(i,n) return (argv[0] = argv[i], n)
  189.