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