1 //------------------------------------------------------------------------------
2 // GB_UnaryOp_new: create a new unary 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 // a unary operator: z = f (x).  The unary function signature must be
11 // void f (void *z, const void *x), and then it must recast its input and
12 // output arguments internally as needed.
13 
14 // This function is not directly user-callable.  Use GrB_UnaryOp_new instead.
15 
16 #include "GB.h"
17 #include <ctype.h>
18 
GB_UnaryOp_new(GrB_UnaryOp * unaryop,GxB_unary_function function,GrB_Type ztype,GrB_Type xtype,const char * name)19 GrB_Info GB_UnaryOp_new             // create a new user-defined unary operator
20 (
21     GrB_UnaryOp *unaryop,           // handle for the new unary operator
22     GxB_unary_function function,    // pointer to the unary function
23     GrB_Type ztype,                 // type of output z
24     GrB_Type xtype,                 // type of input x
25     const char *name                // name of the function
26 )
27 {
28 
29     //--------------------------------------------------------------------------
30     // check inputs
31     //--------------------------------------------------------------------------
32 
33     GB_WHERE1 ("GrB_UnaryOp_new (unaryop, function, ztype, xtype)") ;
34     GB_RETURN_IF_NULL (unaryop) ;
35     (*unaryop) = NULL ;
36     GB_RETURN_IF_NULL (function) ;
37     GB_RETURN_IF_NULL_OR_FAULTY (ztype) ;
38     GB_RETURN_IF_NULL_OR_FAULTY (xtype) ;
39 
40     //--------------------------------------------------------------------------
41     // create the unary op
42     //--------------------------------------------------------------------------
43 
44     // allocate the unary operator
45     size_t header_size ;
46     (*unaryop) = GB_MALLOC (1, struct GB_UnaryOp_opaque, &header_size) ;
47     if (*unaryop == NULL)
48     {
49         // out of memory
50         return (GrB_OUT_OF_MEMORY) ;
51     }
52 
53     // initialize the unary operator
54     GrB_UnaryOp op = *unaryop ;
55     op->magic = GB_MAGIC ;
56     op->header_size = header_size ;
57     op->xtype = xtype ;
58     op->ztype = ztype ;
59     op->function = function ;
60     op->opcode = GB_USER_opcode ;     // user-defined operator
61     op->name [0] = '\0' ;
62 
63     //--------------------------------------------------------------------------
64     // find the name of the operator
65     //--------------------------------------------------------------------------
66 
67     if (name != NULL)
68     {
69         // see if the typecast "(GxB_unary_function)" appears in the name
70         char *p = NULL ;
71         p = strstr ((char *) name, "GxB_unary_function") ;
72         if (p != NULL)
73         {
74             // skip past the typecast, the left parenthesis, and any whitespace
75             p += 19 ;
76             while (isspace (*p)) p++ ;
77             if (*p == ')') p++ ;
78             while (isspace (*p)) p++ ;
79             strncpy (op->name, p, GB_LEN-1) ;
80         }
81         else
82         {
83             // copy the entire name as-is
84             strncpy (op->name, name, GB_LEN-1) ;
85         }
86     }
87 
88     //--------------------------------------------------------------------------
89     // return result
90     //--------------------------------------------------------------------------
91 
92     ASSERT_UNARYOP_OK (op, "new user-defined unary op", GB0) ;
93     return (GrB_SUCCESS) ;
94 }
95 
96