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 again:
135 // print("phi=%i name= %s\n", phi, lexem_getname( plex ) + off );
136 if ( !phi )
137 goto error;
138
139 pm = ( pmacro )( phi + 1 );
140 plexsrc = &pm->mr.vallexem;
141 if ( !plexsrc->type ) // Alias macro
142 {
143 wsprintf( temp, "%s.%s", hash_name( &_compile->names, plexsrc->nameid ),
144 lexem_getname( plex ) + off );
145 phi = hash_find( macrohash, temp );
146 goto again;
147 }
148 if ( pm->flag & MACROF_GROUP ) // Must be a dot in the next lexem
149 {
150 plexem nlex;
151
152 nlex = lexem_next( plex, 0 );
153 if ( !lexem_isys( nlex, LSYS_DOT ))
154 goto error;
155 nlex->type = LEXEM_SKIP;
156 nlex = lexem_next( nlex, LEXNEXT_NAMEDEF );
157 if ( nlex->type != LEXEM_NAME )
158 goto error;
159 nlex->type = LEXEM_SKIP;
160 wsprintf( temp, "%s.%s", lexem_getname( plex ) + off,
161 lexem_getname( nlex ));
162 phi = hash_find( macrohash, temp );
163 goto again;
164 }
165 if ( pm->flag & MACROF_PREDEF )
166 {
167 if ( plexsrc->nameid > MACRO_TIME )
168 {
169 plex->type = LEXEM_NUMBER;
170 plex->num.type = TUint;
171 }
172 else
173 {
174 out = str_init( ( pstr )arr_append( &_compile->string ));
175 plex->type = LEXEM_STRING;
176 plex->strid = arr_count( &_compile->string ) - 1;
177 #ifdef LINUX
178 gettimeofday( &ftime, 0 );
179 localtime_r( &ftime.tv_sec, &tmt );
180 #else
181 GetLocalTime( &st );
182 #endif
183 }
184 switch ( plexsrc->nameid )
185 {
186 case MACRO_FILE:
187 str_copy( out, _compile->cur->filename );
188 break;
189 case MACRO_DATE:
190 #ifdef LINUX
191 wsprintf( temp, "%02i%02i%i", tmt.tm_mday, tmt.tm_mon, tmt.tm_year );
192 #else
193 wsprintf( temp, "%02i%02i%i", st.wDay, st.wMonth, st.wYear );
194 #endif
195 str_copyzero( out, temp );
196 break;
197 case MACRO_TIME:
198 #ifdef LINUX
199 wsprintf( temp, "%02i%02i%02i", tmt.tm_hour, tmt.tm_min, tmt.tm_sec );
200 #else
201 wsprintf( temp, "%02i%02i%02i", st.wHour, st.wMinute, st.wSecond );
202 #endif
203 str_copyzero( out, temp );
204 break;
205 case MACRO_LINE:
206 plex->num.vint = str_pos2line( _compile->cur->src, plex->pos, &pos );
207 break;
208 case MACRO_WINDOWS:
209 #ifdef WINDOWS
210 plex->num.vint = 1;
211 #else
212 plex->num.vint = 0;
213 #endif
214 break;
215 case MACRO_LINUX:
216 #ifdef LINUX
217 plex->num.vint = 1;
218 #else
219 plex->num.vint = 0;
220 #endif
221 break;
222 }
223 }
224 else
225 {
226 lexem_copy( plex, plexsrc );
227 }
228 // printf("Macro=%s\n", lexem_getname( plex ));
229 return plex;
230 error:
231 if ( plex->type == LEXEM_NAME )
232 return plex;
233
234 msg( MUndefmacro | MSG_LEXNAMEERR, plex );
235 return 0;
236 }