home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / p / p024 / 12.img / ADS3.LIB / FACT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-17  |  7.5 KB  |  260 lines

  1. /* Next available MSG number is   8 */
  2.  
  3. /*    FACT.C
  4.       ¬⌐┼v (C) 1990-1992  Autodesk ñ╜Ñq
  5.  
  6.       Ñ╗│n┼ΘºK╢O¿╤▒z╢iªµÑ⌠ª≤Ñ╬│~╗▌¿D¬║½■¿⌐íB¡╫º∩ñ╬╡oªµ, ª²¼O░╚╜╨┐φ┤`ñU¡z
  7.       ¡∞½h :
  8.  
  9.       1)  ñWªC¬║¬⌐┼v│qºi░╚╗▌ÑX▓{ªb¿Cñ@Ñ≈½■¿⌐∙╪íC
  10.       2)  ¼█├÷¬║╗í⌐·ñσÑ≤ñ]Ñ▓╢╖⌐·╕ⁿ¬⌐┼v│qºiñ╬Ñ╗╢╡│\Ñi│qºiíC
  11.  
  12.       Ñ╗│n┼Θ╢╚┤ú¿╤º@¼░└│Ñ╬ñW¬║░╤ª╥, ª╙Ñ╝┴n⌐·⌐╬┴⌠ºtÑ⌠ª≤½O├╥; ╣∩⌐≤Ñ⌠ª≤»S«φ
  13.       Ñ╬│~ñº╛A║┘⌐╩, ÑHñ╬░╙╖~╛P░Γ⌐╥┴⌠ºtÑX¿π¬║½O├╥, ªbª╣ñ@╖ºñ⌐ÑHº_╗{íC
  14.  
  15.  
  16.  
  17.       DESCRIPTION:
  18.  
  19.       ADS FACTORIAL application - 3/14/90
  20.       Fancier function tables, and add sqr for illustration - 7/21/90
  21.  
  22. */
  23.  
  24. #include  <stdio.h>
  25. #include  "adslib.h"
  26.  
  27. /* Utility definition to get an  array's  element  count  (at  compile
  28.    time).   For  example:
  29.  
  30.        int  arr[] = {1,2,3,4,5};
  31.        ...
  32.        printf("%d", ELEMENTS(arr));
  33.  
  34.    would print a five.  ELEMENTS("abc") can also be used to  tell  how
  35.    many  bytes are in a string constant INCLUDING THE TRAILING NULL. */
  36.  
  37. #define ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
  38.  
  39.  
  40. /* All the functions that we'll define will be listed in a single table,
  41.    together with the internal function that we call to handle each.  The
  42.    functions all take a single argument (the resbuf that has the
  43.    arguments) and return an integer (RTNORM or RTERROR for good or bad
  44.    status).  */
  45.  
  46.  
  47. /* First, define the structure of the table: a string giving the AutoCAD name
  48.    of the function, and a pointer to a function returning type int. */
  49. struct func_entry { char *func_name; int (*func) _((struct resbuf *)); };
  50.  
  51. /* Here we declare the functions that handle the calls; at the moment there are
  52.    two of them. */
  53. int fact       _((struct resbuf *rb));
  54. int squareroot _((struct resbuf *rb));
  55.  
  56. /* Here we define the array of function names and handlers. */
  57. static struct func_entry func_table[] = { {/*MSG0*/"fact", fact},
  58.                                           {/*MSG0*/"sqr", squareroot},
  59.                                         };
  60. /* To add more functions to this table, just put them in the list, after
  61.    declaring the function names.  Note that in standard C it's all right to
  62.    have a superfluous comma after the last item.  */
  63.  
  64.  
  65. /* The code from here to the end of dofun() is UNCHANGED when you add or delete
  66.    functions. */
  67.  
  68.  
  69. /*  Declarations of other local functions  */
  70. void     main       _((int, char **));
  71. int      dofun      _((void));
  72. int      funcload   _((void));
  73. ads_real rfact      _((int x));
  74. ads_real rsqr       _((ads_real x));
  75.  
  76.  
  77. /*-----------------------------------------------------------------------*/
  78. /* MAIN - the main routine */
  79.  
  80. void main(argc,argv)
  81.   int argc;
  82.   char *argv[];
  83. {
  84.     short scode = RSRSLT;             /* Normal result code (default) */
  85.     int stat;
  86.  
  87.     ads_init(argc, argv);             /* Open communication with AutoLISP */
  88.  
  89.     for ( ;; ) {                      /* Request/Result loop */
  90.  
  91.         if ((stat = ads_link(scode)) < 0) {
  92.             printf(/*MSG1*/"FACT: Ñ╤ ads_link() ╢╟ª^¬║ñú¿╬¬¼║A = %d\n", stat);
  93.             fflush(stdout);
  94.             exit(1);
  95.         }
  96.  
  97.         scode = RSRSLT;               /* Reset result code */
  98.  
  99.         switch (stat) {
  100.  
  101.         case RQXLOAD:                 /* Load & define functions */
  102.             scode = funcload() == RTNORM ? RSRSLT : RSERR;
  103.             break;
  104.  
  105.         case RQSUBR:                  /* Handle external function requests */
  106.             scode = dofun() == RTNORM ? RSRSLT : RSERR;
  107.             break;
  108.  
  109.         default:
  110.             break;
  111.         }
  112.     }
  113. }
  114.  
  115. /*-----------------------------------------------------------------------*/
  116. /* FUNCLOAD  --  Define this application's external functions.  Return
  117.                  RTERROR on error, else RTNORM.                   */
  118.  
  119. static int funcload()
  120. {
  121.     int i;
  122.  
  123.     for (i = 0; i < ELEMENTS(func_table); i++) {
  124.         if (!ads_defun(func_table[i].func_name, i))
  125.             return RTERROR;
  126.     }
  127.     return RTNORM;
  128. }
  129.  
  130. /*-----------------------------------------------------------------------*/
  131. /* DOFUN -- Execute external function (called upon an RQSUBR request).
  132.             Return value from the function executed, RTNORM or RTERROR. */
  133.  
  134. static int dofun()
  135. {
  136.     struct resbuf *rb;
  137.     int val;
  138.  
  139.     /* Get the function code and check that it's within range.
  140.        (It can't fail to be, but paranoia doesn't hurt.) */
  141.     if ((val = ads_getfuncode()) < 0 || val >= ELEMENTS(func_table)) {
  142.         ads_fail(/*MSG2*/"▒╡ª¼¿∞ñúªsªb¬║íuÑ\134»α¿τªí╜XívíC");
  143.         return RTERROR;
  144.     }
  145.  
  146.     /* Fetch the arguments, if any. */
  147.     rb = ads_getargs();
  148.  
  149.     /* Call the handler and return its success-failure status. */
  150.     val = (*func_table[val].func)(rb);
  151.     ads_relrb(rb);
  152.     return val;
  153. }
  154.  
  155.  
  156. /* The code from the beginning of main() to here is UNCHANGED when you add or
  157.    delete functions.  */
  158.  
  159. /*-----------------------------------------------------------------------*/
  160. /* FACT -- First set up the argument, then call the factorial function */
  161. static int
  162. fact(rb)
  163.   struct resbuf *rb;
  164. {
  165.     int x;
  166.  
  167.     if (rb == NULL)
  168.         return RTERROR;
  169.  
  170.     if (rb->restype == RTSHORT) {
  171.         x = rb->resval.rint;          /* Save in local variable */
  172.     } else {
  173.         ads_fail(/*MSG3*/"ñ▐╝╞└│¼░íu╛π╝╞ívíC");
  174.         return RTERROR;
  175.     }
  176.  
  177.     if (x < 0) {                      /* Check argument range */
  178.         ads_fail(/*MSG4*/"ñ▐╝╞└│¼░íuÑ┐¡╚ívíC");
  179.         return RTERROR;
  180.     } else if (x > 170) {             /* Avoid floating-point overflow */
  181.         ads_fail(/*MSG5*/"íuñ▐╝╞ív└│ <= 170 íC");
  182.         return RTERROR;
  183.     }
  184.  
  185.     ads_retreal(rfact(x));            /* Call the function itself, and
  186.                                          return the value to AutoLISP */
  187.     return RTNORM;
  188. }
  189.  
  190. /*-----------------------------------------------------------------------*/
  191. /* This is the implementation of the actual external factorial function */
  192.  
  193. static ads_real rfact(n)
  194.   int n;
  195. {
  196.     ads_real ans = 1.0;
  197.  
  198.     while (n)
  199.         ans *= n--;
  200.  
  201.     return ans;
  202. }
  203.  
  204. /*-----------------------------------------------------------------------*/
  205. /* SQUAREROOT -- First set up the argument, then call the root function */
  206. static int
  207. squareroot(rb)
  208.   struct resbuf *rb;
  209. {
  210.     ads_real x;
  211.  
  212.     if (rb == NULL)
  213.         return RTERROR;               /* A proper error msg would be better */
  214.  
  215.     if (rb->restype == RTSHORT) {     /* Save in local variable */
  216.         x = (ads_real) rb->resval.rint;
  217.     } else if (rb->restype == RTREAL) {
  218.         x = rb->resval.rreal;         /* Can accept either real
  219.                                          or integer */
  220.     } else {
  221.         ads_fail(/*MSG6*/"ñ▐╝╞└│¼░íu╣Ω╝╞ív⌐╬íu╛π╝╞ívíC");
  222.         return RTERROR;
  223.     }
  224.  
  225.     if (x < 0) {                      /* Check argument range */
  226.         ads_fail(/*MSG7*/"ñ▐╝╞└│¼░íuÑ┐¡╚ívíC");
  227.         return RTERROR;
  228.     }
  229.  
  230.     ads_retreal(rsqr(x));             /* Call the function itself, and
  231.                                          return the value to AutoLISP */
  232.  
  233.     return RTNORM;
  234. }
  235.  
  236. /*-----------------------------------------------------------------------*/
  237. /* This is the implementation of the actual external function */
  238.  
  239. static ads_real rsqr(x)               /* Square root by Newton's method */
  240.   ads_real x;
  241. {
  242.     int n = 50;
  243.     ads_real y, c, cl;
  244.  
  245.     if (x == 0.0) {
  246.         return 0.0;
  247.     }
  248.  
  249.     y = (x * 2 + .1) / (x + 1.0);
  250.     c = (y - x / y) / 2;
  251.     cl= 0.0;
  252.  
  253.     while ((c != cl) && (n-- > 0)) {
  254.         y -= c;
  255.         cl = c;
  256.         c  = (y - x / y) / 2;
  257.     }
  258.     return y;
  259. }
  260.