1 /******************************************************************************
2 *
3 * Copyright (C) 2006, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: define 18.10.06 0.0.A.
11 *
12 * Author: Alexey Krivonogov ( gentee )
13 *
14 * Summary: macro functions
15 *
16 ******************************************************************************/
17
18 #include "../genteeapi/gentee.h"
19 #include "macro.h"
20
21 const pubyte defmacro[] = {
22 "_FILE","_DATE", "_TIME", "_LINE", "_WINDOWS", "_LINUX", ""
23 };
24
25 /*-----------------------------------------------------------------------------
26 *
27 * ID: macro_init 22.11.06 0.0.A.
28 *
29 * Summary: Create default macros
30 *
31 -----------------------------------------------------------------------------*/
32
33 uint STDCALL macro_init( void )
34 {
35 uint i = 0;
36 pmacro pm;
37
38 // Определяем предопределенные макросы
39 while ( *defmacro[ i ] )
40 {
41 pm = ( pmacro )( hash_create( &_compile->macros, defmacro[ i ] ) + 1 );
42 pm->mr.vallexem.type = LEXEM_STRING;
43 pm->mr.vallexem.nameid = i++;
44 pm->flag = MACROF_PREDEF;
45 }
46 return i;
47 }
48
49 /*-----------------------------------------------------------------------------
50 *
51 * ID: macro_set 22.11.06 0.0.A.
52 *
53 * Summary: Set macro value
54 *
55 -----------------------------------------------------------------------------*/
56
57 pmacro STDCALL macro_set( plexem plex, uint type, uint group )
58 {
59 ubyte fullname[256];
60 pmacro pm;
61 pubyte name;
62 phash macrohash;
63 uint namedef = 0;
64
65 if ( type & MACRO_NAMEDEF )
66 {
67 type &= ~MACRO_NAMEDEF;
68 macrohash = &_compile->namedef;
69 namedef = MACRO_NAMEDEF;
70 }
71 else
72 macrohash = &_compile->macros;
73
74 name = lexem_getname( plex );
75 if ( group )
76 {
77 pmacro palias = macro_set( plex, namedef, 0 );
78 // nameid saves the identifier of the group name
79 if ( !palias->mr.vallexem.type )
80 palias->mr.vallexem.nameid = group - 1;
81
82 wsprintf( fullname, "%s.%s", hash_name( &_compile->names, group - 1 ),
83 name );
84 name = ( pubyte )&fullname;
85 // printf("GROUP=%i %s %s\n", group, groupname, name );
86 }
87 pm = ( pmacro )( hash_create( macrohash, name ) + 1 );
88
89 // print("create=%s\n", name );
90 if ( pm->flag & MACROF_PREDEF || pm->flag & MACROF_GROUP )
91 msg( MWrongname | MSG_LEXNAMEERR, plex );
92
93 if ( !pm->mr.vallexem.type )
94 {
95 pm->mr.vallexem.type = ( ubyte )type;
96 // pm->mr.vallexem.nameid = id;
97 }
98 return pm;
99 }
100
101 /*-----------------------------------------------------------------------------
102 *
103 * ID: macro_get 22.11.06 0.0.A.
104 *
105 * Summary: Get macro value
106 *
107 -----------------------------------------------------------------------------*/
108
109 plexem STDCALL macro_get( plexem plex )
110 {
111 ubyte temp[ 256 ];
112 uint pos, off = 1;
113 pstr out;
114 pmacro pm;
115 plexem plexsrc;
116 phashitem phi;
117 phash macrohash;
118 #ifdef LINUX
119 struct timespec ftime;
120 //timezone ztime;
121 struct tm tmt;
122 #else
123 SYSTEMTIME st;
124 #endif
125 if ( plex->type == LEXEM_NAME )
126 {
127 macrohash = &_compile->namedef;
128 off = 0;
129 }
130 else
131 macrohash = &_compile->macros;
132
133 phi = hash_find( macrohash, lexem_getname( plex ) + off );
134 if ( !phi && plex->type != LEXEM_NAME )
135 phi = hash_find( macrohash, "_DEFAULT" );
136
137 again:
138 // print("phi=%i name= %s\n", phi, lexem_getname( plex ) + off );
139 if ( !phi )
140 goto error;
141
142 pm = ( pmacro )( phi + 1 );
143 plexsrc = &pm->mr.vallexem;
144 if ( !plexsrc->type ) // Alias macro
145 {
146 wsprintf( temp, "%s.%s", hash_name( &_compile->names, plexsrc->nameid ),
147 lexem_getname( plex ) + off );
148 phi = hash_find( macrohash, temp );
149 goto again;
150 }
151 if ( pm->flag & MACROF_GROUP ) // Must be a dot in the next lexem
152 {
153 plexem nlex;
154
155 nlex = lexem_next( plex, 0 );
156 if ( !lexem_isys( nlex, LSYS_DOT ))
157 goto error;
158 nlex->type = LEXEM_SKIP;
159 nlex = lexem_next( nlex, LEXNEXT_NAMEDEF );
160 if ( nlex->type != LEXEM_NAME )
161 goto error;
162 nlex->type = LEXEM_SKIP;
163 wsprintf( temp, "%s.%s", lexem_getname( plex ) + off,
164 lexem_getname( nlex ));
165 phi = hash_find( macrohash, temp );
166 goto again;
167 }
168 if ( pm->flag & MACROF_PREDEF )
169 {
170 if ( plexsrc->nameid > MACRO_TIME )
171 {
172 plex->type = LEXEM_NUMBER;
173 plex->num.type = TUint;
174 }
175 else
176 {
177 out = str_init( ( pstr )arr_append( &_compile->string ));
178 plex->type = LEXEM_STRING;
179 plex->strid = arr_count( &_compile->string ) - 1;
180 #ifdef LINUX
181 gettimeofday( &ftime, 0 );
182 localtime_r( &ftime.tv_sec, &tmt );
183 #else
184 GetLocalTime( &st );
185 #endif
186 }
187 switch ( plexsrc->nameid )
188 {
189 case MACRO_FILE:
190 str_copy( out, _compile->cur->filename );
191 break;
192 case MACRO_DATE:
193 #ifdef LINUX
194 wsprintf( temp, "%02i%02i%i", tmt.tm_mday, tmt.tm_mon, tmt.tm_year );
195 #else
196 wsprintf( temp, "%02i%02i%i", st.wDay, st.wMonth, st.wYear );
197 #endif
198 str_copyzero( out, temp );
199 break;
200 case MACRO_TIME:
201 #ifdef LINUX
202 wsprintf( temp, "%02i%02i%02i", tmt.tm_hour, tmt.tm_min, tmt.tm_sec );
203 #else
204 wsprintf( temp, "%02i%02i%02i", st.wHour, st.wMinute, st.wSecond );
205 #endif
206 str_copyzero( out, temp );
207 break;
208 case MACRO_LINE:
209 plex->num.vint = str_pos2line( _compile->cur->src, plex->pos, &pos );
210 break;
211 case MACRO_WINDOWS:
212 #ifdef WINDOWS
213 plex->num.vint = 1;
214 #else
215 plex->num.vint = 0;
216 #endif
217 break;
218 case MACRO_LINUX:
219 #ifdef LINUX
220 plex->num.vint = 1;
221 #else
222 plex->num.vint = 0;
223 #endif
224 break;
225 }
226 }
227 else
228 {
229 lexem_copy( plex, plexsrc );
230 }
231 // printf("Macro=%s\n", lexem_getname( plex ));
232 return plex;
233 error:
234 if ( plex->type == LEXEM_NAME )
235 return plex;
236
237 msg( MUndefmacro | MSG_LEXNAMEERR, plex );
238 return 0;
239 }
240