~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to libshadervm/dsoshadeops.cpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Aqsis
 
2
// Copyright ļæ½ 1997 - 2001, Paul C. Gregory // // Contact: pgregory@aqsis.com //
 
3
// This library is free software; you can redistribute it and/or
 
4
// modify it under the terms of the GNU General Public
 
5
// License as published by the Free Software Foundation; either
 
6
// version 2 of the License, or (at your option) any later version.
 
7
//
 
8
// This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
10
// General Public License for more details.
 
11
//
 
12
// You should have received a copy of the GNU General Public
 
13
// License along with this library; if not, write to the Free Software
 
14
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
 
 
16
/** \file
 
17
                \brief Implements the classes and support structures for DSO shadeops
 
18
                \author Tristan Colgate <tristan@inuxtech.co.uk>
 
19
*/
 
20
 
 
21
#include <sys/stat.h>
 
22
 
 
23
#include        "aqsis.h"
 
24
#include        "sstring.h"
 
25
#include        "irenderer.h"
 
26
#include        "ishaderdata.h"
 
27
#include        "dsoshadeops.h"
 
28
#include        "file.h"
 
29
#include        "logging.h"
 
30
 
 
31
START_NAMESPACE( Aqsis )
 
32
 
 
33
//---------------------------------------------------------------------
 
34
/** This does replicate effort from CqFile and at present doesnt handle NT either
 
35
 ** There is a distinction in that we would like to handle directories here which CqFile doesnt
 
36
 */
 
37
 
 
38
CqString
 
39
CqDSORepository::strPrototype(CqString *strFuncName, SqDSOExternalCall *pExtCall)
 
40
{
 
41
    CqString strProt;
 
42
    EqVariableType type;
 
43
 
 
44
    type = pExtCall->return_type;
 
45
    m_itTypeNameMap = m_TypeNameMap.begin();
 
46
    while (m_itTypeNameMap != m_TypeNameMap.end() &&
 
47
            (*m_itTypeNameMap).second != type)
 
48
    {
 
49
        m_itTypeNameMap++ ;
 
50
    };
 
51
    if(m_itTypeNameMap != m_TypeNameMap.end()){
 
52
        strProt = (*m_itTypeNameMap).first + " ";
 
53
    }else{
 
54
        strProt += "Unkown ";
 
55
    };
 
56
 
 
57
    strProt += *strFuncName + " ( ";
 
58
 
 
59
    std::list<EqVariableType>::iterator it = pExtCall->arg_types.begin();
 
60
    while( it != pExtCall->arg_types.end()){
 
61
        type = (*it);
 
62
        m_itTypeNameMap = m_TypeNameMap.begin();
 
63
        while (m_itTypeNameMap != m_TypeNameMap.end() &&
 
64
                (*m_itTypeNameMap).second != type)
 
65
        {
 
66
            m_itTypeNameMap++ ;
 
67
        };
 
68
        if(m_itTypeNameMap != m_TypeNameMap.end()){
 
69
            strProt += (*m_itTypeNameMap).first + " ";
 
70
        }else{
 
71
            strProt += "Unkown ";
 
72
        };
 
73
 
 
74
        it++ ;
 
75
    };
 
76
 
 
77
    strProt += ")";
 
78
 
 
79
    return strProt;
 
80
};
 
81
 
 
82
//---------------------------------------------------------------------
 
83
/** This does replicate effort from CqFile and at present doesnt handle NT either
 
84
 ** There is a distinction in that we would like to handle directories here which CqFile doesnt
 
85
 */
 
86
void
 
87
CqDSORepository::SetDSOPath(const CqString* pPath)
 
