cScm Configuration Daemon

cScm – is a tool to convert SCM configuration files into binary format and store its in shared memory for reading by cSvn-ui and cGit-ui CGI scripts

12 Commits   0 Branches   1 Tag
Index: symtab.c
===================================================================
--- symtab.c	(nonexistent)
+++ symtab.c	(revision 5)
@@ -0,0 +1,471 @@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include <defs.h>
+
+#include <main.h>
+#include <error.h>
+#include <msglog.h>
+#include <xalloc.h>
+#include <utf8ing.h>
+#include <lex.h>
+
+#include <symtab.h>
+#include <parse.h>
+
+
+SYMBOL *symlist = NULL;
+
+static SYMTAB *symtab  = NULL;
+
+static int constants_counter = 0;
+static int sections_counter  = 0;
+static int repos_counter     = 0;
+
+
+static SYMBOL *free_const( SYMBOL *sp )
+{
+  SYMBOL *next = NULL;
+
+  if( !sp ) return next;
+
+  next = sp->next;
+
+  free( sp->name );
+
+  switch( sp->type )
+  {
+    case STRING:
+      if( sp->u.string ) free( sp->u.string );
+      break;
+    case PATH:
+      if( sp->u.string ) free( sp->u.path );
+      break;
+
+    case NUMERICAL:
+    default:
+      break;
+  }
+
+  free( sp );
+
+  return next;
+}
+
+static void free_symlist( SYMBOL *sp );
+
+static SYMBOL *free_symbol( SYMBOL *sp )
+{
+  SYMBOL *next = NULL;
+
+  if( !sp ) return next;
+
+  if( sp->list ) (void)free_symlist( sp->list );
+
+  next = sp->next;
+
+  free( sp->name );
+
+  switch( sp->type )
+  {
+    case SECTION:
+    case STRING:
+      if( sp->u.string ) free( sp->u.string );
+      break;
+    case REPO:
+    case PATH:
+      if( sp->u.string ) free( sp->u.path );
+      break;
+
+    case VARIABLE:
+    case NUMERICAL:
+    default:
+      break;
+  }
+
+  free( sp );
+
+  return next;
+}
+
+static void free_symlist( SYMBOL *sp )
+{
+  SYMBOL *next = NULL;
+
+  if( !sp ) return;
+
+  next = free_symbol( sp );
+  while( next )
+  {
+    next = free_symbol( next );
+  }
+}
+
+/******************************************
+  Initialize the stak of symlist pointers:
+ */
+void init_symtab( void )
+{
+  SYMTAB *sa = (SYMTAB *)xmalloc( sizeof( SYMTAB ) );
+
+  symtab  = NULL;
+  symlist = NULL;
+
+  constants_counter = 0;
+  sections_counter  = 0;
+  repos_counter     = 0;
+
+  sa->symlist = (SYMBOL **)&symlist;
+  sa->next = symtab;
+  symtab = sa;
+}
+
+
+/*******************************************
+  Push the address of symlist to the stack:
+ */
+void push_symlist( SYMBOL **head )
+{
+  if( head )
+  {
+    SYMTAB  *sa = (SYMTAB *)xmalloc( sizeof( SYMTAB ) );
+
+    sa->symlist = head;
+    sa->next = symtab;
+    symtab = sa;
+  }
+}
+
+/********************************************
+  Pop the address of symlist from the stack:
+ */
+void pop_symlist( void )
+{
+  if( symtab && symtab->next )
+  {
+    SYMTAB *sa = symtab;
+    symtab = symtab->next;
+    free( sa );
+  }
+}
+
+/************************************
+  Free the stak of symlist pointers:
+ */
+void fini_symtab( void )
+{
+  if( !symtab ) return;
+
+  while( symtab )
+  {
+    SYMTAB *sa = symtab;
+    symtab = symtab->next;
+    free( sa );
+  }
+
+  constants_counter = 0;
+  sections_counter  = 0;
+  repos_counter     = 0;
+
+  symtab  = NULL;
+  free_symlist( symlist ); /* free main symlist */
+  symlist = NULL;
+}
+
+
+/******************************
+  Reverse symlist recursively:
+ */
+void reverse_symlist( SYMBOL **head )
+{
+  SYMBOL *prev = NULL, *curr = *head, *next;
+
+  while( curr )
+  {
+    if( curr->list ) reverse_symlist( (SYMBOL **)&(curr->list) );
+
+    next = curr->next;
+    curr->next = prev;
+    prev = curr;
+    curr = next;
+  }
+
+  *head = prev;
+}
+
+/******************************************************
+  Remove temporary constants from symlist recursively:
+ */
+void remove_consts( SYMBOL **head )
+{
+  SYMBOL *tmp = NULL;
+
+  while( *head )
+  {
+    tmp = *head;
+    if( !strncmp( tmp->name, "__const.", 8 ) )
+    {
+      *head = tmp->next;
+      (void)free_const( tmp );
+    }
+    else
+    {
+      head = &tmp->next;
+      if( tmp->list ) remove_consts( (SYMBOL **)&(tmp->list) );
+    }
+  }
+}
+
+
+SYMBOL *assign_value( SYMBOL *dest, SYMBOL *src )
+{
+  SYMBOL *ret = NULL;
+
+  if( !dest || !src ) return ret;
+
+  if( dest->type == VARIABLE ) /* always not initialized */
+  {
+    dest->type = src->type;
+    dest->u.value = 0;
+
+    switch( src->type )
+    {
+      case NUMERICAL:
+        dest->u.value = src->u.value;
+        break;
+      case STRING:
+        dest->u.string = strdup( (const char *)src->u.string );
+        break;
+      case PATH:
+        dest->u.path = strdup( (const char *)src->u.path );
+        break;
+      default:
+        /* error */
+        break;
+    }
+  }
+  else if( dest->type == STRING || dest->type == SECTION )
+  {
+    switch( src->type )
+    {
+      case STRING:
+        if( src->u.string )
+        {
+          if( dest->u.string ) free( dest->u.string );
+          dest->u.string = strdup( (const char *)src->u.string );
+        }
+        else
+        {
+          if( dest->u.string ) free( dest->u.string );
+          dest->u.string = NULL;
+        }
+        break;
+      default:
+        /* error */
+        break;
+    }
+  }
+  else if( dest->type == PATH || dest->type == REPO )
+  {
+    switch( src->type )
+    {
+      case PATH:
+        if( src->u.path )
+        {
+          if( dest->u.path ) free( dest->u.path );
+          dest->u.path = strdup( (const char *)src->u.path );
+        }
+        else
+        {
+          if( dest->u.path ) free( dest->u.path );
+          dest->u.path = NULL;
+        }
+        break;
+      default:
+        /* error */
+        break;
+    }
+  }
+  else if( dest->type == src->type )
+  {
+    switch( src->type )
+    {
+      case NUMERICAL:
+        dest->u.value = src->u.value;
+        break;
+      case STRING:
+        if( dest->u.string ) free( dest->u.string );
+        dest->u.string = strdup( (const char *)src->u.string );
+        break;
+      case PATH:
+        if( dest->u.path ) free( dest->u.path );
+        dest->u.path = strdup( (const char *)src->u.path );
+        break;
+      default:
+        /* error */
+        break;
+    }
+  }
+  else
+  {
+    /* error */
+  }
+
+  return dest;
+}
+
+
+SYMBOL *install( const char *s, int type, ... )
+{
+  SYMBOL *sp       = NULL;
+  char    name[80] = "__undef";
+
+  if( !symtab ) return sp;
+
+  va_list  argp;
+
+  if( ! type ) return( sp );
+
+  sp = (SYMBOL *)xmalloc( sizeof( SYMBOL ) );
+
+  switch( type )
+  {
+    case NUMERICAL:
+    case STRING:
+    case PATH:
+      sprintf( (char *)&name[0], "__const.%d", constants_counter++ );
+      sp->name = strdup( (const char *)&name[0] );
+      break;
+    case REPO:
+      sprintf( (char *)&name[0], "__repo.%d", repos_counter++ );
+      sp->name = strdup( (const char *)&name[0] );
+      break;
+    case SECTION:
+      sprintf( (char *)&name[0], "__section.%d", sections_counter++ );
+      sp->name = strdup( (const char *)&name[0] );
+      break;
+    default:
+      if( !s )
+        sp->name = strdup( (const char *)&name[0] );
+      else
+        sp->name = strdup( s );
+      break;
+  }
+  sp->type  = type;
+
+  va_start( argp, type );
+
+  switch( type )
+  {
+    case SECTION:
+    case STRING:
+    {
+      char *string = (char *)va_arg( argp, char * );
+      if( string ) sp->u.string = strdup( (const char *)string );
+      break;
+    }
+    case REPO:
+    case PATH:
+    {
+      char *path = (char *)va_arg( argp, char * );
+      if( path ) sp->u.path = strdup( (const char *)path );
+      break;
+    }
+
+    case VARIABLE:
+    case NUMERICAL:
+    default:
+      sp->u.value = (int)va_arg( argp, int );
+      break;
+  }
+
+  sp->next  = *(symtab->symlist);  /* alloc in begin of list */
+  *(symtab->symlist) = sp;
+
+  return( sp );
+}
+
+/***********************************
+  Find variable in current symlist:
+ */
+SYMBOL *lookup( const char *s )
+{
+  SYMBOL *sp;
+
+  for( sp = *(symtab->symlist); sp != (SYMBOL *)0; sp = sp->next )
+  {
+    if( strcmp( sp->name, s ) == 0 ) return( sp );
+  }
+
+  return( 0 );  /* запись не найдена */
+}
+
+/*********************************
+  Find section in global symlist:
+ */
+SYMBOL *lookup_section( const char *s )
+{
+  SYMBOL *sp;
+
+  for( sp = symlist; sp != (SYMBOL *)0; sp = sp->next )
+  {
+    if( sp->type == SECTION && sp->u.string && strcmp( sp->u.string, s ) == 0 ) return( sp );
+  }
+
+  return( 0 );  /* запись не найдена */
+}
+
+/********************************
+  Find repo globally in symlist:
+ */
+#if 0
+SYMBOL *lookup_repo_global( const char *s )
+{
+  SYMBOL *sp;
+
+  for( sp = symlist; sp != (SYMBOL *)0; sp = sp->next )
+  {
+    /***************************
+      lookup in global section:
+     */
+    if( sp->type == REPO && sp->u.path && strcmp( sp->u.path, s ) == 0 ) return( sp );
+
+    /*************************
+      lookup in each section:
+     */
+    if( sp->type == SECTION && sp->list )
+    {
+      SYMBOL *rp;
+      for( rp = sp->list; rp != (SYMBOL *)0; rp = rp->next )
+      {
+        if( rp->type == REPO && rp->u.path && strcmp( rp->u.path, s ) == 0 ) return( rp );
+      }
+    }
+  }
+
+  return( 0 );  /* запись не найдена */
+}
+#endif
+
+/*******************************
+  Find repo in current symlist:
+ */
+SYMBOL *lookup_repo( const char *s )
+{
+  SYMBOL *sp;
+
+  for( sp = *(symtab->symlist); sp != (SYMBOL *)0; sp = sp->next )
+  {
+    if( sp->type == REPO && sp->u.path && strcmp( sp->u.path, s ) == 0 ) return( sp );
+  }
+
+  return( 0 );  /* запись не найдена */
+}