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 13f5bebbbbSMarkus Armbruster #include "qemu-common.h" 14f5bebbbbSMarkus Armbruster 15f5bebbbbSMarkus Armbruster bool id_wellformed(const char *id) 16f5bebbbbSMarkus Armbruster { 17f5bebbbbSMarkus Armbruster int i; 18f5bebbbbSMarkus Armbruster 19f5bebbbbSMarkus Armbruster if (!qemu_isalpha(id[0])) { 20f5bebbbbSMarkus Armbruster return false; 21f5bebbbbSMarkus Armbruster } 22f5bebbbbSMarkus Armbruster for (i = 1; id[i]; i++) { 23f5bebbbbSMarkus Armbruster if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) { 24f5bebbbbSMarkus Armbruster return false; 25f5bebbbbSMarkus Armbruster } 26f5bebbbbSMarkus Armbruster } 27f5bebbbbSMarkus Armbruster return true; 28f5bebbbbSMarkus Armbruster } 29a0f19136SJeff Cody 30a0f19136SJeff Cody #define ID_SPECIAL_CHAR '#' 31a0f19136SJeff Cody 32*624533e5SJohn Snow static const char *const id_subsys_str[ID_MAX] = { 33a0f19136SJeff Cody [ID_QDEV] = "qdev", 34a0f19136SJeff Cody [ID_BLOCK] = "block", 35a0f19136SJeff Cody }; 36a0f19136SJeff Cody 37a0f19136SJeff Cody /* 38a0f19136SJeff Cody * Generates an ID of the form PREFIX SUBSYSTEM NUMBER 39a0f19136SJeff Cody * where: 40a0f19136SJeff Cody * 41a0f19136SJeff Cody * - PREFIX is the reserved character '#' 42a0f19136SJeff Cody * - SUBSYSTEM identifies the subsystem creating the ID 43a0f19136SJeff Cody * - NUMBER is a decimal number unique within SUBSYSTEM. 44a0f19136SJeff Cody * 45a0f19136SJeff Cody * Example: "#block146" 46a0f19136SJeff Cody * 47a0f19136SJeff Cody * Note that these IDs do not satisfy id_wellformed(). 48a0f19136SJeff Cody * 49a0f19136SJeff Cody * The caller is responsible for freeing the returned string with g_free() 50a0f19136SJeff Cody */ 51a0f19136SJeff Cody char *id_generate(IdSubSystems id) 52a0f19136SJeff Cody { 53a0f19136SJeff Cody static uint64_t id_counters[ID_MAX]; 54a0f19136SJeff Cody uint32_t rnd; 55a0f19136SJeff Cody 56*624533e5SJohn Snow assert(id < ARRAY_SIZE(id_subsys_str)); 57a0f19136SJeff Cody assert(id_subsys_str[id]); 58a0f19136SJeff Cody 59a0f19136SJeff Cody rnd = g_random_int_range(0, 100); 60a0f19136SJeff Cody 61a0f19136SJeff Cody return g_strdup_printf("%c%s%" PRIu64 "%02" PRId32, ID_SPECIAL_CHAR, 62a0f19136SJeff Cody id_subsys_str[id], 63a0f19136SJeff Cody id_counters[id]++, 64a0f19136SJeff Cody rnd); 65a0f19136SJeff Cody } 66