This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Very early version of module that creates XML-based test reports.
- Loading branch information
Showing
2 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
Copyright (C) 2011 Markus Kauppila <markus.kauppila@gmail.com> | ||
This software is provided 'as-is', without any express or implied | ||
warranty. In no event will the authors be held liable for any damages | ||
arising from the use of this software. | ||
Permission is granted to anyone to use this software for any purpose, | ||
including commercial applications, and to alter it and redistribute it | ||
freely, subject to the following restrictions: | ||
1. The origin of this software must not be misrepresented; you must not | ||
claim that you wrote the original software. If you use this software | ||
in a product, an acknowledgment in the product documentation would be | ||
appreciated but is not required. | ||
2. Altered source versions must be plainly marked as such, and must not be | ||
misrepresented as being the original software. | ||
3. This notice may not be removed or altered from any source distribution. | ||
*/ | ||
|
||
#ifndef _LOGGER_H | ||
#define _LOGGER_H | ||
|
||
/*! | ||
* Init the logger. | ||
*/ | ||
//int LogInit(); | ||
|
||
/*! | ||
* Quit the logger. | ||
*/ | ||
//int LogQuit(); | ||
|
||
/*! | ||
* Generic ouput function for the logger. Prints the | ||
* message to stderr. | ||
* | ||
* \param scope Source of message (eg. suite, test, harness) | ||
* \return non-zero if logging fails, zero on success | ||
*/ | ||
//int LogGenericOutput(int scope, const char *message, ...); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,334 @@ | ||
/* | ||
Copyright (C) 2011 Markus Kauppila <markus.kauppila@gmail.com> | ||
This software is provided 'as-is', without any express or implied | ||
warranty. In no event will the authors be held liable for any damages | ||
arising from the use of this software. | ||
Permission is granted to anyone to use this software for any purpose, | ||
including commercial applications, and to alter it and redistribute it | ||
freely, subject to the following restrictions: | ||
1. The origin of this software must not be misrepresented; you must not | ||
claim that you wrote the original software. If you use this software | ||
in a product, an acknowledgment in the product documentation would be | ||
appreciated but is not required. | ||
2. Altered source versions must be plainly marked as such, and must not be | ||
misrepresented as being the original software. | ||
3. This notice may not be removed or altered from any source distribution. | ||
*/ | ||
|
||
#ifndef _LOGGER_C | ||
#define _LOGGER_C | ||
|
||
#include "logger.h" | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <stdarg.h> | ||
|
||
/* \todo | ||
* - Fp to LogGenericOutput | ||
* - print <?xml version="1.0" encoding="utf-8" ?> as header | ||
* - use SDL_malloc etc... | ||
* - nest output /OK | ||
* - dummy functions for no-xml execution | ||
* - Make XML (and relevant comparisions) case-insensitive | ||
*/ | ||
|
||
|
||
/*! Function pointer definitions. \todo Move to logger.h */ | ||
typedef int (*LogInitFp)(void); | ||
typedef int (*LogCleanUptFp)(void); | ||
|
||
/*! Function prototypes */ | ||
int LogGenericOutput(char *message); | ||
int XMLLogOutput(const char *tag, const char *fmt, va_list list); | ||
|
||
static int xml_enabled = 1; | ||
|
||
static int loggingPriority = 0; | ||
static int nestingDepth = 0; | ||
|
||
enum Priority { | ||
VERBOSE, | ||
DEFAULT, | ||
SILENT | ||
}; | ||
|
||
|
||
#define TAG_START 0x00000001 | ||
#define TAG_END 0x00000002 | ||
#define TAG_BOTH (TAG_START & TAG_END) | ||
|
||
/*! | ||
* Defines structure used for "counting" open XML-tags | ||
*/ | ||
typedef struct TagList { | ||
const char *tag; | ||
struct TagList *next; | ||
} TagList; | ||
|
||
static TagList *openTags = NULL; | ||
|
||
/*! | ||
* Prepend the open tags list | ||
*/ | ||
static int | ||
AddOpenTag(const char *tag) | ||
{ | ||
TagList *openTag = malloc(sizeof(TagList)); | ||
if(openTag == NULL) { | ||
return 1; | ||
} | ||
memset(openTag, 0, sizeof(TagList)); | ||
|
||
openTag->tag = tag; // Should be fine without malloc? | ||
openTag->next = openTags; | ||
|
||
openTags = openTag; | ||
|
||
return 0; | ||
} | ||
|
||
/*! | ||
* Removes the first tag from the open tag list | ||
*/ | ||
static int | ||
RemoveOpenTag(const char *tag) | ||
{ | ||
if(openTags == NULL) { | ||
return 1; | ||
} | ||
|
||
int retVal = 0; | ||
|
||
// Tag should always be the same as previously opened tag | ||
// to prevent opening and ending tag mismatch | ||
if(strcmp(openTags->tag, tag) == 0) { | ||
TagList *openTag = openTags; | ||
openTags = openTags->next; | ||
|
||
free(openTag); | ||
} else { | ||
printf("Else activated!"); | ||
retVal = 1; | ||
} | ||
|
||
return retVal; | ||
} | ||
|
||
/*! | ||
* Goes through the open tag list and checks if | ||
* given tag is already opened | ||
* | ||
* \return 1 is tag is open, 0 if not | ||
*/ | ||
static int | ||
IsTagOpen(const char *tag) | ||
{ | ||
int retVal = 0; | ||
|
||
TagList *openTag = NULL; | ||
for(openTag = openTags; openTag; openTag = openTag->next) { | ||
if(strcmp(openTag->tag, tag) == 0) { | ||
retVal = 1; | ||
break; | ||
} | ||
} | ||
|
||
return retVal; | ||
} | ||
|
||
/*! | ||
* Debug function. Prints the contents of the open tags list. | ||
*/ | ||
static int | ||
PrintOpenTags() | ||
{ | ||
printf("\nOpen tags:\n"); | ||
|
||
TagList *openTag = NULL; | ||
for(openTag = openTags; openTag; openTag = openTag->next) { | ||
printf("\ttag: %s\n", openTag->tag); | ||
} | ||
} | ||
|
||
//! \TODO move these to upwards!! | ||
int XMLStartTag(int priority, const char *tag); | ||
int XMLEndTag(int priority, const char *tag); | ||
|
||
int | ||
XMLLogInit() | ||
{ | ||
|
||
LogGenericOutput("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"); | ||
|
||
XMLStartTag(0, "testlog"); | ||
} | ||
|
||
int | ||
XMLLogCleanUp() | ||
{ | ||
//! \todo do CloseOpenTags() instead | ||
XMLEndTag(0, "testlog"); | ||
} | ||
|
||
/*! | ||
* Forms a valid XML-tag based on the given parameters | ||
* | ||
* \param tag XML-tag to create | ||
* \param tagStyle Do start or end tag, or both. | ||
* \param message text content of the tags | ||
*/ | ||
static char * | ||
Tagify(const char *tag, const int tagStyle, const char *message) | ||
{ | ||
// buffer simplifies the creation of the string | ||
const int bufferSize = 1024; | ||
char buffer[bufferSize]; | ||
memset(buffer, 0, bufferSize); | ||
|
||
if(tagStyle & TAG_START) { | ||
strcat(buffer, "<"); | ||
strcat(buffer, tag); | ||
strcat(buffer, ">"); | ||
} | ||
|
||
if(message) { | ||
strcat(buffer, message); | ||
} | ||
|
||
if(tagStyle & TAG_END) { | ||
strcat(buffer, "</"); | ||
strcat(buffer, tag); | ||
strcat(buffer, ">"); | ||
} | ||
|
||
|
||
const int size = strlen(buffer) + 1; | ||
char *newTag = malloc(size * sizeof(char)); | ||
memset(newTag, 0, size * sizeof(char)); | ||
memcpy(newTag, buffer, size); | ||
|
||
return newTag; | ||
} | ||
|
||
|
||
int | ||
XMLStartTag(int priority, const char *tag) | ||
{ | ||
if(priority < loggingPriority) { | ||
return 1; | ||
} | ||
|
||
AddOpenTag(tag); | ||
char *newTag = Tagify(tag, TAG_START, NULL); | ||
LogGenericOutput(newTag); | ||
free(newTag); | ||
|
||
nestingDepth++; | ||
} | ||
|
||
int | ||
XMLEndTag(int priority, const char *tag) | ||
{ | ||
/* | ||
Do it before priority check, so incorrect usage of | ||
priorities won't mess it up | ||
*/ | ||
nestingDepth--; | ||
|
||
if(priority < loggingPriority) { | ||
return 1; | ||
} | ||
|
||
RemoveOpenTag(tag); | ||
|
||
char *newTag = Tagify(tag, TAG_END, NULL); | ||
LogGenericOutput(newTag); | ||
free(newTag); | ||
} | ||
|
||
int | ||
XMLTag(int priority, const char *tag, const char *fmt, ...) | ||
{ | ||
if(priority < loggingPriority) { | ||
return 1; | ||
} | ||
|
||
const int bufferSize = 1024; | ||
char buffer[bufferSize]; | ||
memset(buffer, 0, bufferSize); | ||
|
||
va_list list; | ||
va_start(list, fmt); | ||
vsnprintf(buffer, bufferSize, fmt, list); | ||
va_end(list); | ||
|
||
char *newTag = Tagify(tag, TAG_BOTH, buffer); | ||
LogGenericOutput(newTag); | ||
free(newTag); | ||
} | ||
|
||
//! \TODO Make it changeable by using a function pointer | ||
/*! | ||
* Prints the given message to stderr. Function adds nesting | ||
* to the output. | ||
*/ | ||
int | ||
LogGenericOutput(char *message) | ||
{ | ||
int depth = nestingDepth; | ||
while(depth--) { | ||
fprintf(stderr, " "); | ||
} | ||
|
||
fprintf(stderr, "%s\n", message); | ||
} | ||
|
||
|
||
/*! | ||
* Main for testing the logger | ||
*/ | ||
int | ||
main() | ||
{ | ||
LogInitFp LogInit = NULL; | ||
LogCleanUptFp LogCleanUp = NULL; | ||
|
||
if(xml_enabled) { | ||
// set logger functions to XML | ||
LogInit = XMLLogInit; | ||
LogCleanUp = XMLLogCleanUp; | ||
} else { | ||
// set up dummy functions | ||
} | ||
|
||
LogInit(); | ||
XMLStartTag(0, "hello"); | ||
XMLStartTag(0, "world!"); | ||
XMLEndTag(0, "world!"); | ||
XMLEndTag(0, "hello"); | ||
|
||
LogCleanUp(); | ||
|
||
|
||
|
||
#if 0 | ||
XMLStartTag("log"); | ||
XMLStartTag("suite"); | ||
XMLStartTag("test"); | ||
|
||
XMLEndTag("test"); | ||
XMLEndTag("suite"); | ||
|
||
|
||
PrintOpenTags(); | ||
#endif | ||
|
||
return 0; | ||
} | ||
|
||
#endif |