1 //------------------------------------------------------------------------------
2 // GB_Type_new: create a new user-defined type
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 // This is not used for built-in types. Those are created statically.
11 // Users should not call this function directly; use GrB_Type_new instead.
12
13 #include "GB.h"
14
GB_Type_new(GrB_Type * type,size_t sizeof_ctype,const char * name)15 GrB_Info GB_Type_new
16 (
17 GrB_Type *type, // handle of user type to create
18 size_t sizeof_ctype, // size of the user type
19 const char *name // name of the type, as "sizeof (ctype)"
20 )
21 {
22
23 //--------------------------------------------------------------------------
24 // check inputs
25 //--------------------------------------------------------------------------
26
27 GB_WHERE1 ("GrB_Type_new (&type, sizeof (ctype))") ;
28 GB_RETURN_IF_NULL (type) ;
29 (*type) = NULL ;
30
31 #if ( ! GB_HAS_VLA )
32
33 // Microsoft Visual Studio does not support variable-length arrays
34 // allocating automatically on the stack. These arrays are used for
35 // scalar values for a given type. If VLA is not supported,
36 // user-defined types can be no larger than GB_VLA_MAXSIZE.
37
38 if (sizeof_ctype > GB_VLA_MAXSIZE)
39 {
40 return (GrB_INVALID_VALUE) ;
41 }
42
43 #endif
44
45 //--------------------------------------------------------------------------
46 // create the type
47 //--------------------------------------------------------------------------
48
49 // allocate the type
50 size_t header_size ;
51 (*type) = GB_MALLOC (1, struct GB_Type_opaque, &header_size) ;
52 if (*type == NULL)
53 {
54 // out of memory
55 return (GrB_OUT_OF_MEMORY) ;
56 }
57
58 // initialize the type
59 GrB_Type t = *type ;
60 t->magic = GB_MAGIC ;
61 t->header_size = header_size ;
62 t->size = GB_IMAX (sizeof_ctype, 1) ;
63 t->code = GB_UDT_code ; // user-defined type
64 t->name [0] = '\0' ;
65
66 //--------------------------------------------------------------------------
67 // get the name
68 //--------------------------------------------------------------------------
69
70 char input2 [GB_LEN+1] ;
71 char *p = NULL ;
72
73 // look for "sizeof" in the input string
74 if (name != NULL)
75 {
76 strncpy (input2, name, GB_LEN) ;
77 p = strstr (input2, "sizeof") ;
78 }
79
80 if (p != NULL)
81 {
82
83 // "sizeof" appears in the input string, advance past it
84 p += 6 ;
85
86 // find leading "(" if it appears, and advance to one character past it
87 char *p2 = strstr (p, "(") ;
88 if (p2 != NULL) p = p2 + 1 ;
89
90 // find trailing ")" if it appears, and delete it
91 p2 = strstr (p, ")") ;
92 if (p2 != NULL) *p2 = '\0' ;
93
94 // p now contains the final name, copy it to the output name
95 strncpy (t->name, p, GB_LEN-1) ;
96 }
97
98 //--------------------------------------------------------------------------
99 // return result
100 //--------------------------------------------------------------------------
101
102 return (GrB_SUCCESS) ;
103 }
104
105