88
{
 
89
    CqString::size_type iLeft = 0;
 
90
    CqString::size_type iRight = iLeft ;
 
91
 
 
92
    if ( pPath == NULL ) return;
 
93
 
 
94
    // Split the string up into the components of the path;
 
95
    while(iRight <= pPath->length())
 
96
    {
 
97
        if (    ( *pPath)[iRight] == ';' ||  // completed a path element with ';'
 
98
                ( ( *pPath)[iRight] == ':' && ( iRight - iLeft ) > 1) || // completed a path element ':'
 
99
                ( iRight+1 > pPath->length() && iLeft != iRight) ) // hit end of list
 
100
        {
 
101
            CqString *element = new CqString(pPath->substr(iLeft,iRight - iLeft));
 
102
            // Here, if element points to a directory, we can add each library in the
 
103
            // named directory which is not already in the path list
 
104
 
 
105
            struct stat s;
 
106
            if (!stat( element->c_str(), &s ))
 
107
            {
 
108
                if ( S_ISDIR(s.st_mode) )
 
109
                {
 
110
                    // We have a directory, list all the libraries in that directory and add them to the path
 
111
                    CqString wild = *element + CqString( DIRSEP ) + CqString( "*" ) + CqString ( SHARED_LIBRARY_SUFFIX );
 
112
                    std::list<CqString*> files = Aqsis::CqFile::Glob(wild);
 
113
                    if ( !files.empty() )
 
114
                    {
 
115
                        m_pDSOPathList.splice(m_pDSOPathList.end(), files);
 
116
                    }
 
117
                    delete(element);
 
118
                }
 
119
                else
 
120
                {
 
121
                    m_pDSOPathList.push_back(element);
 
122
                }
 
123
            }
 
124
            else
 
125
                delete(element);
 
126
        }
 
127
 
 
128
        if (    ( *pPath)[iRight] == ';' ||  // completed a path element with ';'
 
129
                ( ( *pPath)[iRight] == ':' && ( iRight - iLeft ) > 1) ) // completed a path element ':'
 
130
            iLeft = iRight + 1  ;
 
131
        iRight ++ ;
 
132
    };
 
133
};
 
134
 
 
135
 
 
136
//---------------------------------------------------------------------
 
137
/**  This returns a list of descriptors of calls to external DSO functions that
 
138
 * implement a named shadeop, entries are returned for each polymorphic function
 
139
 */
 
140
std::list<SqDSOExternalCall*>*
 
141
CqDSORepository::getShadeOpMethods(CqString* pShadeOpName)
 
142
{
 
143
    CqString strTableSymbol = *pShadeOpName + "_shadeops" ;
 
144
 
 
145
    std::list<SqDSOExternalCall*>* oplist = new (std::list<SqDSOExternalCall*>);
 
146
    std::list<CqString*>::iterator itPathEntry;
 
147
    SqShadeOp *pTableSymbol = NULL;
 
148
 
 
149
 
 
150
    for ( itPathEntry = m_pDSOPathList.begin() ; itPathEntry != m_pDSOPathList.end() ; itPathEntry++ )
 
151
    {
 
152
        void *handle = DLOpen( (*itPathEntry) );
 
153
 
 
154
        if( handle != NULL )
 
155
        {
 
156
            pTableSymbol = (SqShadeOp*) DLSym( handle, &strTableSymbol );
 
157
 
 
158
            if ( pTableSymbol != NULL )
 
159
            {
 
160
                //We have an appropriate named shadeop table
 
161
                SqShadeOp *pShadeOp = (SqShadeOp*) pTableSymbol;
 
162
                while( ( pShadeOp->m_opspec )[0] != (char) NULL )
 
163
                {
 
164
                    SqDSOExternalCall *pDSOCall = NULL;
 
165
                    pDSOCall = parseShadeOpTableEntry( handle, pShadeOp );
 
166
                    if ( pDSOCall != NULL )
 
167
                        oplist->push_back( pDSOCall );
 
168
 
 
169
                    pShadeOp++;
 
170
                };
 
171
            };
 
172
 
 
173
            // Failure here does not neccesarily mean anything since
 
174
        }
 
175
        else
 
176
        {
 
177
            CqString strError = DLError();
 
178
            std::cerr << error << "DLOpen: " << strError.c_str() << std::endl;
 
179
        };
 
180
    };
 
181
    return ( oplist->empty() ? NULL : oplist );
 
182
};
 
183
 
 
184
//---------------------------------------------------------------------
 
185
/** We have found a plugins with the desried shadeop table in it
 
186
 * For each shaeop table entry we parse the prototype and validate all
 
187
 * symbols that are named by the shadeop entry.
 
188
 */
 
189
 
 
190
SqDSOExternalCall*
 
