1 //------------------------------------------------------------------------------
2 // GB_SelectOp_new: create a new select operator
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7 
8 //------------------------------------------------------------------------------
9 
10 // The select function signature must be:
11 
12 //      bool f (GrB_Index i, GrB_Index j, GrB_Index nrows, GrB_Index ncols,
13 //              const void *x, const void *thunk) ;
14 
15 #include "GB.h"
16 #include <ctype.h>
17 
GB_SelectOp_new(GxB_SelectOp * selectop,GxB_select_function function,GrB_Type xtype,GrB_Type ttype,const char * name)18 GrB_Info GB_SelectOp_new        // create a new user-defined select operator
19 (
20     GxB_SelectOp *selectop,     // handle for the new select operator
21     GxB_select_function function,// pointer to the select function
22     GrB_Type xtype,             // type of input x
23     GrB_Type ttype,             // type of input thunk
24     const char *name            // name of the function
25 )
26 {
27 
28     //--------------------------------------------------------------------------
29     // check inputs
30     //--------------------------------------------------------------------------
31 
32     GB_WHERE1 ("GxB_SelectOp_new (selectop, function, xtype)") ;
33     GB_RETURN_IF_NULL (selectop) ;
34     (*selectop) = NULL ;
35     GB_RETURN_IF_NULL (function) ;
36     GB_RETURN_IF_FAULTY (xtype) ;   // xtype may be NULL
37     GB_RETURN_IF_FAULTY (ttype) ;   // ttype may be NULL
38 
39     //--------------------------------------------------------------------------
40     // create the select op
41     //--------------------------------------------------------------------------
42 
43     // allocate the select operator
44     size_t header_size ;
45     (*selectop) = GB_MALLOC (1, struct GB_SelectOp_opaque, &header_size) ;
46     if (*selectop == NULL)
47     {
48         // out of memory
49         return (GrB_OUT_OF_MEMORY) ;
50     }
51 
52     // initialize the select operator
53     GxB_SelectOp op = *selectop ;
54     op->magic = GB_MAGIC ;
55     op->header_size = header_size ;
56     op->xtype = xtype ;
57     op->ttype = ttype ;
58     op->function = function ;
59     op->opcode = GB_USER_SELECT_opcode ;
60     op->name [0] = '\0' ;
61 
62     //--------------------------------------------------------------------------
63     // find the name of the operator
64     //--------------------------------------------------------------------------
65 
66     if (name != NULL)
67     {
68         // see if the typecast "(GxB_select_function)" appears in the name
69         char *p = NULL ;
70         p = strstr ((char *) name, "GxB_select_function") ;
71         if (p != NULL)
72         {
73             // skip past the typecast, the left parenthesis, and any whitespace
74             p += 19 ;
75             while (isspace (*p)) p++ ;
76             if (*p == ')') p++ ;
77             while (isspace (*p)) p++ ;
78             strncpy (op->name, p, GB_LEN-1) ;
79         }
80         else
81         {
82             // copy the entire name as-is
83             strncpy (op->name, name, GB_LEN-1) ;
84         }
85     }
86 
87     //--------------------------------------------------------------------------
88     // return result
89     //--------------------------------------------------------------------------
90 
91     ASSERT_SELECTOP_OK (op, "new user-defined select op", GB0) ;
92     return (GrB_SUCCESS) ;
93 }
94 
95