Commit | Line | Data |
---|---|---|
a42893dd MW |
1 | /* -*-c-*- |
2 | * | |
3 | * Runtime support for SOD requiring hosted implementation | |
4 | * | |
5 | * (c) 2015 Straylight/Edgeware | |
6 | */ | |
7 | ||
8 | /*----- Licensing notice --------------------------------------------------* | |
9 | * | |
10 | * This file is part of the Sensible Object Design, an object system for C. | |
11 | * | |
12 | * SOD is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU Library General Public License as | |
14 | * published by the Free Software Foundation; either version 2 of the | |
15 | * License, or (at your option) any later version. | |
16 | * | |
17 | * SOD is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Library General Public License for more details. | |
21 | * | |
22 | * You should have received a copy of the GNU Library General Public | |
23 | * License along with SOD; if not, write to the Free | |
24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
25 | * MA 02111-1307, USA. | |
26 | */ | |
27 | ||
28 | /*----- Header files ------------------------------------------------------*/ | |
29 | ||
3b7437bc | 30 | #include <stdio.h> |
a42893dd MW |
31 | #include <stdlib.h> |
32 | ||
33 | #include "sod.h" | |
34 | ||
3b7437bc MW |
35 | /*----- Preliminary macros ------------------------------------------------*/ |
36 | ||
37 | #if __STDC_VERSION__ >= 199901 | |
38 | # define PRIuSZ "zu" | |
39 | # define PRINT_SZ(x) (x) | |
40 | #else | |
41 | # define PRIuSZ "lu" | |
42 | # define PRINT_SZ(x) ((unsigned long)(x)) | |
43 | #endif | |
44 | ||
a42893dd MW |
45 | /*----- Main code ---------------------------------------------------------*/ |
46 | ||
3b7437bc MW |
47 | /* --- @sod__chksz_fail@ --- * |
48 | * | |
49 | * Arguments: @const SodClass *cls@ = class we were trying to instantiate | |
50 | * @size_t sz@ = size allocated | |
51 | * | |
52 | * Returns: Doesn't. | |
53 | * | |
54 | * Use: Reports instantiation failure caused by a mismatch between | |
55 | * the size allocated (@sz@) and the size required for an | |
56 | * instance of class @cls@. | |
57 | */ | |
58 | ||
59 | SOD__NORETURN void sod__chksz_fail(const SodClass *cls, size_t sz) | |
60 | { | |
61 | fprintf(stderr, "INTERNAL ERROR: size mismatch for class `%s': " | |
62 | "%"PRIuSZ" allocated but %"PRIuSZ" required", | |
63 | cls->cls.name, PRINT_SZ(sz), PRINT_SZ(cls->cls.initsz)); | |
64 | abort(); | |
65 | } | |
66 | ||
a42893dd MW |
67 | /* --- @sod_make@, @sod_makev@ --- * |
68 | * | |
69 | * Arguments: @const SodClass *cls@ = class object for new instance | |
70 | * @va_list ap, ...@ = initialization keyword arguments | |
71 | * | |
72 | * Returns: Pointer to the newly-allocated initialized instance, or null. | |
73 | * | |
74 | * Use: Allocates storage for a new instance, initializes it, and | |
75 | * returns a pointer to it. If allocation fails, a null pointer | |
76 | * is returned instead. | |
77 | * | |
78 | * This function will allocate the storage using @malloc@, and | |
79 | * then initialize it as for @sod_init@. | |
80 | * | |
81 | * It's usually convenient to use the macro @SOD_MAKE@ rather | |
82 | * than calling @sod_make@ directly. | |
83 | * | |
84 | * (This function is not available in freestanding environments | |
85 | * lacking @malloc@ and @free@.) | |
86 | */ | |
87 | ||
88 | void *sod_make(const SodClass *cls, ...) | |
89 | { | |
90 | void *p; | |
91 | va_list ap; | |
92 | ||
93 | va_start(ap, cls); | |
94 | p = sod_makev(cls, ap); | |
95 | va_end(ap); | |
96 | return (p); | |
97 | } | |
98 | ||
99 | void *sod_makev(const SodClass *cls, va_list ap) | |
100 | { | |
101 | void *p; | |
102 | ||
103 | if ((p = malloc(cls->cls.initsz)) == 0) return (0); | |
104 | return (sod_initv(cls, p, ap)); | |
105 | } | |
106 | ||
107 | /* --- @sod_destroy@ --- * | |
108 | * | |
109 | * Arguments: @void *p@ = pointer to an instance to be torn down, or null | |
110 | * | |
111 | * Returns: Zero if the object was freed; nonzero if it refused for some | |
112 | * reason. | |
113 | * | |
114 | * Use: Invokes the instance's `teardown' method to release any held | |
115 | * resources, and then calls @free@ to release the instance's | |
116 | * storage. See @sod_teardown@ for details, especially | |
117 | * regarding the return value's meaning. | |
118 | * | |
119 | * If @p@ is null, then this function does nothing except | |
120 | * returns zero. | |
121 | * | |
122 | * (This function is not available in freestanding environments | |
123 | * lacking @malloc@ and @free@.) | |
124 | */ | |
125 | ||
126 | int sod_destroy(void *p) | |
127 | { | |
128 | int rc; | |
129 | ||
130 | if (!p) return (0); | |
131 | rc = sod_teardown(p); | |
132 | if (!rc) free(p); | |
133 | return (rc); | |
134 | } | |
135 | ||
136 | /*----- That's all, folks -------------------------------------------------*/ |