1 /* 2 * Dealing with identifiers 3 * 4 * Copyright (C) 2014 Red Hat, Inc. 5 * 6 * Authors: 7 * Markus Armbruster <armbru@redhat.com>, 8 * 9 * This work is licensed under the terms of the GNU LGPL, version 2.1 10 * or later. See the COPYING.LIB file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "qemu/ctype.h" 15 #include "qemu/id.h" 16 17 bool id_wellformed(const char *id) 18 { 19 int i; 20 21 if (!qemu_isalpha(id[0])) { 22 return false; 23 } 24 for (i = 1; id[i]; i++) { 25 if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) { 26 return false; 27 } 28 } 29 return true; 30 } 31 32 #define ID_SPECIAL_CHAR '#' 33 34 static const char *const id_subsys_str[ID_MAX] = { 35 [ID_QDEV] = "qdev", 36 [ID_BLOCK] = "block", 37 }; 38 39 /* 40 * Generates an ID of the form PREFIX SUBSYSTEM NUMBER 41 * where: 42 * 43 * - PREFIX is the reserved character '#' 44 * - SUBSYSTEM identifies the subsystem creating the ID 45 * - NUMBER is a decimal number unique within SUBSYSTEM. 46 * 47 * Example: "#block146" 48 * 49 * Note that these IDs do not satisfy id_wellformed(). 50 * 51 * The caller is responsible for freeing the returned string with g_free() 52 */ 53 char *id_generate(IdSubSystems id) 54 { 55 static uint64_t id_counters[ID_MAX]; 56 uint32_t rnd; 57 58 assert(id < ARRAY_SIZE(id_subsys_str)); 59 assert(id_subsys_str[id]); 60 61 rnd = g_random_int_range(0, 100); 62 63 return g_strdup_printf("%c%s%" PRIu64 "%02" PRId32, ID_SPECIAL_CHAR, 64 id_subsys_str[id], 65 id_counters[id]++, 66 rnd); 67 } 68