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 [ID_CHR] = "chr", 38 }; 39 40 /* 41 * Generates an ID of the form PREFIX SUBSYSTEM NUMBER 42 * where: 43 * 44 * - PREFIX is the reserved character '#' 45 * - SUBSYSTEM identifies the subsystem creating the ID 46 * - NUMBER is a decimal number unique within SUBSYSTEM. 47 * 48 * Example: "#block146" 49 * 50 * Note that these IDs do not satisfy id_wellformed(). 51 * 52 * The caller is responsible for freeing the returned string with g_free() 53 */ 54 char *id_generate(IdSubSystems id) 55 { 56 static uint64_t id_counters[ID_MAX]; 57 uint32_t rnd; 58 59 assert(id < ARRAY_SIZE(id_subsys_str)); 60 assert(id_subsys_str[id]); 61 62 rnd = g_random_int_range(0, 100); 63 64 return g_strdup_printf("%c%s%" PRIu64 "%02" PRId32, ID_SPECIAL_CHAR, 65 id_subsys_str[id], 66 id_counters[id]++, 67 rnd); 68 } 69