📄 n_reg.c
字号:
/*
* Copyright (c) 2004-2006, Dennis Kuschel.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file n_reg.c
* @brief nano layer, registry implementation
* @author Dennis Kuschel
*
* This file is originally from the pico]OS realtime operating system
* (http://picoos.sourceforge.net).
*
* CVS-ID $Id: n_reg.c,v 1.4 2006/04/16 08:48:27 dkuschel Exp $
*/
#if NOSCFG_FEATURE_SPRINTF == 0
#include <stdio.h>
#endif
#define _N_REG_C
#include "../src/nano/privnano.h"
#if NOSCFG_FEATURE_REGISTRY != 0
#if POSCFG_FEATURE_SEMAPHORES == 0
#error POSCFG_FEATURE_SEMAPHORES not enabled
#endif
#if NOSCFG_FEATURE_MEMALLOC == 0
#error NOSCFG_FEATURE_MEMALLOC not enabled
#endif
/*---------------------------------------------------------------------------
* CONFIGURATION
*-------------------------------------------------------------------------*/
#define KEY_MAXNAMENBR 9999
/*---------------------------------------------------------------------------
* TYPEDEFS AND VARIABLES
*-------------------------------------------------------------------------*/
typedef struct regquery {
REGELEM_t queryElem;
NOSREGTYPE_t type;
} *REGQUERY_t;
/*---------------------------------------------------------------------------
* GLOBAL VARIABLES
*-------------------------------------------------------------------------*/
static REGELEM_t reglist_free_g;
static POSSEMA_t reglist_sema_g;
static REGELEM_t reglist_syselem_g[MAX_REGTYPE+1];
/*---------------------------------------------------------------------------
* MACROS
*-------------------------------------------------------------------------*/
#if POSCFG_ALIGNMENT < 2
#define ALIGNEDSIZE(size) (size)
#define NEXTALIGNED(type, var) (((type)((void*)(var))) + 1)
#else
#define ALIGNEDSIZE(size) \
(((size) + (POSCFG_ALIGNMENT - 1)) & ~(POSCFG_ALIGNMENT - 1))
#define NEXTALIGNED(type, var) \
(type)((void*)(((MEMPTR_t)(var)) + ALIGNEDSIZE(sizeof(*(var)))))
#endif
#define REEUNKNOWN ((REGELEM_t)((void*)-1))
#if NOSCFG_FEATURE_REGQUERY
#define HAVE_REGREFCOUNT
#define INC_REFCOUNT(re) ++re->refcount
#define DEC_REFCOUNT(re, type) n_remove(re, REEUNKNOWN, type)
#define IS_REFERENCED(re) (re->refcount > 0)
#define RESET_REFCOUNT(re) re->refcount = 0
#else
#define RESET_REFCOUNT(re) do{}while(0)
#endif
#define IS_VISIBLE(re) (re->state == 1)
#define IS_DELETED(re) (re->state == 2)
#define MARK_INVISIBLE(re) re->state = 0;
#define MARK_VISIBLE(re) re->state = 1;
#define MARK_DELETED(re) re->state = 2;
/*---------------------------------------------------------------------------
* FUNCTION PROTOTYPES
*-------------------------------------------------------------------------*/
/* exports */
void nos_initRegistry(void);
REGELEM_t nos_regNewSysKey(NOSREGTYPE_t type, const char* name);
void nos_regEnableSysKey(REGELEM_t re, NOSGENERICHANDLE_t handle);
void nos_regDelSysKey(NOSREGTYPE_t type, NOSGENERICHANDLE_t handle,
REGELEM_t delre);
/* imports */
/* private */
static VAR_t n_strlen(const char *buf);
static REGELEM_t n_regAlloc(void);
static void n_regFree(REGELEM_t re);
static void n_remove(REGELEM_t re, REGELEM_t rl, NOSREGTYPE_t type);
static REGELEM_t n_findKeyByName(NOSREGTYPE_t type, const char *keyname);
static REGELEM_t n_findKeyByHandle(NOSREGTYPE_t type,
NOSGENERICHANDLE_t handle);
static void n_buildKeyName(char *dest, const char *basename,
VAR_t basenlen, INT_t nbr);
static VAR_t n_newKey(NOSREGTYPE_t type,
const char* name, REGELEM_t *reret);
/*---------------------------------------------------------------------------
* IMPLEMENTATION OF FUNCTIONS
*-------------------------------------------------------------------------*/
static VAR_t n_strlen(const char *buf)
{
VAR_t l;
for (l=0; buf[l]!=0; ++l);
return l;
}
static REGELEM_t n_regAlloc(void)
{
REGELEM_t re;
#if NOS_REGKEY_PREALLOC > 1
UVAR_t i;
#endif
re = reglist_free_g;
if (re != NULL)
{
reglist_free_g = re->next;
}
else
{
re = (REGELEM_t) nosMemAlloc( NOS_REGKEY_PREALLOC *
ALIGNEDSIZE(sizeof(struct regelem)) );
if (re == NULL)
return NULL;
#if NOS_REGKEY_PREALLOC > 1
for (i=0; i<NOS_REGKEY_PREALLOC-1; ++i)
{
re->next = reglist_free_g;
reglist_free_g = re;
re = NEXTALIGNED(REGELEM_t, re);
}
#endif
}
RESET_REFCOUNT(re);
MARK_INVISIBLE(re);
re->handle.generic = NULL;
#ifdef POS_DEBUGHELP
re->name[NOS_MAX_REGKEYLEN] = 0;
#endif
return re;
}
static void n_regFree(REGELEM_t re)
{
re->next = reglist_free_g;
reglist_free_g = re;
}
static void n_remove(REGELEM_t re, REGELEM_t rl, NOSREGTYPE_t type)
{
#ifdef HAVE_REGREFCOUNT
if (IS_REFERENCED(re))
{
--re->refcount;
}
else
#endif
{
if (rl == REEUNKNOWN)
{
if (re == reglist_syselem_g[type])
{
rl = NULL;
}
else
{
for (rl = reglist_syselem_g[type];
(rl != NULL) && (rl->next != re);
rl = rl->next);
if (rl == NULL)
{
rl = REEUNKNOWN;
}
}
}
if (rl != REEUNKNOWN)
{
if (rl == NULL) {
reglist_syselem_g[type] = re->next;
} else {
rl->next = re->next;
}
}
n_regFree(re);
}
}
/*-------------------------------------------------------------------------*/
static REGELEM_t n_findKeyByName(NOSREGTYPE_t type, const char *keyname)
{
REGELEM_t re;
VAR_t i;
for (re = reglist_syselem_g[type]; re != NULL; re = re->next)
{
if (!IS_DELETED(re))
{
for (i=0; i<NOS_MAX_REGKEYLEN; ++i)
{
if (re->name[i] != keyname[i])
break;
if ((keyname[i] == 0) || (i == NOS_MAX_REGKEYLEN-1))
return re;
}
}
}
return NULL;
}
static REGELEM_t n_findKeyByHandle(NOSREGTYPE_t type,
NOSGENERICHANDLE_t handle)
{
REGELEM_t re;
for (re = reglist_syselem_g[type]; re != NULL; re = re->next)
{
if ((re->handle.generic == handle) && !IS_DELETED(re))
break;
}
return re;
}
static void n_buildKeyName(char *dest, const char *basename,
VAR_t baselen, INT_t nbr)
{
char buf[5];
VAR_t l, i;
#if NOSCFG_FEATURE_SPRINTF != 0
nosSPrintf1(buf, "%i", nbr);
#else
sprintf(buf, "%i", nbr);
#endif
l = n_strlen(buf);
if ((baselen + l) >= NOS_MAX_REGKEYLEN) {
baselen = NOS_MAX_REGKEYLEN - l;
} else {
dest[baselen + l] = 0;
}
for (i=0; i<baselen; ++i)
dest[i] = basename[i];
for (i=0; i<l; ++i)
dest[baselen + i] = buf[i];
}
static VAR_t n_newKey(NOSREGTYPE_t type,
const char* name, REGELEM_t *reret)
{
REGELEM_t re;
#if NOSCFG_FEATURE_REGQUERY != 0
REGELEM_t ri;
#endif
VAR_t i, bl, status;
INT_t n;
bl = n_strlen(name);
if (bl == 0)
return -E_FAIL;
re = n_regAlloc();
if (re == NULL)
return -E_NOMEM;
status = -E_FAIL;
if ((bl > NOS_MAX_REGKEYLEN) || (name[bl - 1] == '*'))
{
if (bl > NOS_MAX_REGKEYLEN)
bl = NOS_MAX_REGKEYLEN;
--bl;
for (n=0; n <= KEY_MAXNAMENBR; ++n)
{
n_buildKeyName(re->name, name, bl, n);
if (n_findKeyByName(type, re->name) == NULL)
{
status = E_OK;
break;
}
}
}
else
{
if (n_findKeyByName(type, name) == NULL)
{
status = E_OK;
for (i=0; i<bl; ++i)
re->name[i] = name[i];
if (i < NOS_MAX_REGKEYLEN)
re->name[i] = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -