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 "config.h" 25 26 #include <string.h> 27 28 #include "genums.h" 29 #include "gvalue.h" 30 #include "gvaluecollector.h" 31 #include "gobjectalias.h" 32 33 34 /** 35 * SECTION:enumerations_flags 36 * @short_description: Enumeration and flags types 37 * @see_also:#GParamSpecEnum, #GParamSpecFlags, g_param_spec_enum(), 38 * g_param_spec_flags(), 39 * 40 * <link linkend="glib-mkenums">glib-mkenums</link> 41 * @title: Enumeration and Flag Types 42 * 43 * The GLib type system provides fundamental types for enumeration and 44 * flags types. (Flags types are like enumerations, but allow their 45 * values to be combined by bitwise or). A registered enumeration or 46 * flags type associates a name and a nickname with each allowed 47 * value, and the methods g_enum_get_value_by_name(), 48 * g_enum_get_value_by_nick(), g_flags_get_value_by_name() and 49 * g_flags_get_value_by_nick() can look up values by their name or 50 * nickname. When an enumeration or flags type is registered with the 51 * GLib type system, it can be used as value type for object 52 * properties, using g_param_spec_enum() or g_param_spec_flags(). 53 * 54 * GObject ships with a utility called <link 55 * linkend="glib-mkenums">glib-mkenums</link> that can construct 56 * suitable type registration functions from C enumeration 57 * definitions. 58 */ 59 60 61 /* --- prototypes --- */ 62 static void g_enum_class_init (GEnumClass *class, 63 gpointer class_data); 64 static void g_flags_class_init (GFlagsClass *class, 65 gpointer class_data); 66 static void value_flags_enum_init (GValue *value); 67 static void value_flags_enum_copy_value (const GValue *src_value, 68 GValue *dest_value); 69 static gchar* value_flags_enum_collect_value (GValue *value, 70 guint n_collect_values, 71 GTypeCValue *collect_values, 72 guint collect_flags); 73 static gchar* value_flags_enum_lcopy_value (const GValue *value, 74 guint n_collect_values, 75 GTypeCValue *collect_values, 76 guint collect_flags); 77 78 /* --- functions --- */ 79 void 80 g_enum_types_init (void) 81 { 82 static gboolean initialized = FALSE; 83 static const GTypeValueTable flags_enum_value_table = { 84 value_flags_enum_init, /* value_init */ 85 NULL, /* value_free */ 86 value_flags_enum_copy_value, /* value_copy */ 87 NULL, /* value_peek_pointer */ 88 "i", /* collect_format */ 89 value_flags_enum_collect_value, /* collect_value */ 90 "p", /* lcopy_format */ 91 value_flags_enum_lcopy_value, /* lcopy_value */ 92 }; 93 static GTypeInfo info = { 94 0, /* class_size */ 95 NULL, /* base_init */ 96 NULL, /* base_destroy */ 97 NULL, /* class_init */ 98 NULL, /* class_destroy */ 99 NULL, /* class_data */ 100 0, /* instance_size */ 101 0, /* n_preallocs */ 102 NULL, /* instance_init */ 103 &flags_enum_value_table, /* value_table */ 104 }; 105 static const GTypeFundamentalInfo finfo = { 106 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE, 107 }; 108 GType type; 109 110 g_return_if_fail (initialized == FALSE); 111 initialized = TRUE; 112 113 /* G_TYPE_ENUM 114 */ 115 info.class_size = sizeof (GEnumClass); 116 type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo, 117 G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); 118 g_assert (type == G_TYPE_ENUM); 119 120 /* G_TYPE_FLAGS 121 */ 122 info.class_size = sizeof (GFlagsClass); 123 type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo, 124 G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT); 125 g_assert (type == G_TYPE_FLAGS); 126 } 127 128 static void 129 value_flags_enum_init (GValue *value) 130 { 131 value->data[0].v_long = 0; 132 } 133 134 static void 135 value_flags_enum_copy_value (const GValue *src_value, 136 GValue *dest_value) 137 { 138 dest_value->data[0].v_long = src_value->data[0].v_long; 139 } 140 141 static gchar* 142 value_flags_enum_collect_value (GValue *value, 143 guint n_collect_values, 144 GTypeCValue *collect_values, 145 guint collect_flags) 146 { 147 value->data[0].v_long = collect_values[0].v_int; 148 149 return NULL; 150 } 151 152 static gchar* 153 value_flags_enum_lcopy_value (const GValue *value, 154 guint n_collect_values, 155 GTypeCValue *collect_values, 156 guint collect_flags) 157 { 158 gint *int_p = collect_values[0].v_pointer; 159 160 if (!int_p) 161 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); 162 163 *int_p = value->data[0].v_long; 164 165 return NULL; 166 } 167 168 /** 169 * g_enum_register_static: 170 * @name: A nul-terminated string used as the name of the new type. 171 * @const_static_values: An array of #GEnumValue structs for the possible 172 * enumeration values. The array is terminated by a struct with all 173 * members being 0. GObject keeps a reference to the data, so it cannot 174 * be stack-allocated. 175 * 176 * Registers a new static enumeration type with the name @name. 177 * 178 * It is normally more convenient to let <link 179 * linkend="glib-mkenums">glib-mkenums</link> generate a 180 * my_enum_get_type() function from a usual C enumeration definition 181 * than to write one yourself using g_enum_register_static(). 182 * 183 * Returns: The new type identifier. 184 */ 185 GType 186 g_enum_register_static (const gchar *name, 187 const GEnumValue *const_static_values) 188 { 189 GTypeInfo enum_type_info = { 190 sizeof (GEnumClass), /* class_size */ 191 NULL, /* base_init */ 192 NULL, /* base_finalize */ 193 (GClassInitFunc) g_enum_class_init, 194 NULL, /* class_finalize */ 195 NULL, /* class_data */ 196 0, /* instance_size */ 197 0, /* n_preallocs */ 198 NULL, /* instance_init */ 199 NULL, /* value_table */ 200 }; 201 GType type; 202 203 g_return_val_if_fail (name != NULL, 0); 204 g_return_val_if_fail (const_static_values != NULL, 0); 205 206 enum_type_info.class_data = const_static_values; 207 208 type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0); 209 210 return type; 211 } 212 213 /** 214 * g_flags_register_static: 215 * @name: A nul-terminated string used as the name of the new type. 216 * @const_static_values: An array of #GFlagsValue structs for the possible 217 * flags values. The array is terminated by a struct with all members being 0. 218 * GObject keeps a reference to the data, so it cannot be stack-allocated. 219 * 220 * Registers a new static flags type with the name @name. 221 * 222 * It is normally more convenient to let <link 223 * linkend="glib-mkenums">glib-mkenums</link> generate a 224 * my_flags_get_type() function from a usual C enumeration definition 225 * than to write one yourself using g_flags_register_static(). 226 * 227 * Returns: The new type identifier. 228 */ 229 GType 230 g_flags_register_static (const gchar *name, 231 const GFlagsValue *const_static_values) 232 { 233 GTypeInfo flags_type_info = { 234 sizeof (GFlagsClass), /* class_size */ 235 NULL, /* base_init */ 236 NULL, /* base_finalize */ 237 (GClassInitFunc) g_flags_class_init, 238 NULL, /* class_finalize */ 239 NULL, /* class_data */ 240 0, /* instance_size */ 241 0, /* n_preallocs */ 242 NULL, /* instance_init */ 243 NULL, /* value_table */ 244 }; 245 GType type; 246 247 g_return_val_if_fail (name != NULL, 0); 248 g_return_val_if_fail (const_static_values != NULL, 0); 249 250 flags_type_info.class_data = const_static_values; 251 252 type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0); 253 254 return type; 255 } 256 257 /** 258 * g_enum_complete_type_info: 259 * @g_enum_type: the type identifier of the type being completed 260 * @info: the #GTypeInfo struct to be filled in 261 * @const_values: An array of #GEnumValue structs for the possible 262 * enumeration values. The array is terminated by a struct with all 263 * members being 0. 264 * 265 * This function is meant to be called from the complete_type_info() 266 * function of a #GTypePlugin implementation, as in the following 267 * example: 268 * 269 * |[ 270 * static void 271 * my_enum_complete_type_info (GTypePlugin *plugin, 272 * GType g_type, 273 * GTypeInfo *info, 274 * GTypeValueTable *value_table) 275 * { 276 * static const GEnumValue values[] = { 277 * { MY_ENUM_FOO, "MY_ENUM_FOO", "foo" }, 278 * { MY_ENUM_BAR, "MY_ENUM_BAR", "bar" }, 279 * { 0, NULL, NULL } 280 * }; 281 * 282 * g_enum_complete_type_info (type, info, values); 283 * } 284 * ]| 285 */ 286 void 287 g_enum_complete_type_info (GType g_enum_type, 288 GTypeInfo *info, 289 const GEnumValue *const_values) 290 { 291 g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type)); 292 g_return_if_fail (info != NULL); 293 g_return_if_fail (const_values != NULL); 294 295 info->class_size = sizeof (GEnumClass); 296 info->base_init = NULL; 297 info->base_finalize = NULL; 298 info->class_init = (GClassInitFunc) g_enum_class_init; 299 info->class_finalize = NULL; 300 info->class_data = const_values; 301 } 302 303 /** 304 * g_flags_complete_type_info: 305 * @g_flags_type: the type identifier of the type being completed 306 * @info: the #GTypeInfo struct to be filled in 307 * @const_values: An array of #GFlagsValue structs for the possible 308 * enumeration values. The array is terminated by a struct with all 309 * members being 0. 310 * 311 * This function is meant to be called from the complete_type_info() 312 * function of a #GTypePlugin implementation, see the example for 313 * g_enum_complete_type_info() above. 314 */ 315 void 316 g_flags_complete_type_info (GType g_flags_type, 317 GTypeInfo *info, 318 const GFlagsValue *const_values) 319 { 320 g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type)); 321 g_return_if_fail (info != NULL); 322 g_return_if_fail (const_values != NULL); 323 324 info->class_size = sizeof (GFlagsClass); 325 info->base_init = NULL; 326 info->base_finalize = NULL; 327 info->class_init = (GClassInitFunc) g_flags_class_init; 328 info->class_finalize = NULL; 329 info->class_data = const_values; 330 } 331 332 static void 333 g_enum_class_init (GEnumClass *class, 334 gpointer class_data) 335 { 336 g_return_if_fail (G_IS_ENUM_CLASS (class)); 337 338 class->minimum = 0; 339 class->maximum = 0; 340 class->n_values = 0; 341 class->values = class_data; 342 343 if (class->values) 344 { 345 GEnumValue *values; 346 347 class->minimum = class->values->value; 348 class->maximum = class->values->value; 349 for (values = class->values; values->value_name; values++) 350 { 351 class->minimum = MIN (class->minimum, values->value); 352 class->maximum = MAX (class->maximum, values->value); 353 class->n_values++; 354 } 355 } 356 } 357 358 static void 359 g_flags_class_init (GFlagsClass *class, 360 gpointer class_data) 361 { 362 g_return_if_fail (G_IS_FLAGS_CLASS (class)); 363 364 class->mask = 0; 365 class->n_values = 0; 366 class->values = class_data; 367 368 if (class->values) 369 { 370 GFlagsValue *values; 371 372 for (values = class->values; values->value_name; values++) 373 { 374 class->mask |= values->value; 375 class->n_values++; 376 } 377 } 378 } 379 380 /** 381 * g_enum_get_value_by_name: 382 * @enum_class: a #GEnumClass 383 * @name: the name to look up 384 * 385 * Looks up a #GEnumValue by name. 386 * 387 * Returns: the #GEnumValue with name @name, or %NULL if the 388 * enumeration doesn't have a member with that name 389 */ 390 GEnumValue* 391 g_enum_get_value_by_name (GEnumClass *enum_class, 392 const gchar *name) 393 { 394 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); 395 g_return_val_if_fail (name != NULL, NULL); 396 397 if (enum_class->n_values) 398 { 399 GEnumValue *enum_value; 400 401 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) 402 if (strcmp (name, enum_value->value_name) == 0) 403 return enum_value; 404 } 405 406 return NULL; 407 } 408 409 /** 410 * g_flags_get_value_by_name: 411 * @flags_class: a #GFlagsClass 412 * @name: the name to look up 413 * 414 * Looks up a #GFlagsValue by name. 415 * 416 * Returns: the #GFlagsValue with name @name, or %NULL if there is no 417 * flag with that name 418 */ 419 GFlagsValue* 420 g_flags_get_value_by_name (GFlagsClass *flags_class, 421 const gchar *name) 422 { 423 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); 424 g_return_val_if_fail (name != NULL, NULL); 425 426 if (flags_class->n_values) 427 { 428 GFlagsValue *flags_value; 429 430 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) 431 if (strcmp (name, flags_value->value_name) == 0) 432 return flags_value; 433 } 434 435 return NULL; 436 } 437 438 /** 439 * g_enum_get_value_by_nick: 440 * @enum_class: a #GEnumClass 441 * @nick: the nickname to look up 442 * 443 * Looks up a #GEnumValue by nickname. 444 * 445 * Returns: the #GEnumValue with nickname @nick, or %NULL if the 446 * enumeration doesn't have a member with that nickname 447 */ 448 GEnumValue* 449 g_enum_get_value_by_nick (GEnumClass *enum_class, 450 const gchar *nick) 451 { 452 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); 453 g_return_val_if_fail (nick != NULL, NULL); 454 455 if (enum_class->n_values) 456 { 457 GEnumValue *enum_value; 458 459 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) 460 if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0) 461 return enum_value; 462 } 463 464 return NULL; 465 } 466 467 /** 468 * g_flags_get_value_by_nick: 469 * @flags_class: a #GFlagsClass 470 * @nick: the nickname to look up 471 * 472 * Looks up a #GFlagsValue by nickname. 473 * 474 * Returns: the #GFlagsValue with nickname @nick, or %NULL if there is 475 * no flag with that nickname 476 */ 477 GFlagsValue* 478 g_flags_get_value_by_nick (GFlagsClass *flags_class, 479 const gchar *nick) 480 { 481 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); 482 g_return_val_if_fail (nick != NULL, NULL); 483 484 if (flags_class->n_values) 485 { 486 GFlagsValue *flags_value; 487 488 for (flags_value = flags_class->values; flags_value->value_nick; flags_value++) 489 if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0) 490 return flags_value; 491 } 492 493 return NULL; 494 } 495 496 /** 497 * g_enum_get_value: 498 * @enum_class: a #GEnumClass 499 * @value: the value to look up 500 * 501 * Returns the #GEnumValue for a value. 502 * 503 * Returns: the #GEnumValue for @value, or %NULL if @value is not a 504 * member of the enumeration 505 */ 506 GEnumValue* 507 g_enum_get_value (GEnumClass *enum_class, 508 gint value) 509 { 510 g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); 511 512 if (enum_class->n_values) 513 { 514 GEnumValue *enum_value; 515 516 for (enum_value = enum_class->values; enum_value->value_name; enum_value++) 517 if (enum_value->value == value) 518 return enum_value; 519 } 520 521 return NULL; 522 } 523 524 /** 525 * g_flags_get_first_value: 526 * @flags_class: a #GFlagsClass 527 * @value: the value 528 * 529 * Returns the first #GFlagsValue which is set in @value. 530 * 531 * Returns: the first #GFlagsValue which is set in @value, or %NULL if 532 * none is set 533 */ 534 GFlagsValue* 535 g_flags_get_first_value (GFlagsClass *flags_class, 536 guint value) 537 { 538 g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); 539 540 if (flags_class->n_values) 541 { 542 GFlagsValue *flags_value; 543 544 if (value == 0) 545 { 546 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) 547 if (flags_value->value == 0) 548 return flags_value; 549 } 550 else 551 { 552 for (flags_value = flags_class->values; flags_value->value_name; flags_value++) 553 if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value) 554 return flags_value; 555 } 556 } 557 558 return NULL; 559 } 560 561 /** 562 * g_value_set_enum: 563 * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM 564 * @v_enum: enum value to be set 565 * 566 * Set the contents of a %G_TYPE_ENUM #GValue to @v_enum. 567 */ 568 void 569 g_value_set_enum (GValue *value, 570 gint v_enum) 571 { 572 g_return_if_fail (G_VALUE_HOLDS_ENUM (value)); 573 574 value->data[0].v_long = v_enum; 575 } 576 577 /** 578 * g_value_get_enum: 579 * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM 580 * 581 * Get the contents of a %G_TYPE_ENUM #GValue. 582 * 583 * Returns: enum contents of @value 584 */ 585 gint 586 g_value_get_enum (const GValue *value) 587 { 588 g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0); 589 590 return value->data[0].v_long; 591 } 592 593 /** 594 * g_value_set_flags: 595 * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS 596 * @v_flags: flags value to be set 597 * 598 * Set the contents of a %G_TYPE_FLAGS #GValue to @v_flags. 599 */ 600 void 601 g_value_set_flags (GValue *value, 602 guint v_flags) 603 { 604 g_return_if_fail (G_VALUE_HOLDS_FLAGS (value)); 605 606 value->data[0].v_ulong = v_flags; 607 } 608 609 /** 610 * g_value_get_flags: 611 * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS 612 * 613 * Get the contents of a %G_TYPE_FLAGS #GValue. 614 * 615 * Returns: flags contents of @value 616 */ 617 guint 618 g_value_get_flags (const GValue *value) 619 { 620 g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0); 621 622 return value->data[0].v_ulong; 623 } 624 625 #define __G_ENUMS_C__ 626 #include "gobjectaliasdef.c" 627