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