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

2 Commits   0 Branches   1 Tag
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   1) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   2) #ifdef HAVE_CONFIG_H
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   3) #include <config.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   4) #endif
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   5) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   6) #include <stdlib.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   7) #include <stdio.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   8) #include <string.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300   9) #include <stdarg.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  10) #include <unistd.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  11) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  12) #include <defs.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  13) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  14) #include <main.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  15) #include <error.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  16) #include <msglog.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  17) #include <xalloc.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  18) #include <utf8ing.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  19) #include <lex.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  20) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  21) #include <symtab.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  22) #include <parse.h>
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  23) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  24) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  25) SYMBOL *symlist = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  26) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  27) static SYMTAB *symtab  = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  28) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  29) static int constants_counter = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  30) static int sections_counter  = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  31) static int repos_counter     = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  32) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  33) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  34) static SYMBOL *free_const( SYMBOL *sp )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  35) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  36)   SYMBOL *next = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  37) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  38)   if( !sp ) return next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  39) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  40)   next = sp->next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  41) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  42)   free( sp->name );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  43) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  44)   switch( sp->type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  45)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  46)     case STRING:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  47)       if( sp->u.string ) free( sp->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  48)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  49)     case PATH:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  50)       if( sp->u.string ) free( sp->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  51)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  52) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  53)     case NUMERICAL:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  54)     default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  55)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  56)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  57) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  58)   free( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  59) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  60)   return next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  61) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  62) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  63) static void free_symlist( SYMBOL *sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  64) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  65) static SYMBOL *free_symbol( SYMBOL *sp )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  66) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  67)   SYMBOL *next = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  68) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  69)   if( !sp ) return next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  70) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  71)   if( sp->list ) (void)free_symlist( sp->list );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  72) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  73)   next = sp->next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  74) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  75)   free( sp->name );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  76) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  77)   switch( sp->type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  78)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  79)     case SECTION:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  80)     case STRING:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  81)       if( sp->u.string ) free( sp->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  82)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  83)     case REPO:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  84)     case PATH:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  85)       if( sp->u.string ) free( sp->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  86)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  87) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  88)     case VARIABLE:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  89)     case NUMERICAL:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  90)     default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  91)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  92)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  93) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  94)   free( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  95) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  96)   return next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  97) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  98) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300  99) static void free_symlist( SYMBOL *sp )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 100) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 101)   SYMBOL *next = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 102) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 103)   if( !sp ) return;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 104) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 105)   next = free_symbol( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 106)   while( next )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 107)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 108)     next = free_symbol( next );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 109)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 110) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 111) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 112) /******************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 113)   Initialize the stak of symlist pointers:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 114)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 115) void init_symtab( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 116) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 117)   SYMTAB *sa = (SYMTAB *)xmalloc( sizeof( SYMTAB ) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 118) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 119)   symtab  = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 120)   symlist = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 121) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 122)   constants_counter = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 123)   sections_counter  = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 124)   repos_counter     = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 125) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 126)   sa->symlist = (SYMBOL **)&symlist;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 127)   sa->next = symtab;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 128)   symtab = sa;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 129) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 130) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 131) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 132) /*******************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 133)   Push the address of symlist to the stack:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 134)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 135) void push_symlist( SYMBOL **head )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 136) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 137)   if( head )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 138)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 139)     SYMTAB  *sa = (SYMTAB *)xmalloc( sizeof( SYMTAB ) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 140) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 141)     sa->symlist = head;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 142)     sa->next = symtab;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 143)     symtab = sa;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 144)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 145) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 146) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 147) /********************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 148)   Pop the address of symlist from the stack:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 149)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 150) void pop_symlist( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 151) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 152)   if( symtab && symtab->next )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 153)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 154)     SYMTAB *sa = symtab;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 155)     symtab = symtab->next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 156)     free( sa );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 157)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 158) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 159) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 160) /************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 161)   Free the stak of symlist pointers:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 162)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 163) void fini_symtab( void )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 164) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 165)   if( !symtab ) return;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 166) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 167)   while( symtab )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 168)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 169)     SYMTAB *sa = symtab;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 170)     symtab = symtab->next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 171)     free( sa );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 172)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 173) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 174)   constants_counter = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 175)   sections_counter  = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 176)   repos_counter     = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 177) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 178)   symtab  = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 179)   free_symlist( symlist ); /* free main symlist */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 180)   symlist = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 181) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 182) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 183) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 184) /******************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 185)   Reverse symlist recursively:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 186)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 187) void reverse_symlist( SYMBOL **head )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 188) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 189)   SYMBOL *prev = NULL, *curr = *head, *next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 190) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 191)   while( curr )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 192)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 193)     if( curr->list ) reverse_symlist( (SYMBOL **)&(curr->list) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 194) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 195)     next = curr->next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 196)     curr->next = prev;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 197)     prev = curr;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 198)     curr = next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 199)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 200) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 201)   *head = prev;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 202) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 203) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 204) /******************************************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 205)   Remove temporary constants from symlist recursively:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 206)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 207) void remove_consts( SYMBOL **head )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 208) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 209)   SYMBOL *tmp = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 210) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 211)   while( *head )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 212)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 213)     tmp = *head;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 214)     if( !strncmp( tmp->name, "__const.", 8 ) )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 215)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 216)       *head = tmp->next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 217)       (void)free_const( tmp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 218)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 219)     else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 220)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 221)       head = &tmp->next;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 222)       if( tmp->list ) remove_consts( (SYMBOL **)&(tmp->list) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 223)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 224)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 225) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 226) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 227) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 228) SYMBOL *assign_value( SYMBOL *dest, SYMBOL *src )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 229) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 230)   SYMBOL *ret = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 231) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 232)   if( !dest || !src ) return ret;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 233) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 234)   if( dest->type == VARIABLE ) /* always not initialized */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 235)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 236)     dest->type = src->type;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 237)     dest->u.value = 0;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 238) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 239)     switch( src->type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 240)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 241)       case NUMERICAL:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 242)         dest->u.value = src->u.value;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 243)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 244)       case STRING:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 245)         dest->u.string = strdup( (const char *)src->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 246)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 247)       case PATH:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 248)         dest->u.path = strdup( (const char *)src->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 249)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 250)       default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 251)         /* error */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 252)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 253)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 254)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 255)   else if( dest->type == STRING || dest->type == SECTION )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 256)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 257)     switch( src->type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 258)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 259)       case STRING:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 260)         if( src->u.string )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 261)         {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 262)           if( dest->u.string ) free( dest->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 263)           dest->u.string = strdup( (const char *)src->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 264)         }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 265)         else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 266)         {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 267)           if( dest->u.string ) free( dest->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 268)           dest->u.string = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 269)         }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 270)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 271)       default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 272)         /* error */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 273)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 274)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 275)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 276)   else if( dest->type == PATH || dest->type == REPO )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 277)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 278)     switch( src->type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 279)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 280)       case PATH:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 281)         if( src->u.path )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 282)         {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 283)           if( dest->u.path ) free( dest->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 284)           dest->u.path = strdup( (const char *)src->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 285)         }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 286)         else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 287)         {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 288)           if( dest->u.path ) free( dest->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 289)           dest->u.path = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 290)         }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 291)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 292)       default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 293)         /* error */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 294)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 295)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 296)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 297)   else if( dest->type == src->type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 298)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 299)     switch( src->type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 300)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 301)       case NUMERICAL:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 302)         dest->u.value = src->u.value;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 303)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 304)       case STRING:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 305)         if( dest->u.string ) free( dest->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 306)         dest->u.string = strdup( (const char *)src->u.string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 307)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 308)       case PATH:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 309)         if( dest->u.path ) free( dest->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 310)         dest->u.path = strdup( (const char *)src->u.path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 311)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 312)       default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 313)         /* error */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 314)         break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 315)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 316)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 317)   else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 318)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 319)     /* error */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 320)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 321) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 322)   return dest;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 323) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 324) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 325) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 326) SYMBOL *install( const char *s, int type, ... )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 327) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 328)   SYMBOL *sp       = NULL;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 329)   char    name[80] = "__undef";
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 330) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 331)   if( !symtab ) return sp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 332) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 333)   va_list  argp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 334) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 335)   if( ! type ) return( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 336) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 337)   sp = (SYMBOL *)xmalloc( sizeof( SYMBOL ) );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 338) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 339)   switch( type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 340)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 341)     case NUMERICAL:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 342)     case STRING:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 343)     case PATH:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 344)       sprintf( (char *)&name[0], "__const.%d", constants_counter++ );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 345)       sp->name = strdup( (const char *)&name[0] );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 346)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 347)     case REPO:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 348)       sprintf( (char *)&name[0], "__repo.%d", repos_counter++ );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 349)       sp->name = strdup( (const char *)&name[0] );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 350)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 351)     case SECTION:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 352)       sprintf( (char *)&name[0], "__section.%d", sections_counter++ );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 353)       sp->name = strdup( (const char *)&name[0] );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 354)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 355)     default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 356)       if( !s )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 357)         sp->name = strdup( (const char *)&name[0] );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 358)       else
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 359)         sp->name = strdup( s );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 360)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 361)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 362)   sp->type  = type;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 363) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 364)   va_start( argp, type );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 365) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 366)   switch( type )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 367)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 368)     case SECTION:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 369)     case STRING:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 370)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 371)       char *string = (char *)va_arg( argp, char * );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 372)       if( string ) sp->u.string = strdup( (const char *)string );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 373)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 374)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 375)     case REPO:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 376)     case PATH:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 377)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 378)       char *path = (char *)va_arg( argp, char * );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 379)       if( path ) sp->u.path = strdup( (const char *)path );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 380)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 381)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 382) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 383)     case VARIABLE:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 384)     case NUMERICAL:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 385)     default:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 386)       sp->u.value = (int)va_arg( argp, int );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 387)       break;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 388)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 389) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 390)   sp->next  = *(symtab->symlist);  /* alloc in begin of list */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 391)   *(symtab->symlist) = sp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 392) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 393)   return( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 394) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 395) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 396) /***********************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 397)   Find variable in current symlist:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 398)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 399) SYMBOL *lookup( const char *s )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 400) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 401)   SYMBOL *sp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 402) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 403)   for( sp = *(symtab->symlist); sp != (SYMBOL *)0; sp = sp->next )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 404)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 405)     if( strcmp( sp->name, s ) == 0 ) return( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 406)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 407) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 408)   return( 0 );  /* запись не найдена */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 409) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 410) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 411) /*********************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 412)   Find section in global symlist:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 413)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 414) SYMBOL *lookup_section( const char *s )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 415) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 416)   SYMBOL *sp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 417) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 418)   for( sp = symlist; sp != (SYMBOL *)0; sp = sp->next )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 419)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 420)     if( sp->type == SECTION && sp->u.string && strcmp( sp->u.string, s ) == 0 ) return( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 421)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 422) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 423)   return( 0 );  /* запись не найдена */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 424) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 425) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 426) /********************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 427)   Find repo globally in symlist:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 428)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 429) #if 0
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 430) SYMBOL *lookup_repo_global( const char *s )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 431) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 432)   SYMBOL *sp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 433) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 434)   for( sp = symlist; sp != (SYMBOL *)0; sp = sp->next )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 435)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 436)     /***************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 437)       lookup in global section:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 438)      */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 439)     if( sp->type == REPO && sp->u.path && strcmp( sp->u.path, s ) == 0 ) return( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 440) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 441)     /*************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 442)       lookup in each section:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 443)      */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 444)     if( sp->type == SECTION && sp->list )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 445)     {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 446)       SYMBOL *rp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 447)       for( rp = sp->list; rp != (SYMBOL *)0; rp = rp->next )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 448)       {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 449)         if( rp->type == REPO && rp->u.path && strcmp( rp->u.path, s ) == 0 ) return( rp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 450)       }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 451)     }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 452)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 453) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 454)   return( 0 );  /* запись не найдена */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 455) }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 456) #endif
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 457) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 458) /*******************************
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 459)   Find repo in current symlist:
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 460)  */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 461) SYMBOL *lookup_repo( const char *s )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 462) {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 463)   SYMBOL *sp;
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 464) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 465)   for( sp = *(symtab->symlist); sp != (SYMBOL *)0; sp = sp->next )
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 466)   {
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 467)     if( sp->type == REPO && sp->u.path && strcmp( sp->u.path, s ) == 0 ) return( sp );
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 468)   }
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 469) 
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 470)   return( 0 );  /* запись не найдена */
12c7b1c5 (kx 2023-03-24 02:53:04 +0300 471) }