1
// This file is part of PUMA.
2
// Copyright (C) 1999-2003 The PUMA developer team.
4
// This program is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU General Public License as
6
// published by the Free Software Foundation; either version 2 of
7
// the License, or (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public
15
// License along with this program; if not, write to the Free
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
#ifndef __WinIfExists__
20
#define __WinIfExists__
22
/********************************************************/
23
/* Win __if_exists and __if_not_exists support aspect */
24
/********************************************************/
26
#include "Puma/Stack.h"
27
#include "Puma/CTokens.h"
28
#include "Puma/Token.h"
34
/********************************************************/
35
/* Win __if_exists and __if_not_exists */
36
/********************************************************/
38
// pointcut definitions
39
pointcut cpp () = classes ("Puma::PreprocessorParser");
41
// introduce data member into preprocessor
42
advice cpp () : Stack<unsigned> _depth;
44
// introduce method into preprocessor
45
advice cpp () : void skip_up_to (int);
47
// preprocess __if_exists and __if_not_exists statements
48
advice execution ("% Puma::PreprocessorParser::next()") : around () {
51
JoinPoint::That *preparser;
53
preparser = tjp->that ();
54
tjp->proceed (); // get the next token
55
token = *tjp->result ();
57
type = token->type ();
58
// __if_exists (...) { ... }
59
if (type == TOK_IF_EXISTS) {
60
preparser->skip_up_to (TOK_CLOSE_CURLY);
61
*(Token**)thisJoinPoint->result () = preparser->next ();
63
// __if_not_exists (...) { ... }
64
} else if (type == TOK_IF_NOT_EXISTS) {
65
preparser->skip_up_to (TOK_OPEN_CURLY);
66
preparser->_depth.push (1);
67
*(Token**)thisJoinPoint->result () = preparser->next ();
70
// skip closing `}' of __if_not_exists
71
if (preparser->_depth.length ()) {
72
if (type == TOK_OPEN_CURLY)
73
preparser->_depth.top () = preparser->_depth.top () + 1;
74
else if (type == TOK_CLOSE_CURLY) {
75
preparser->_depth.top () = preparser->_depth.top () - 1;
76
if (preparser->_depth.top () == 0) {
77
preparser->_depth.pop ();
78
*(Token**)thisJoinPoint->result () = preparser->next ();
90
// skip __if_exists resp. __if_not_exists statement
91
advice WinIfExists::cpp () : void WinIfExists::skip_up_to (int end_token) {
92
unsigned parenthesis = 0, curlies = 0;
96
// skip up to the first non-nested `{'
97
while ((token = parseToken ())) {
98
type = token->type ();
99
if (type == TOK_OPEN_CURLY) {
100
if (parenthesis == 0 && curlies == 0)
103
} else if (type == TOK_CLOSE_CURLY)
105
else if (type == TOK_OPEN_ROUND)
107
else if (type == TOK_CLOSE_ROUND)
111
// skip up to the first non-nested `}'
112
if (end_token == TOK_CLOSE_CURLY) {
113
parenthesis = curlies = 0;
114
while ((token = parseToken ())) {
115
type = token->type ();
116
if (type == TOK_OPEN_CURLY)
118
else if (type == TOK_CLOSE_CURLY) {
119
if (parenthesis == 0 && curlies == 0)
122
} else if (type == TOK_OPEN_ROUND)
124
else if (type == TOK_CLOSE_ROUND)
131
#endif /* __WinIfExists__ */