191
CqDSORepository::parseShadeOpTableEntry(void* handle, SqShadeOp* pShadeOpEntry){
 
192
 
 
193
    TqInt length = strlen(pShadeOpEntry->m_opspec)+1;
 
194
    char temp[1024];
 
195
    strncpy(temp, pShadeOpEntry->m_opspec,length);
 
196
 
 
197
    // We remove all the '(),' charachters, so we are left with
 
198
    //   returntype name argtype ...
 
199
    for (int x = 0; x < length; x++)
 
200
        if(temp[x]=='('||temp[x]==')'||temp[x]==',')temp[x]=' ';
 
201
 
 
202
    CqString strSpec(temp);
 
203
 
 
204
    // Get the return type of the function
 
205
    std::string strRetType;
 
206
 
 
207
 
 
208
    strRetType = strtok(temp, " ");
 
209
    m_itTypeNameMap = m_TypeNameMap.find(strRetType.c_str());
 
210
 
 
211
    // ERROR if we cant find this types name;
 
212
    if (m_itTypeNameMap == m_TypeNameMap.end())
 
213
    {
 
214
        std::cerr << warning << "Discarding DSO Table entry due to unsupported return type: \"" << strRetType.c_str() << "\"" << std::endl;
 
215
        return NULL;
 
216
    }
 
217
    EqVariableType rettype = (*m_itTypeNameMap).second;
 
218
 
 
219
 
 
220
    // Get function name
 
221
    std::string strMethodName;
 
222
 
 
223
    strMethodName = strtok(NULL, " ");
 
224
    CqString s = strMethodName.c_str();
 
225
    DSOMethod method = (DSOMethod) DLSym (handle,&s);
 
226
    if(method == NULL)
 
227
    {
 
228
        std::cerr << warning << "Discarding DSO Table entry due to unknown symbol for method: \"" << strMethodName.c_str() << "\"" << std::endl;
 
229
        return NULL;
 
230
    };
 
231
 
 
232
 
 
233
    // Parse each arg type, presumably we need to handle arrays here
 
234
    std::list<EqVariableType> arglist;
 
235
    char *nextarg = NULL;
 
236
    do
 
237
    {
 
238
        // Get the next arguments type
 
239
        std::string strArgType;
 
240
 
 
241
        nextarg = strtok(NULL, " ");
 
242
        if (nextarg == NULL) break;
 
243
        strArgType = nextarg;
 
244
        m_itTypeNameMap = m_TypeNameMap.find(strArgType.c_str());
 
245
 
 
246
        // ERROR if we cant find this arguments type name;
 
247
        if (m_itTypeNameMap == m_TypeNameMap.end())
 
248
        {
 
249
            std::cerr << warning << "Discarding DSO Table entry due to unsupported argument type: \"" << strArgType.c_str() << "\"" << std::endl;
 
250
            return NULL;
 
251
        };
 
252
        arglist.push_back((*m_itTypeNameMap).second);
 
253
 
 
254
    }while(nextarg);
 
255
 
 
256
    // Check if there is a valid init function
 
257
    CqString strInit = pShadeOpEntry->m_init;
 
258
    DSOInit initfunc = NULL;
 
259
    if (strcmp(pShadeOpEntry->m_init,""))
 
260
    {
 
261
        initfunc = (DSOInit) DLSym(handle,&strInit);
 
262
        if (initfunc == NULL)
 
263
        {
 
264
            std::cerr << warning << "Discarding DSO Table entry due to unknown symbol for init: \"" << strInit.c_str() << "\"" << std::endl;
 
265
            return NULL; // ERROR ;
 
266
        };
 
267
    }
 
268
 
 
269
    // Check if there is a valid shutdown function
 
270
    CqString strShutdown = pShadeOpEntry->m_shutdown;
 
271
    DSOShutdown shutdownfunc = NULL;
 
272
    if (strcmp(pShadeOpEntry->m_shutdown,""))
 
273
    {
 
274
        shutdownfunc = (DSOShutdown) DLSym(handle,&strShutdown);
 
275
        if (shutdownfunc == NULL)
 
276
        {
 
277
            std::cerr << warning << "Discarding DSO Table entry due to unknown symbol for shutdown: \"" << strShutdown.c_str() << "\"" << std::endl;
 
278
            return NULL; // ERROR ;
 
279
        };
 
280
    };
 
281
 
 
282
 
 
283
    // We have a valid shadeop implementation
 
284
    SqDSOExternalCall *ret = new SqDSOExternalCall;
 
285
    ret->method = method;
 
286
    ret->init = initfunc;
 
287
    ret->shutdown = shutdownfunc;
 
288
    ret->return_type = rettype;
 
289
    ret->arg_types = arglist;
 
290
    ret->initData = NULL;
 
291
    ret->initialised = false;
 
292
 
 
293
    return ret;
 
294
};
 
295
 
 
296
 
 
297
END_NAMESPACE( Aqsis )
 
298
//---------------------------------------------------------------------