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