genums.c revision 7788ead1376fd75d4798c5602b9ad6b742020570
1/* GObject - GLib Type, Object, Parameter and Signal Library 2 * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General 15 * Public License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20/* 21 * MT safe 22 */ 23 24#include <string.h> 25 26#include "genums.h" 27 28#include "gvalue.h" 29#include "gvaluecollector.h" 30 31#include "gobjectalias.h" 32 33 34/* --- prototypes --- */ 35static void g_enum_class_init (GEnumClass *class, 36 gpointer class_data); 37static void g_flags_class_init (GFlagsClass *class, 38 gpointer class_data); 39static void value_flags_enum_init (GValue *value); 40static void value_flags_enum_copy_value (const GValue *src_value, 41 GValue *dest_value); 42static gchar* value_flags_enum_collect_value (GValue *value, 43 guint n_collect_values, 44 GTypeCValue *collect_values, 45 guint collect_flags); 46static gchar* value_flags_enum_lcopy_value (const GValue *value, 47 guint n_collect_values, 48 GTypeCValue *collect_values, 49 guint collect_flags); 50 51/* --- functions --- */ 52void 53g_enum_types_init (void) 54{ 55 static gboolean initialized = FALSE; 56 static const GTypeValueTable flags_enum_value_table = { 57 value_flags_enum_init, /* value_init */ 58 NULL, /* value_free */ 59 value_flags_enum_copy_value, /* value_copy */ 60 NULL, /* value_peek_pointer */ 61 "i", /* collect_format */ 62 value_flags_enum_collect_value, /* collect_value */ 63 "p", /* lcopy_format */ 64 value_flags_enum_lcopy_value, /* lcopy_value */ 65 }; 66 static GTypeInfo info = { 67 0, /* class_size */ 68 NULL, /* base_init */ 69 NULL, /* base_destroy */ 70 NULL, /* class_init */ 71 NULL, /* class_destroy */ 72 NULL, /* class_data */ 73 0, /* instance_size */ 74 0, /* n_preallocs */ 75 NULL, /* instance_init */ 76 &flags_enum_value_table, /* value_table */ 77 }; 78 static const GTypeFundamentalInfo finfo = { 79 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE, 80 }; 81 GType type; 82 83 g_return_if_fail (initialized == FALSE); 84 initialized = TRUE; 85 86 /* G_TYPE_ENUM 87 */ 88 info.class_size = sizeof (GEnumClass); 89 type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &info, &finfo, 90 G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); 91 g_assert (type == G_TYPE_ENUM); 92 93 /* G_TYPE_FLAGS 94 */ 95 info.class_size = sizeof (GFlagsClass); 96 type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &info, &finfo, 97 G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); 98 g_assert (type == G_TYPE_FLAGS); 99} 100 101static void 102value_flags_enum_init (GValue *value) 103{ 104 value->data[0].v_long = 0; 105} 106 107static void 108value_flags_enum_copy_value (const GValue *src_value, 109 GValue *dest_value) 110{ 111 dest_value->data[0].v_long = src_value->data[0].v_long; 112} 113 114static gchar* 115value_flags_enum_collect_value (GValue *value, 116 guint n_collect_values, 117 GTypeCValue *collect_values, 118 guint collect_flags) 119{ 120 value->data[0].v_long = collect_values[0].v_int; 121 122 return NULL; 123} 124 125static gchar* 126value_flags_enum_lcopy_value (const GValue *value, 127 guint n_collect_values, 128 GTypeCValue *collect_values, 129 guint collect_flags) 130{ 131 gint *int_p = collect_values[0].v_pointer; 132 133 if (!int_p) 134 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); 135 136 *int_p = value->data[0].v_long; 137 138 return NULL; 139} 140 141GType 142g_enum_register_static (const gchar *name, 143 const GEnumValue *const_static_values) 144{ 145 GTypeInfo enum_type_info = { 146 sizeof (GEnumClass), /* class_size */ 147 NULL, /* base_init */ 148 NULL, /* base_finalize */ 149 (GClassInitFunc) g_enum_class_init, 150 NULL, /* class_finalize */ 151 NULL, /* class_data */ 152 0, /* instance_size */ 153 0, /* n_preallocs */ 154 NULL, /* instance_init */ 155 NULL, /* value_table */ 156 }; 157 GType type; 158 159 g_return_val_if_fail (name != NULL, 0); 160 g_return_val_if_fail (const_static_values != NULL, 0); 161 162 enum_type_info.class_data = const_static_values; 163 164 type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0); 165 166 return type; 167} 168 169GType 170g_flags_register_static (const gchar *name, 171 const GFlagsValue *const_static_values) 172{ 173 GTypeInfo flags_type_info = { 174 sizeof (GFlagsClass), /* class_size */ 175 NULL, /* base_init */ 176 NULL, /* base_finalize */ 177 (GClassInitFunc) g_flags_class_init, 178 NULL, /* class_finalize */ 179 NULL, /* class_data */ 180 0, /* instance_size */ 181 0, /* n_preallocs */ 182 NULL, /* instance_init */ 183 NULL, /* value_table */ 184 }; 185 GType type; 186 187 g_return_val_if_fail (name != NULL, 0); 188 g_return_val_if_fail (const_static_values != NULL, 0); 189 190 flags_type_info.class_data = const_static_values; 191 192 type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0); 193 194 return type; 195} 196 197void 198g_enum_complete_type_info (GType g_enum_type, 199 GTypeInfo *info, 200 const GEnumValue *const_values) 201{ 202 g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type)); 203 g_return_if_fail (info != NULL); 204 g_return_if_fail (const_values != NULL); 205 206 info->class_size = sizeof (GEnumClass); 207 info->base_init = NULL; 208 info->base_finalize = NULL; 209 info->class_init = (GClassInitFunc) g_enum_class_init; 210 info->class_finalize = NULL; 211 info->class_data = const_values; 212} 213 214void 215g_flags_complete_type_info (GType g_flags_type, 216 GTypeInfo *info, 217 const GFlagsValue *const_values) 218{ 219 g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type)); 220 g_return_if_fail (info != NULL); 221 g_return_if_fail (const_values != NULL); 222 223 info->class_size = sizeof (GFlagsClass); 224 info->base_init = NULL; 225 info->base_finalize = NULL; 226 info->class_init = (GClassInitFunc) g_flags_class_init; 227 info->class_finalize = NULL; 228 info->class_data = const_values; 229} 230 231static void 232g_enum_class_init (GEnumClass *class, 233 gpointer class_data) 234{ 235 g_return_if_fail (G_IS_ENUM_CLASS (class)); 236 237 class->minimum = 0; 238 class->maximum = 0; 239 class->n_values = 0; 240 class->values = class_data; 241 242 if (class->values) 243 { 244 GEnumValue *values; 245 246 class->minimum = class->values->value; 247 class->maximum = class->values->value; 248 for (values = class->values; values->value_name; values++) 249 { 250 class->minimum = MIN (class->minimum, values->value); 251 class->maximum = MAX (class->maximum, values->value); 252 class->n_values++; 253 } 254 } 255} 256 257static void 258g_flags_class_init (GFlagsClass *class, 259 gpointer class_data) 260{ 261 g_return_if_fail (G_IS_FLAGS_CLASS (class)); 262 263 class->mask = 0; 264 class->n_values = 0; 265 class->values = class_data; 266 267 if (class->values) 268 { 269 GFlagsValue *values; 270 271 for (values = class->values; values->value_name; values++) 272 { 273 class->mask |= values->value; 274 class->n_values++; 275 } 276 } 277} 278 279GEnumValue* 280g_enum_get_value_by_name (GEnumClass *enum_class, 281 const gchar *name) 282{ 283 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); 284 g_return_val_if_fail (name != NULL, NULL); 285 286 if (enum_class->n_values) 287 { 288 GEnumValue *enum_value; 289 290 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) 291 if (strcmp (name, enum_value->value_name) == 0) 292 return enum_value; 293 } 294 295 return NULL; 296} 297 298GFlagsValue* 299g_flags_get_value_by_name (GFlagsClass *flags_class, 300 const gchar *name) 301{ 302 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); 303 g_return_val_if_fail (name != NULL, NULL); 304 305 if (flags_class->n_values) 306 { 307 GFlagsValue *flags_value; 308 309 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) 310 if (strcmp (name, flags_value->value_name) == 0) 311 return flags_value; 312 } 313 314 return NULL; 315} 316 317GEnumValue* 318g_enum_get_value_by_nick (GEnumClass *enum_class, 319 const gchar *nick) 320{ 321 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); 322 g_return_val_if_fail (nick != NULL, NULL); 323 324 if (enum_class->n_values) 325 { 326 GEnumValue *enum_value; 327 328 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) 329 if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0) 330 return enum_value; 331 } 332 333 return NULL; 334} 335 336GFlagsValue* 337g_flags_get_value_by_nick (GFlagsClass *flags_class, 338 const gchar *nick) 339{ 340 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); 341 g_return_val_if_fail (nick != NULL, NULL); 342 343 if (flags_class->n_values) 344 { 345 GFlagsValue *flags_value; 346 347 for (flags_value = flags_class->values; flags_value->value_nick; flags_value++) 348 if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0) 349 return flags_value; 350 } 351 352 return NULL; 353} 354 355GEnumValue* 356g_enum_get_value (GEnumClass *enum_class, 357 gint value) 358{ 359 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); 360 361 if (enum_class->n_values) 362 { 363 GEnumValue *enum_value; 364 365 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) 366 if (enum_value->value == value) 367 return enum_value; 368 } 369 370 return NULL; 371} 372 373GFlagsValue* 374g_flags_get_first_value (GFlagsClass *flags_class, 375 guint value) 376{ 377 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); 378 379 if (flags_class->n_values) 380 { 381 GFlagsValue *flags_value; 382 383 if (value == 0) 384 { 385 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) 386 if (flags_value->value == 0) 387 return flags_value; 388 } 389 else 390 { 391 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) 392 if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value) 393 return flags_value; 394 } 395 } 396 397 return NULL; 398} 399 400void 401g_value_set_enum (GValue *value, 402 gint v_enum) 403{ 404 g_return_if_fail (G_VALUE_HOLDS_ENUM (value)); 405 406 value->data[0].v_long = v_enum; 407} 408 409gint 410g_value_get_enum (const GValue *value) 411{ 412 g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0); 413 414 return value->data[0].v_long; 415} 416 417void 418g_value_set_flags (GValue *value, 419 guint v_flags) 420{ 421 g_return_if_fail (G_VALUE_HOLDS_FLAGS (value)); 422 423 value->data[0].v_ulong = v_flags; 424} 425 426guint 427g_value_get_flags (const GValue *value) 428{ 429 g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0); 430 431 return value->data[0].v_ulong; 432} 433 434#define __G_ENUMS_C__ 435#include "gobjectaliasdef.c" 436