update dev300-m58
[ooovba.git] / sal / rtl / source / tres.c
blob0c591b7baeb6a6186dd17699c7ae198fad1c4afa
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tres.c,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <stdio.h>
32 #include <rtl/tres.h>
33 #include <osl/diagnose.h>
34 #include <osl/time.h>
36 /* force an assertion on false state */
37 #define TST_BOOM(c, m) OSL_ENSURE(c, m)
40 typedef struct _rtl_CmpState
42 struct _rtl_CmpState* m_next;
43 struct _rtl_CmpState* m_prev;
45 sal_Bool m_stat;
46 rtl_String* m_msg;
48 } rtl_CmpState;
50 typedef struct _rtl_FuncState
52 struct _rtl_FuncState* m_next;
53 struct _rtl_FuncState* m_prev;
54 rtl_String* m_name;
55 sal_uInt32 m_flags;
56 sal_uInt32 m_start;
57 sal_uInt32 m_stop;
58 struct _rtl_CmpState* m_cmp;
60 } rtl_FuncState;
64 typedef struct _rtl_TestResult_Data
66 rtl_TestResult_vtable* m_funcs;
67 void* m_externaldata;
69 rtl_FuncState* m_state;
71 } rtl_TestResult_Data;
74 /**
75 * internal helper functions
78 /* ...to create, link, unlink and destroy allocated memory */
79 rtl_FuncState* SAL_CALL rtl_tres_create_funcstate( const sal_Char* meth );
80 rtl_FuncState* SAL_CALL rtl_tres_link_funcstate( rtl_FuncState* ptr,
81 rtl_FuncState* plink );
82 rtl_FuncState* SAL_CALL rtl_tres_unlink_funcstate( rtl_FuncState* plink );
83 rtl_CmpState* SAL_CALL rtl_tres_create_cmpstate(
84 sal_Bool state,
85 const sal_Char* msg
87 rtl_CmpState* SAL_CALL rtl_tres_link_cmpstate( rtl_CmpState* ptr,
88 rtl_CmpState* plink );
89 rtl_CmpState* SAL_CALL rtl_tres_unlink_cmpstate( rtl_CmpState* plink );
90 sal_uInt32 SAL_CALL rtl_tres_timer();
91 void SAL_CALL rtl_tres_destroy_funcstate( rtl_FuncState* pState_ );
92 void SAL_CALL rtl_tres_destroy_funcstates( rtl_FuncState* pState_ );
93 void SAL_CALL rtl_tres_destroy_cmpstates( rtl_CmpState* pState_ );
94 void SAL_CALL rtl_tres_destroy_cmpstate( rtl_CmpState* pState_ );
97 /* set and clear single bits */
98 static void SAL_CALL rtl_tres_setbit( rtl_FuncState* pState_,
99 sal_uInt32 flag );
100 static void SAL_CALL rtl_tres_clearbit( rtl_FuncState* pState_,
101 sal_uInt32 flag );
104 * forward declarations of concrete function implementations overloadable
105 * and accessible via vtable
107 static sal_Bool SAL_CALL rtl_tres_state(
108 rtl_TestResult* pThis_,
109 sal_Bool state,
110 const sal_Char* msg,
111 const sal_Char* sub,
112 sal_Bool v
115 static void SAL_CALL rtl_tres_end( rtl_TestResult* pThis_,
116 const sal_Char* msg );
118 static rtl_funcstate SAL_CALL rtl_tres_funcstate( rtl_TestResult* pThis_ );
120 static sal_Bool SAL_CALL rtl_tres_ispassed( rtl_TestResult* pThis_ );
121 static sal_Bool SAL_CALL rtl_tres_isok( rtl_TestResult* pThis_ );
123 static sal_Bool SAL_CALL rtl_tres_isbit( rtl_TestResult* pThis_,
124 sal_uInt32 flag );
126 static rtl_funcstate SAL_CALL rtl_tres_getnextfuncstate( rtl_funcstate );
127 static rtl_funcstate SAL_CALL rtl_tres_getprevfuncstate( rtl_funcstate );
128 static sal_uInt32 SAL_CALL rtl_tres_getflags( rtl_funcstate );
129 sal_uInt32 SAL_CALL rtl_tres_getstarttime( rtl_funcstate );
130 sal_uInt32 SAL_CALL rtl_tres_getstoptime( rtl_funcstate );
131 static rtl_cmpstate SAL_CALL rtl_tres_getcmpstate( rtl_funcstate );
133 static sal_Bool SAL_CALL rtl_tres_getstat( rtl_cmpstate );
134 rtl_String* SAL_CALL rtl_tres_getname( rtl_funcstate );
135 rtl_String* SAL_CALL rtl_tres_getmsg( rtl_cmpstate );
136 static rtl_cmpstate SAL_CALL rtl_tres_getnextcmpstate( rtl_cmpstate );
140 * initialize vtable with function pointers
142 static rtl_TestResult_vtable trVTable =
144 sizeof(rtl_TestResult_vtable),
145 rtl_tres_state,
146 rtl_tres_end,
147 rtl_tres_ispassed,
148 rtl_tres_isok,
149 rtl_tres_funcstate,
150 rtl_tres_isbit,
151 rtl_tres_getnextfuncstate,
152 rtl_tres_getprevfuncstate,
153 rtl_tres_getflags,
154 rtl_tres_getname,
155 rtl_tres_getstarttime,
156 rtl_tres_getstoptime,
157 rtl_tres_getcmpstate,
158 rtl_tres_getstat,
159 rtl_tres_getmsg,
160 rtl_tres_getnextcmpstate
164 * rtl_tres_create
165 * create and initialize data struct for TestResult
167 * @param const sal_Char* meth = name of the method (entryname)
168 * @param sal_uInt32 flags = bitmap of comandline and status flags
170 * @return rtl_TestResult* = pointer to a new allocated testresult struct
172 rtl_TestResult* rtl_tres_create( const sal_Char* meth, sal_uInt32 flags )
174 /* allocate memory for testresult data structure */
175 rtl_TestResult_Data* pData = (rtl_TestResult_Data*) malloc( sizeof(
176 rtl_TestResult_Data ) );
177 /* initialize members... */
178 pData->m_funcs = &trVTable; /* ...vtableptr to vtbladr */
179 pData->m_externaldata = 0; /* ...external data pointer */
181 /* allocate memory for state structure and initialize members */
182 pData->m_state = rtl_tres_create_funcstate( meth );
183 pData->m_state->m_flags = flags; /* ...option Bitmap */
185 /* set OK flag initial */
186 rtl_tres_setbit( pData->m_state, rtl_tres_Flag_OK );
188 return (rtl_TestResult*)pData ;
192 * rtl_tres_create_funcstate
193 * allocates and initializes a structure to represent the status of a test
194 * entry or its substates
196 * @param const sal_Char* meth = the name of the method (entry or sub entry)
198 * @return rtl_FuncState* = pointer to a new allocated funcstate struct
200 rtl_FuncState* SAL_CALL rtl_tres_create_funcstate( const sal_Char* meth )
202 rtl_FuncState* pStat = 0; /* status structure */
204 /* allocate memory for status structure */
205 pStat = (rtl_FuncState*) malloc( sizeof( struct _rtl_FuncState ) );
207 if ( pStat )
209 pStat->m_next = pStat; /* init ptr to next struct */
210 pStat->m_prev = pStat; /* init ptr to prev struct */
212 pStat->m_name = 0; /* init name */
213 pStat->m_flags = 0; /* init flags */
214 pStat->m_start = rtl_tres_timer(); /* init start milliseconds */
215 pStat->m_stop = 0; /* init stop milliseconds */
216 pStat->m_cmp = 0; /* init ptr to msg struct */
217 rtl_string_newFromStr( &pStat->m_name, meth );/* copy meth to name */
219 /* set ok flag initially */
220 rtl_tres_setbit(pStat, rtl_tres_Flag_OK);
223 return ( pStat );
226 * rtl_tres_link_funcstate
227 * link initialized funcstate structure to a circular double linked list
229 * @param rtl_FuncState* ptr = pointer to a funcstate where to link in new
230 * @param rtl_FuncState* plink = pointer to a funcstate to link in list
232 * @return rtl_FuncState* = pointer to structure linked in new
234 rtl_FuncState* SAL_CALL rtl_tres_link_funcstate( rtl_FuncState* ptr,
235 rtl_FuncState* plink )
237 ptr->m_next->m_prev = plink;
238 ptr->m_next->m_prev->m_next = ptr->m_next;
239 ptr->m_next->m_prev->m_prev = ptr;
240 ptr->m_next = plink;
241 return ( plink );
245 * rtl_tres_unlink_funcstate
246 * unlink funcstate structure from a circular double linked list
248 * @param rtl_FuncState* plink = pointer to a funcstate to unlink from list
250 * @return rtl_FuncState* = pointer to funcstate struct unlinked from
251 * list
253 rtl_FuncState* SAL_CALL rtl_tres_unlink_funcstate( rtl_FuncState* plink )
255 plink->m_next->m_prev = plink->m_prev;
256 plink->m_prev->m_next = plink->m_next;
257 plink->m_next = plink;
258 plink->m_prev = plink;
259 return ( plink );
263 * rtl_tres_link_cmpstate
264 * link initialized cmpstate structure to a circular double linked list
266 * @param rtl_CmpState* ptr = pointer to a cmpstate where to link in new
267 * @param rtl_CmpState* plink = pointer to a cmpstate to link in list
269 * @return rtl_CmpState* = pointer to cmpstate struct linked in new
271 rtl_CmpState* SAL_CALL rtl_tres_link_cmpstate( rtl_CmpState* ptr,
272 rtl_CmpState* plink )
274 ptr->m_next->m_prev = plink;
275 ptr->m_next->m_prev->m_next = ptr->m_next;
276 ptr->m_next->m_prev->m_prev = ptr;
277 ptr->m_next = plink;
278 return ( plink );
281 * rtl_tres_unlink_cmpstate
282 * unlink cmpstate structure from a circular double linked list
284 * @param rtl_CmpState* plink = pointer to a cmpstate to unlink from list
286 * @return rtl_CmpState* = pointer to cmpstate struct unlinked from list
288 rtl_CmpState* SAL_CALL rtl_tres_unlink_cmpstate( rtl_CmpState* plink )
290 plink->m_next->m_prev = plink->m_prev;
291 plink->m_prev->m_next = plink->m_next;
292 plink->m_next = plink;
293 plink->m_prev = plink;
294 return ( plink );
298 * rtl_tres_create_cmpstate
299 * allocates and initializes a structure to represent the status of a test
300 * comparison
302 * @param sal_Bool state = compare state
303 * @param sal_Char* msg = message for logging and debug purposes
305 * @return rtl_CmpState* = pointer to the new allocated struct
307 rtl_CmpState* SAL_CALL rtl_tres_create_cmpstate(
308 sal_Bool state,
309 const sal_Char* msg
312 /* allocate memory for cmpstate struct */
313 rtl_CmpState* pStat = (rtl_CmpState*) malloc( sizeof( rtl_CmpState ) );
315 /* initialize if memory could be allocated */
316 if ( pStat )
318 pStat->m_next = pStat; /* init next with this */
319 pStat->m_prev = pStat; /* init prev with this */
320 pStat->m_msg = 0;
321 pStat->m_stat = state; /* boolean state */
322 rtl_string_newFromStr( &pStat->m_msg, msg ); /* copy message */
324 return ( pStat );
328 * rtl_tres_destroy
329 * free allocated memory of testresult data struct
331 * @param rtl_TestResult* pThis_ = ponter to a valid testresult struct
333 void SAL_CALL rtl_tres_destroy( rtl_TestResult* pThis_ )
335 /* cast to implementation representation structure */
336 rtl_TestResult_Data* pData = (rtl_TestResult_Data*) pThis_;
338 /* destroy all funcstates */
339 if ( pData->m_state )
340 rtl_tres_destroy_funcstates( pData->m_state );
342 /* free allocted memory and reinitialize to zero */
343 /* to be able to prevent dangling pointer access*/
344 free( pData ); pData = 0;
348 * rtl_tres_destroy_funcstates
349 * free allocated memory occupied by the list of funcstate data structs
350 * (iterates through next pointers)
352 * @param rtl_FuncState* pState_ = pointer to a valid funcstate struct
354 void SAL_CALL rtl_tres_destroy_funcstates( rtl_FuncState* pState_ )
356 rtl_FuncState* plink = pState_->m_next;
357 while ( plink != plink->m_next )
359 rtl_tres_destroy_funcstate( rtl_tres_unlink_funcstate( plink ) );
360 plink = pState_->m_next;
362 rtl_tres_destroy_funcstate( plink );
366 * rtl_tres_destroy_cmpstates
367 * free allocated memory occupied by the list of cmpstate data structs
368 * (iterates through next pointers)
370 * @param rtl_CmpState* pState_ = pointer to a valid cmpstate struct
372 void SAL_CALL rtl_tres_destroy_cmpstates( rtl_CmpState* pState_ )
374 rtl_CmpState* plink = pState_->m_next;
375 while ( plink != plink->m_next )
377 rtl_tres_destroy_cmpstate( rtl_tres_unlink_cmpstate( plink ) );
378 plink = pState_->m_next;
380 rtl_tres_destroy_cmpstate( plink );
385 * rtl_tres_destroy_funcstate
386 * free allocated memory occupied by one funcstate and it's list
387 * of cmpstate data structs
389 * @param rtl_FuncState* pState_ = pointer to a valid funcstate struct
391 void SAL_CALL rtl_tres_destroy_funcstate( rtl_FuncState* pState_ )
393 rtl_FuncState* plink = pState_;
395 if ( plink->m_cmp )
396 rtl_tres_destroy_cmpstates( plink->m_cmp );
398 if ( plink->m_name )
400 rtl_string_release( plink->m_name );
401 plink->m_name = 0;
403 plink->m_flags = 0;
404 free( plink );
405 plink = 0;
409 * rtl_tres_destroy_cmpstate
410 * free allocated memory of a cmpstate data struct
412 * @param rtl_CmpState* pState_ = pointer to cmpstate struct to destroy
414 void SAL_CALL rtl_tres_destroy_cmpstate( rtl_CmpState* pState_ )
417 rtl_CmpState* plink = pState_;
419 if ( plink->m_msg )
421 rtl_string_release( plink->m_msg );
422 plink->m_msg = 0;
424 free( plink );
425 plink = 0;
428 * central function to call in tests
430 * @param rtl_TestResult* pThis_ = self pointer to TestResult structure
431 * @param sal_Bool state = boolean result of statement comparison
432 * @param const sal_Char* msg = message for actual statementcomparison
433 * @param const sal_Char* sub = name of sub testfunction
434 * @param sal_Bool v = boolean verbose parameter
436 * @return sal_Bool = determines if statement comparison
437 * was positive or not
439 static sal_Bool SAL_CALL rtl_tres_state(
440 rtl_TestResult* pThis_,
441 sal_Bool state,
442 const sal_Char* msg,
443 const sal_Char* sub,
444 sal_Bool v
448 /* cast pointer to testresult data implementation struct*/
449 rtl_TestResult_Data* pData = (rtl_TestResult_Data*)pThis_;
451 /* initialize funcstate pointer with masterstate */
452 rtl_FuncState* pFunc = pData->m_state;
454 /* if substate required */
455 if ( sub )
457 /* link new created function state to last item */
458 pFunc = rtl_tres_link_funcstate( pFunc->m_prev,
459 rtl_tres_create_funcstate( sub ) );
461 /* indicate this state as substate */
462 rtl_tres_setbit( pFunc, rtl_tres_Flag_SUB );
464 /* indicate prvious state as passed if no masterstate */
465 if ( pFunc->m_prev != pData->m_state )
466 rtl_tres_setbit( pFunc->m_prev, rtl_tres_Flag_PASSED );
470 /* test failed */
471 if( ! state )
473 /* determine if assertion should be thrown */
474 if ( rtl_tres_isbit( pThis_, rtl_tres_Flag_BOOM ) )
476 /* if message available */
477 if ( msg )
478 TST_BOOM( state, msg );
479 else
480 TST_BOOM( state, "no msg available" );
483 /* clear this state ok flag and masterstate ok flag */
484 rtl_tres_clearbit( pFunc, rtl_tres_Flag_OK );
485 rtl_tres_clearbit( pData->m_state, rtl_tres_Flag_OK );
487 /* message available */
488 if( msg )
490 /* append a new comparison state */
491 if (! pFunc->m_cmp )
492 pFunc->m_cmp = rtl_tres_create_cmpstate( state, msg );
493 else
494 rtl_tres_link_cmpstate( pFunc->m_cmp,
495 rtl_tres_create_cmpstate(state, msg ) );
497 /* message to stderr required ? */
498 if ( v || ( pFunc->m_next->m_flags & rtl_tres_Flag_VERBOSE ) )
499 fprintf( stderr, "%s\n", msg );
502 pFunc->m_stop = rtl_tres_timer();
503 return ( state );
507 * rtl_tres_timer
508 * function to get actual timevalue
509 * this has to be replaced by a high resolution timer
511 sal_uInt32 SAL_CALL rtl_tres_timer()
513 sal_uInt32 val = 0;
514 TimeValue* tmv = (TimeValue*)malloc( sizeof( TimeValue ) );
515 osl_getSystemTime( tmv );
516 val = tmv->Nanosec/1000L;
517 free( tmv );
518 return ( val );
522 static void SAL_CALL rtl_tres_end( rtl_TestResult* pThis_,
523 const sal_Char* msg )
525 rtl_TestResult_Data* pData = (rtl_TestResult_Data*) pThis_;
527 if( msg )
529 if (! pData->m_state->m_cmp )
530 pData->m_state->m_cmp = rtl_tres_create_cmpstate( sal_True, msg );
531 else
532 rtl_tres_link_cmpstate( pData->m_state->m_cmp,
533 rtl_tres_create_cmpstate( sal_True, msg ) );
535 pData->m_state->m_prev->m_flags |= rtl_tres_Flag_PASSED;
536 pData->m_state->m_flags |= rtl_tres_Flag_PASSED;
537 pData->m_state->m_stop = rtl_tres_timer();
541 static sal_Bool SAL_CALL rtl_tres_ispassed( rtl_TestResult* pThis_ )
543 return rtl_tres_isbit( pThis_, rtl_tres_Flag_PASSED );
546 static sal_Bool SAL_CALL rtl_tres_isok( rtl_TestResult* pThis_ )
548 return rtl_tres_isbit( pThis_, rtl_tres_Flag_OK );
551 * return pointer to funcstate structure
553 static rtl_funcstate SAL_CALL rtl_tres_funcstate( rtl_TestResult* pThis_ )
556 rtl_TestResult_Data* pThis = (rtl_TestResult_Data*) pThis_;
557 return (rtl_funcstate)pThis->m_state;
561 * determine if a flag is set or not
563 static sal_Bool SAL_CALL rtl_tres_isbit( rtl_TestResult* pThis_,
564 sal_uInt32 flag )
566 return (sal_Bool)
567 ((((rtl_TestResult_Data *) pThis_)->m_state->m_flags & flag) == flag);
570 * set one single bit
572 static void SAL_CALL rtl_tres_setbit( rtl_FuncState* pState_,
573 sal_uInt32 flag )
575 pState_->m_flags |= flag;
578 * clear one single bit
580 static void SAL_CALL rtl_tres_clearbit( rtl_FuncState* pState_,
581 sal_uInt32 flag )
583 pState_->m_flags = pState_->m_flags & ( ~flag );
587 * returns next pointer of passed funcstate structure
589 rtl_funcstate SAL_CALL rtl_tres_getnextfuncstate( rtl_funcstate fstate )
591 rtl_FuncState* fs = (rtl_FuncState*)fstate;
592 return( (rtl_funcstate)fs->m_next );
596 * returns previous pointer of passed funcstate structure
598 rtl_funcstate SAL_CALL rtl_tres_getprevfuncstate( rtl_funcstate fstate )
600 rtl_FuncState* fs = (rtl_FuncState*)fstate;
601 return( (rtl_funcstate)fs->m_prev );
605 * returns flag value of passed funcstate structure
607 sal_uInt32 SAL_CALL rtl_tres_getflags( rtl_funcstate fstate )
609 rtl_FuncState* fs = (rtl_FuncState*)fstate;
610 return( fs->m_flags );
613 * returns name of passed funcstate structure
615 rtl_String* SAL_CALL rtl_tres_getname( rtl_funcstate fstate )
617 rtl_FuncState* fs = (rtl_FuncState*)fstate;
618 return( fs->m_name );
621 * returns starttime of passed funcstate structure
623 sal_uInt32 SAL_CALL rtl_tres_getstarttime( rtl_funcstate fstate )
625 rtl_FuncState* fs = (rtl_FuncState*)fstate;
626 return( fs->m_start );
630 * returns stoptime of passed funcstate structure
632 sal_uInt32 SAL_CALL rtl_tres_getstoptime( rtl_funcstate fstate )
634 rtl_FuncState* fs = (rtl_FuncState*)fstate;
635 return( fs->m_stop );
639 * returns pointer to cmpstate of passed funcstate structure
641 rtl_cmpstate SAL_CALL rtl_tres_getcmpstate( rtl_funcstate fstate)
643 rtl_FuncState* fs = (rtl_FuncState*)fstate;
644 return( (rtl_cmpstate)fs->m_cmp );
648 * returns boolean state of passed cmpstate structure
650 sal_Bool SAL_CALL rtl_tres_getstat( rtl_cmpstate cstate)
652 rtl_CmpState* cs = (rtl_CmpState*)cstate;
653 return( cs->m_stat );
656 * returns message of passed cmpstate structure
658 rtl_String* SAL_CALL rtl_tres_getmsg( rtl_cmpstate cstate)
660 rtl_CmpState* cs = (rtl_CmpState*)cstate;
661 return( cs->m_msg );
664 * returns next pointer of passed cmpstate structure
666 rtl_cmpstate SAL_CALL rtl_tres_getnextcmpstate( rtl_cmpstate cstate)
668 rtl_CmpState* cs = (rtl_CmpState*)cstate;
669 return( (rtl_cmpstate)cs->m_next );
673 // <method_logPrintf>
674 //inline void logPrintf ( const sal_Bool bTestCaseState,
675 // const char *pFormatStr, ...
676 // )
678 // if( m_pFunctions && m_pFunctions->pLogPrintf )
679 // {
680 // va_list vArgumentList;
681 // va_start ( vArgumentList, pFormatStr );
683 // m_pFunctions->pLogPrintf( this, bTestCaseState, pFormatStr, vArgumentList );
685 // va_end ( vArgumentList );
686 // }
687 //} // </method_logPrintf>