merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / rtl / source / tres.c
blob85e5c4367066b3937e9e7873a538d3636bb29686
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include <stdio.h>
29 #include <rtl/tres.h>
30 #include <osl/diagnose.h>
31 #include <osl/time.h>
33 /* force an assertion on false state */
34 #define TST_BOOM(c, m) OSL_ENSURE(c, m)
37 typedef struct _rtl_CmpState
39 struct _rtl_CmpState* m_next;
40 struct _rtl_CmpState* m_prev;
42 sal_Bool m_stat;
43 rtl_String* m_msg;
45 } rtl_CmpState;
47 typedef struct _rtl_FuncState
49 struct _rtl_FuncState* m_next;
50 struct _rtl_FuncState* m_prev;
51 rtl_String* m_name;
52 sal_uInt32 m_flags;
53 sal_uInt32 m_start;
54 sal_uInt32 m_stop;
55 struct _rtl_CmpState* m_cmp;
57 } rtl_FuncState;
61 typedef struct _rtl_TestResult_Data
63 rtl_TestResult_vtable* m_funcs;
64 void* m_externaldata;
66 rtl_FuncState* m_state;
68 } rtl_TestResult_Data;
71 /**
72 * internal helper functions
75 /* ...to create, link, unlink and destroy allocated memory */
76 rtl_FuncState* SAL_CALL rtl_tres_create_funcstate( const sal_Char* meth );
77 rtl_FuncState* SAL_CALL rtl_tres_link_funcstate( rtl_FuncState* ptr,
78 rtl_FuncState* plink );
79 rtl_FuncState* SAL_CALL rtl_tres_unlink_funcstate( rtl_FuncState* plink );
80 rtl_CmpState* SAL_CALL rtl_tres_create_cmpstate(
81 sal_Bool state,
82 const sal_Char* msg
84 rtl_CmpState* SAL_CALL rtl_tres_link_cmpstate( rtl_CmpState* ptr,
85 rtl_CmpState* plink );
86 rtl_CmpState* SAL_CALL rtl_tres_unlink_cmpstate( rtl_CmpState* plink );
87 sal_uInt32 SAL_CALL rtl_tres_timer();
88 void SAL_CALL rtl_tres_destroy_funcstate( rtl_FuncState* pState_ );
89 void SAL_CALL rtl_tres_destroy_funcstates( rtl_FuncState* pState_ );
90 void SAL_CALL rtl_tres_destroy_cmpstates( rtl_CmpState* pState_ );
91 void SAL_CALL rtl_tres_destroy_cmpstate( rtl_CmpState* pState_ );
94 /* set and clear single bits */
95 static void SAL_CALL rtl_tres_setbit( rtl_FuncState* pState_,
96 sal_uInt32 flag );
97 static void SAL_CALL rtl_tres_clearbit( rtl_FuncState* pState_,
98 sal_uInt32 flag );
101 * forward declarations of concrete function implementations overloadable
102 * and accessible via vtable
104 static sal_Bool SAL_CALL rtl_tres_state(
105 rtl_TestResult* pThis_,
106 sal_Bool state,
107 const sal_Char* msg,
108 const sal_Char* sub,
109 sal_Bool v
112 static void SAL_CALL rtl_tres_end( rtl_TestResult* pThis_,
113 const sal_Char* msg );
115 static rtl_funcstate SAL_CALL rtl_tres_funcstate( rtl_TestResult* pThis_ );
117 static sal_Bool SAL_CALL rtl_tres_ispassed( rtl_TestResult* pThis_ );
118 static sal_Bool SAL_CALL rtl_tres_isok( rtl_TestResult* pThis_ );
120 static sal_Bool SAL_CALL rtl_tres_isbit( rtl_TestResult* pThis_,
121 sal_uInt32 flag );
123 static rtl_funcstate SAL_CALL rtl_tres_getnextfuncstate( rtl_funcstate );
124 static rtl_funcstate SAL_CALL rtl_tres_getprevfuncstate( rtl_funcstate );
125 static sal_uInt32 SAL_CALL rtl_tres_getflags( rtl_funcstate );
126 sal_uInt32 SAL_CALL rtl_tres_getstarttime( rtl_funcstate );
127 sal_uInt32 SAL_CALL rtl_tres_getstoptime( rtl_funcstate );
128 static rtl_cmpstate SAL_CALL rtl_tres_getcmpstate( rtl_funcstate );
130 static sal_Bool SAL_CALL rtl_tres_getstat( rtl_cmpstate );
131 rtl_String* SAL_CALL rtl_tres_getname( rtl_funcstate );
132 rtl_String* SAL_CALL rtl_tres_getmsg( rtl_cmpstate );
133 static rtl_cmpstate SAL_CALL rtl_tres_getnextcmpstate( rtl_cmpstate );
137 * initialize vtable with function pointers
139 static rtl_TestResult_vtable trVTable =
141 sizeof(rtl_TestResult_vtable),
142 rtl_tres_state,
143 rtl_tres_end,
144 rtl_tres_ispassed,
145 rtl_tres_isok,
146 rtl_tres_funcstate,
147 rtl_tres_isbit,
148 rtl_tres_getnextfuncstate,
149 rtl_tres_getprevfuncstate,
150 rtl_tres_getflags,
151 rtl_tres_getname,
152 rtl_tres_getstarttime,
153 rtl_tres_getstoptime,
154 rtl_tres_getcmpstate,
155 rtl_tres_getstat,
156 rtl_tres_getmsg,
157 rtl_tres_getnextcmpstate
161 * rtl_tres_create
162 * create and initialize data struct for TestResult
164 * @param const sal_Char* meth = name of the method (entryname)
165 * @param sal_uInt32 flags = bitmap of comandline and status flags
167 * @return rtl_TestResult* = pointer to a new allocated testresult struct
169 rtl_TestResult* rtl_tres_create( const sal_Char* meth, sal_uInt32 flags )
171 /* allocate memory for testresult data structure */
172 rtl_TestResult_Data* pData = (rtl_TestResult_Data*) malloc( sizeof(
173 rtl_TestResult_Data ) );
174 /* initialize members... */
175 pData->m_funcs = &trVTable; /* ...vtableptr to vtbladr */
176 pData->m_externaldata = 0; /* ...external data pointer */
178 /* allocate memory for state structure and initialize members */
179 pData->m_state = rtl_tres_create_funcstate( meth );
180 pData->m_state->m_flags = flags; /* ...option Bitmap */
182 /* set OK flag initial */
183 rtl_tres_setbit( pData->m_state, rtl_tres_Flag_OK );
185 return (rtl_TestResult*)pData ;
189 * rtl_tres_create_funcstate
190 * allocates and initializes a structure to represent the status of a test
191 * entry or its substates
193 * @param const sal_Char* meth = the name of the method (entry or sub entry)
195 * @return rtl_FuncState* = pointer to a new allocated funcstate struct
197 rtl_FuncState* SAL_CALL rtl_tres_create_funcstate( const sal_Char* meth )
199 rtl_FuncState* pStat = 0; /* status structure */
201 /* allocate memory for status structure */
202 pStat = (rtl_FuncState*) malloc( sizeof( struct _rtl_FuncState ) );
204 if ( pStat )
206 pStat->m_next = pStat; /* init ptr to next struct */
207 pStat->m_prev = pStat; /* init ptr to prev struct */
209 pStat->m_name = 0; /* init name */
210 pStat->m_flags = 0; /* init flags */
211 pStat->m_start = rtl_tres_timer(); /* init start milliseconds */
212 pStat->m_stop = 0; /* init stop milliseconds */
213 pStat->m_cmp = 0; /* init ptr to msg struct */
214 rtl_string_newFromStr( &pStat->m_name, meth );/* copy meth to name */
216 /* set ok flag initially */
217 rtl_tres_setbit(pStat, rtl_tres_Flag_OK);
220 return ( pStat );
223 * rtl_tres_link_funcstate
224 * link initialized funcstate structure to a circular double linked list
226 * @param rtl_FuncState* ptr = pointer to a funcstate where to link in new
227 * @param rtl_FuncState* plink = pointer to a funcstate to link in list
229 * @return rtl_FuncState* = pointer to structure linked in new
231 rtl_FuncState* SAL_CALL rtl_tres_link_funcstate( rtl_FuncState* ptr,
232 rtl_FuncState* plink )
234 ptr->m_next->m_prev = plink;
235 ptr->m_next->m_prev->m_next = ptr->m_next;
236 ptr->m_next->m_prev->m_prev = ptr;
237 ptr->m_next = plink;
238 return ( plink );
242 * rtl_tres_unlink_funcstate
243 * unlink funcstate structure from a circular double linked list
245 * @param rtl_FuncState* plink = pointer to a funcstate to unlink from list
247 * @return rtl_FuncState* = pointer to funcstate struct unlinked from
248 * list
250 rtl_FuncState* SAL_CALL rtl_tres_unlink_funcstate( rtl_FuncState* plink )
252 plink->m_next->m_prev = plink->m_prev;
253 plink->m_prev->m_next = plink->m_next;
254 plink->m_next = plink;
255 plink->m_prev = plink;
256 return ( plink );
260 * rtl_tres_link_cmpstate
261 * link initialized cmpstate structure to a circular double linked list
263 * @param rtl_CmpState* ptr = pointer to a cmpstate where to link in new
264 * @param rtl_CmpState* plink = pointer to a cmpstate to link in list
266 * @return rtl_CmpState* = pointer to cmpstate struct linked in new
268 rtl_CmpState* SAL_CALL rtl_tres_link_cmpstate( rtl_CmpState* ptr,
269 rtl_CmpState* plink )
271 ptr->m_next->m_prev = plink;
272 ptr->m_next->m_prev->m_next = ptr->m_next;
273 ptr->m_next->m_prev->m_prev = ptr;
274 ptr->m_next = plink;
275 return ( plink );
278 * rtl_tres_unlink_cmpstate
279 * unlink cmpstate structure from a circular double linked list
281 * @param rtl_CmpState* plink = pointer to a cmpstate to unlink from list
283 * @return rtl_CmpState* = pointer to cmpstate struct unlinked from list
285 rtl_CmpState* SAL_CALL rtl_tres_unlink_cmpstate( rtl_CmpState* plink )
287 plink->m_next->m_prev = plink->m_prev;
288 plink->m_prev->m_next = plink->m_next;
289 plink->m_next = plink;
290 plink->m_prev = plink;
291 return ( plink );
295 * rtl_tres_create_cmpstate
296 * allocates and initializes a structure to represent the status of a test
297 * comparison
299 * @param sal_Bool state = compare state
300 * @param sal_Char* msg = message for logging and debug purposes
302 * @return rtl_CmpState* = pointer to the new allocated struct
304 rtl_CmpState* SAL_CALL rtl_tres_create_cmpstate(
305 sal_Bool state,
306 const sal_Char* msg
309 /* allocate memory for cmpstate struct */
310 rtl_CmpState* pStat = (rtl_CmpState*) malloc( sizeof( rtl_CmpState ) );
312 /* initialize if memory could be allocated */
313 if ( pStat )
315 pStat->m_next = pStat; /* init next with this */
316 pStat->m_prev = pStat; /* init prev with this */
317 pStat->m_msg = 0;
318 pStat->m_stat = state; /* boolean state */
319 rtl_string_newFromStr( &pStat->m_msg, msg ); /* copy message */
321 return ( pStat );
325 * rtl_tres_destroy
326 * free allocated memory of testresult data struct
328 * @param rtl_TestResult* pThis_ = ponter to a valid testresult struct
330 void SAL_CALL rtl_tres_destroy( rtl_TestResult* pThis_ )
332 /* cast to implementation representation structure */
333 rtl_TestResult_Data* pData = (rtl_TestResult_Data*) pThis_;
335 /* destroy all funcstates */
336 if ( pData->m_state )
337 rtl_tres_destroy_funcstates( pData->m_state );
339 /* free allocted memory and reinitialize to zero */
340 /* to be able to prevent dangling pointer access*/
341 free( pData ); pData = 0;
345 * rtl_tres_destroy_funcstates
346 * free allocated memory occupied by the list of funcstate data structs
347 * (iterates through next pointers)
349 * @param rtl_FuncState* pState_ = pointer to a valid funcstate struct
351 void SAL_CALL rtl_tres_destroy_funcstates( rtl_FuncState* pState_ )
353 rtl_FuncState* plink = pState_->m_next;
354 while ( plink != plink->m_next )
356 rtl_tres_destroy_funcstate( rtl_tres_unlink_funcstate( plink ) );
357 plink = pState_->m_next;
359 rtl_tres_destroy_funcstate( plink );
363 * rtl_tres_destroy_cmpstates
364 * free allocated memory occupied by the list of cmpstate data structs
365 * (iterates through next pointers)
367 * @param rtl_CmpState* pState_ = pointer to a valid cmpstate struct
369 void SAL_CALL rtl_tres_destroy_cmpstates( rtl_CmpState* pState_ )
371 rtl_CmpState* plink = pState_->m_next;
372 while ( plink != plink->m_next )
374 rtl_tres_destroy_cmpstate( rtl_tres_unlink_cmpstate( plink ) );
375 plink = pState_->m_next;
377 rtl_tres_destroy_cmpstate( plink );
382 * rtl_tres_destroy_funcstate
383 * free allocated memory occupied by one funcstate and it's list
384 * of cmpstate data structs
386 * @param rtl_FuncState* pState_ = pointer to a valid funcstate struct
388 void SAL_CALL rtl_tres_destroy_funcstate( rtl_FuncState* pState_ )
390 rtl_FuncState* plink = pState_;
392 if ( plink->m_cmp )
393 rtl_tres_destroy_cmpstates( plink->m_cmp );
395 if ( plink->m_name )
397 rtl_string_release( plink->m_name );
398 plink->m_name = 0;
400 plink->m_flags = 0;
401 free( plink );
402 plink = 0;
406 * rtl_tres_destroy_cmpstate
407 * free allocated memory of a cmpstate data struct
409 * @param rtl_CmpState* pState_ = pointer to cmpstate struct to destroy
411 void SAL_CALL rtl_tres_destroy_cmpstate( rtl_CmpState* pState_ )
414 rtl_CmpState* plink = pState_;
416 if ( plink->m_msg )
418 rtl_string_release( plink->m_msg );
419 plink->m_msg = 0;
421 free( plink );
422 plink = 0;
425 * central function to call in tests
427 * @param rtl_TestResult* pThis_ = self pointer to TestResult structure
428 * @param sal_Bool state = boolean result of statement comparison
429 * @param const sal_Char* msg = message for actual statementcomparison
430 * @param const sal_Char* sub = name of sub testfunction
431 * @param sal_Bool v = boolean verbose parameter
433 * @return sal_Bool = determines if statement comparison
434 * was positive or not
436 static sal_Bool SAL_CALL rtl_tres_state(
437 rtl_TestResult* pThis_,
438 sal_Bool state,
439 const sal_Char* msg,
440 const sal_Char* sub,
441 sal_Bool v
445 /* cast pointer to testresult data implementation struct*/
446 rtl_TestResult_Data* pData = (rtl_TestResult_Data*)pThis_;
448 /* initialize funcstate pointer with masterstate */
449 rtl_FuncState* pFunc = pData->m_state;
451 /* if substate required */
452 if ( sub )
454 /* link new created function state to last item */
455 pFunc = rtl_tres_link_funcstate( pFunc->m_prev,
456 rtl_tres_create_funcstate( sub ) );
458 /* indicate this state as substate */
459 rtl_tres_setbit( pFunc, rtl_tres_Flag_SUB );
461 /* indicate prvious state as passed if no masterstate */
462 if ( pFunc->m_prev != pData->m_state )
463 rtl_tres_setbit( pFunc->m_prev, rtl_tres_Flag_PASSED );
467 /* test failed */
468 if( ! state )
470 /* determine if assertion should be thrown */
471 if ( rtl_tres_isbit( pThis_, rtl_tres_Flag_BOOM ) )
473 /* if message available */
474 if ( msg )
475 TST_BOOM( state, msg );
476 else
477 TST_BOOM( state, "no msg available" );
480 /* clear this state ok flag and masterstate ok flag */
481 rtl_tres_clearbit( pFunc, rtl_tres_Flag_OK );
482 rtl_tres_clearbit( pData->m_state, rtl_tres_Flag_OK );
484 /* message available */
485 if( msg )
487 /* append a new comparison state */
488 if (! pFunc->m_cmp )
489 pFunc->m_cmp = rtl_tres_create_cmpstate( state, msg );
490 else
491 rtl_tres_link_cmpstate( pFunc->m_cmp,
492 rtl_tres_create_cmpstate(state, msg ) );
494 /* message to stderr required ? */
495 if ( v || ( pFunc->m_next->m_flags & rtl_tres_Flag_VERBOSE ) )
496 fprintf( stderr, "%s\n", msg );
499 pFunc->m_stop = rtl_tres_timer();
500 return ( state );
504 * rtl_tres_timer
505 * function to get actual timevalue
506 * this has to be replaced by a high resolution timer
508 sal_uInt32 SAL_CALL rtl_tres_timer()
510 sal_uInt32 val = 0;
511 TimeValue* tmv = (TimeValue*)malloc( sizeof( TimeValue ) );
512 osl_getSystemTime( tmv );
513 val = tmv->Nanosec/1000L;
514 free( tmv );
515 return ( val );
519 static void SAL_CALL rtl_tres_end( rtl_TestResult* pThis_,
520 const sal_Char* msg )
522 rtl_TestResult_Data* pData = (rtl_TestResult_Data*) pThis_;
524 if( msg )
526 if (! pData->m_state->m_cmp )
527 pData->m_state->m_cmp = rtl_tres_create_cmpstate( sal_True, msg );
528 else
529 rtl_tres_link_cmpstate( pData->m_state->m_cmp,
530 rtl_tres_create_cmpstate( sal_True, msg ) );
532 pData->m_state->m_prev->m_flags |= rtl_tres_Flag_PASSED;
533 pData->m_state->m_flags |= rtl_tres_Flag_PASSED;
534 pData->m_state->m_stop = rtl_tres_timer();
538 static sal_Bool SAL_CALL rtl_tres_ispassed( rtl_TestResult* pThis_ )
540 return rtl_tres_isbit( pThis_, rtl_tres_Flag_PASSED );
543 static sal_Bool SAL_CALL rtl_tres_isok( rtl_TestResult* pThis_ )
545 return rtl_tres_isbit( pThis_, rtl_tres_Flag_OK );
548 * return pointer to funcstate structure
550 static rtl_funcstate SAL_CALL rtl_tres_funcstate( rtl_TestResult* pThis_ )
553 rtl_TestResult_Data* pThis = (rtl_TestResult_Data*) pThis_;
554 return (rtl_funcstate)pThis->m_state;
558 * determine if a flag is set or not
560 static sal_Bool SAL_CALL rtl_tres_isbit( rtl_TestResult* pThis_,
561 sal_uInt32 flag )
563 return (sal_Bool)
564 ((((rtl_TestResult_Data *) pThis_)->m_state->m_flags & flag) == flag);
567 * set one single bit
569 static void SAL_CALL rtl_tres_setbit( rtl_FuncState* pState_,
570 sal_uInt32 flag )
572 pState_->m_flags |= flag;
575 * clear one single bit
577 static void SAL_CALL rtl_tres_clearbit( rtl_FuncState* pState_,
578 sal_uInt32 flag )
580 pState_->m_flags = pState_->m_flags & ( ~flag );
584 * returns next pointer of passed funcstate structure
586 rtl_funcstate SAL_CALL rtl_tres_getnextfuncstate( rtl_funcstate fstate )
588 rtl_FuncState* fs = (rtl_FuncState*)fstate;
589 return( (rtl_funcstate)fs->m_next );
593 * returns previous pointer of passed funcstate structure
595 rtl_funcstate SAL_CALL rtl_tres_getprevfuncstate( rtl_funcstate fstate )
597 rtl_FuncState* fs = (rtl_FuncState*)fstate;
598 return( (rtl_funcstate)fs->m_prev );
602 * returns flag value of passed funcstate structure
604 sal_uInt32 SAL_CALL rtl_tres_getflags( rtl_funcstate fstate )
606 rtl_FuncState* fs = (rtl_FuncState*)fstate;
607 return( fs->m_flags );
610 * returns name of passed funcstate structure
612 rtl_String* SAL_CALL rtl_tres_getname( rtl_funcstate fstate )
614 rtl_FuncState* fs = (rtl_FuncState*)fstate;
615 return( fs->m_name );
618 * returns starttime of passed funcstate structure
620 sal_uInt32 SAL_CALL rtl_tres_getstarttime( rtl_funcstate fstate )
622 rtl_FuncState* fs = (rtl_FuncState*)fstate;
623 return( fs->m_start );
627 * returns stoptime of passed funcstate structure
629 sal_uInt32 SAL_CALL rtl_tres_getstoptime( rtl_funcstate fstate )
631 rtl_FuncState* fs = (rtl_FuncState*)fstate;
632 return( fs->m_stop );
636 * returns pointer to cmpstate of passed funcstate structure
638 rtl_cmpstate SAL_CALL rtl_tres_getcmpstate( rtl_funcstate fstate)
640 rtl_FuncState* fs = (rtl_FuncState*)fstate;
641 return( (rtl_cmpstate)fs->m_cmp );
645 * returns boolean state of passed cmpstate structure
647 sal_Bool SAL_CALL rtl_tres_getstat( rtl_cmpstate cstate)
649 rtl_CmpState* cs = (rtl_CmpState*)cstate;
650 return( cs->m_stat );
653 * returns message of passed cmpstate structure
655 rtl_String* SAL_CALL rtl_tres_getmsg( rtl_cmpstate cstate)
657 rtl_CmpState* cs = (rtl_CmpState*)cstate;
658 return( cs->m_msg );
661 * returns next pointer of passed cmpstate structure
663 rtl_cmpstate SAL_CALL rtl_tres_getnextcmpstate( rtl_cmpstate cstate)
665 rtl_CmpState* cs = (rtl_CmpState*)cstate;
666 return( (rtl_cmpstate)cs->m_next );
670 // <method_logPrintf>
671 //inline void logPrintf ( const sal_Bool bTestCaseState,
672 // const char *pFormatStr, ...
673 // )
675 // if( m_pFunctions && m_pFunctions->pLogPrintf )
676 // {
677 // va_list vArgumentList;
678 // va_start ( vArgumentList, pFormatStr );
680 // m_pFunctions->pLogPrintf( this, bTestCaseState, pFormatStr, vArgumentList );
682 // va_end ( vArgumentList );
683 // }
684 //} // </method_logPrintf>