home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / external / sharelib / string_array.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-08  |  6.8 KB  |  247 lines

  1. /*
  2. **    $Id: string_array.c,v 1.2 1995/08/07 19:28:01 kirk Exp $
  3. **
  4. ** NAME:
  5. **    string_array    
  6. **
  7. ** PURPOSE:
  8. **    This C function is used to demonstrate how to pass a IDL array
  9. **    of type string to a C function using the IDL function CALL_EXTERNAL.
  10. **
  11. ** CATEGORY:
  12. **
  13. **    Dynamic Link
  14. **
  15. ** CALLING SEQUENCE:
  16. **      This function is called in IDL by using the following command
  17. **
  18. **      IDL> result = CALL_EXTERNAL('string_array.so', '_string_array',    $
  19. **      IDL>            array_var, array_size)
  20. **
  21. ** INPUTS:
  22. **
  23. **    array_var:    A IDL array of type string 
  24. **
  25. **    array_size:    A IDL scalar long varaible that contains the number
  26. **            of elements in array_var. This is the number that
  27. **            is returned from the IDL function N_ELEMENTS.
  28. **
  29. ** OUTPUTS:
  30. **    This function will return the lexical maximum value of the passed in
  31. **    array. This value is an IDL string scalar value.
  32. **
  33. ** SIDE EFFECTS:
  34. **    The values contained in the array and the number of elements 
  35. **    are written to stdout. 
  36. **
  37. ** RESTRICTIONS:
  38. **    This example assumes that the length value is long (4 bytes) and not
  39. **    a short integer. An IDL integer is only 2 bytes long, so the variables
  40. **    should be delcared in IDL at type long.
  41. **
  42. **      The values contained in the IDL STRING structures should NOT be
  43. **    changed. If the string structures are changed, IDL will not
  44. **    know the correct amount of memory allocated to the string and 
  45. **    errors could arise. To manipulate strings the user should 
  46. **    copy the STRING->s field to another variable and perform the 
  47. **    desired string operations. To return a string value to IDL, the
  48. **    user should return the value through the C function return value and
  49. **    use the /S_VALUE keyword with CALL_EXTERNAL.
  50. **
  51. ** EXAMPLE:
  52. **-----------------------------------------------------------------------------
  53. ;; The following are the commands that would be used to call this
  54. ;; routine in IDL.
  55. ;;
  56.            array_var = ["AAA","BBB","CCC","DDD","aaa","bbb","ccc","ddd"]    
  57.       array_size = n_elements(array_var)    
  58.  
  59.     max = CALL_EXTERNAL('string_array.so', '_string_array',        $
  60.             array_var, array_size, /S_VALUE )
  61.  
  62. **-----------------------------------------------------------------------------
  63. **
  64. ** MODIFICATION HISTORY:
  65. **    Written October, 1993        KDB
  66. **    
  67. ** Declare header file.
  68. */
  69.  
  70. #include <stdio.h>
  71. #include <string.h>
  72.  
  73. /*
  74. ** Declare the IDL string Structure. This is take from the IDL header
  75. ** file $IDL_DIR/source/export.h
  76. */
  77. typedef struct {
  78.    unsigned short slen;
  79.    short stype;
  80.    char *s;
  81. } STRING;
  82.  
  83. /*
  84. ** Declare the function
  85. */
  86.  
  87. char *
  88. string_array(argc, argv)
  89. int argc;
  90. void *argv[];
  91. {
  92. /*
  93. ** Declare local variables
  94. */
  95.    char           **string_array;    /* pointer to a C string array     */
  96.    short     n_elements;    /* number of elements in array    */
  97.    char     *max_value;     /* used to hold max value    */
  98.    STRING    *str_descr;    /* Pointer to array of STRINGs  */
  99.    short     i;        /* Counter            */
  100.    long         max_index;    /* Array Index of max string     */
  101.  
  102. /*
  103. ** Insure that the correct number of arguments were passed in (argc = 2).
  104. */
  105.    if(argc != 2)
  106.    {
  107.    /*
  108.    ** Print an error message and return.
  109.    */
  110.       fprintf(stderr, "string_array: Incorrect number of arguments\r\n");
  111.       return((char *)NULL);
  112.    }
  113. /*
  114. ** Cast the pointers in argv to local variables.
  115. */
  116.    str_descr    = (STRING *) argv[0];
  117.    n_elements    = (short)(*(long*) argv[1]);  /* convert long to short */
  118.                                               /* Needed for an alpha   */
  119. /*
  120. ** Check the size of the array passed in. n_elements should be > 0.
  121. */
  122.    if( n_elements < 1)
  123.    {
  124.    /*
  125.    ** Print an error message and return
  126.    */
  127.       fprintf(stderr, "string_array: Array elements is less that one\r\n");
  128.       return((char*)NULL);
  129.    }
  130.  
  131. /*
  132. ** First create an actual C string array and copy in the string values
  133. ** contained in the IDL STRING array
  134. **
  135. ** malloc a char* array that contains the same number of elements as
  136. ** the IDL array.
  137. */
  138.    if( (string_array=(char**)malloc((unsigned)sizeof(char*)*(n_elements)))
  139.     == (char**)NULL)
  140.    {
  141.    /*
  142.    ** Had a malloc error. Issue an error message and return a NULL
  143.    */
  144.       fprintf(stderr, "string_array: malloc error\r\n");
  145.       return((char*)NULL);
  146.    }
  147.  
  148. /*
  149. ** Use a for loop to insert the string elements. Space is malloced for 
  150. ** each element and the IDL string value copied in.
  151. */
  152.    for(i=0; i < n_elements; i++, str_descr++)
  153.    {
  154.    /*
  155.    ** Allocate memory space for the IDL string value and place the pointer
  156.    ** into the C character string array.
  157.    */
  158.       if( (string_array[i]=(char*)malloc((unsigned)sizeof(char)*
  159.     (str_descr->slen)+1) ) == (char*)NULL )
  160.       {
  161.       /*
  162.       ** We had a malloc error. Free memory, write a message
  163.       ** and return a NULL
  164.       */
  165.      for(--i; i >= 0; i--)
  166.               free( string_array[i] );   /* frees each element */
  167.  
  168.          free((char*)string_array);      /* Frees the array of char* */
  169.          
  170.          fprintf(stderr,"string_array: malloc error\r\n");
  171.  
  172.          return( (char*)NULL );          /* Return NULL */
  173.  
  174.       }
  175.  
  176.    /*
  177.    ** Copy the IDL string value into the malloced space
  178.    */
  179.        string_array[i] = strcpy(string_array[i], str_descr->s);
  180.  
  181.    } /* end of build array for loop */
  182.  
  183. /*
  184. ** Now we have a C string array. Print out the passed in information
  185. */
  186.    fprintf(stdout,
  187.     "\r\n-----------------------------------------------------\r\n");
  188.    fprintf(stdout,"Inside C function string_array ");
  189.    fprintf(stdout,"(Called from IDL using CALL_EXTERNAL)\r\n\r\n");
  190.  
  191. /*
  192. ** Now print the values of each variable that was passed in from IDL
  193. */
  194.    fprintf(stdout,"Number of elements in the String array: %d\r\n",n_elements);
  195.    fprintf(stdout, "String Array Contents:\r\n");
  196.  
  197.    for(i=0; i < n_elements; i++)
  198.         fprintf(stdout,"\tElement %3d:   %s\r\n",i, string_array[i]);
  199.  
  200.    fprintf(stdout,
  201.     "\r\n-----------------------------------------------------\r\n");
  202.  
  203. /*
  204. ** Now we have C string (char **) array that contains the values 
  205. ** of the IDL STRING structures. Now find the Max valued string.
  206. */
  207.    for(max_index=0, i=1; i < n_elements; i++) 
  208.    /*
  209.    ** Compair the max and the current string values
  210.    */
  211.       if(strcmp( string_array[max_index], string_array[i] ) < 0 )  
  212.           max_index = i; 
  213. /*
  214. ** Now malloc space for the max string and copy it to the max_sting
  215. ** pointer.
  216. */
  217.    if( (max_value=(char*)malloc((unsigned)sizeof(char)*strlen(string_array[max_index])))
  218.       == (char*)NULL )
  219.    /*
  220.    ** We had a malloc error, write a message and skip the rest of the 
  221.    ** function
  222.    */
  223.       fprintf(stderr,"string_array: malloc error\r\n");
  224.    else
  225.    /*
  226.    ** Copy the max string into the max_value pointer.
  227.    */
  228.       max_value = strcpy(max_value, string_array[max_index] );
  229.  
  230. /*
  231. ** free all the allocated memory except for the max_value and return
  232. ** max_value to IDL
  233. */
  234.    for(i=0; i < n_elements; i++)
  235.       free(string_array[i]);
  236.  
  237.    free( (char*)string_array );
  238.  
  239.    return( max_value );
  240.  
  241. } /* end of string array */
  242.  
  243.  
  244.  
  245.  
  246.  
  247.