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