test/harness/testcaseparser.c
author ali <ali@juiblex.co.uk>
Sat Oct 05 21:37:31 2013 +0100 (2013-10-05)
changeset 99 783eff3047bc
parent 11 4a80c6053a66
permissions -rw-r--r--
Fix bug #21: False positive: Opening slanted double-quote, followed by single slanted quote, should be accepted by BL
ali@0
     1
#include <stdlib.h>
ali@0
     2
#include <stdio.h>
ali@0
     3
#include <string.h>
ali@6
     4
#include <glib.h>
ali@5
     5
#include <bl/bl.h>
ali@0
     6
#include "testcaseparser.h"
ali@0
     7
ali@0
     8
/*
ali@0
     9
 * Get the flag (the string of characters which bracket tags in test cases).
ali@0
    10
 */
ali@0
    11
const char *testcase_parser_get_flag(TestcaseParser *parser)
ali@0
    12
{
ali@0
    13
    char *s=parser->contents;
ali@0
    14
    if (!parser->flag)
ali@0
    15
    {
ali@6
    16
	parser->flag=g_string_new(NULL);
ali@0
    17
	while(*s>' ' && *s<='~')
ali@6
    18
	    g_string_append_c(parser->flag,*s++);
ali@0
    19
    }
ali@0
    20
    return parser->flag->str;
ali@0
    21
}
ali@0
    22
ali@0
    23
/*
ali@0
    24
 * Test if the parser has reached the end of the input file
ali@0
    25
 */
ali@6
    26
gboolean testcase_parser_at_eof(TestcaseParser *parser)
ali@0
    27
{
ali@0
    28
    return !parser->contents[parser->pos];
ali@0
    29
}
ali@0
    30
ali@0
    31
/*
ali@0
    32
 * Get the next tag (and its associated text, if any) from a test case.
ali@0
    33
 * Returns: TRUE if successful and FALSE if no more valid tags are present.
ali@0
    34
 * Callers can call testcase_parser_at_eof() when testcase_parser_get_next_tag()
ali@0
    35
 * to distinguish EOF and text which isn't a valid tag.
ali@0
    36
 */
ali@6
    37
gboolean testcase_parser_get_next_tag(TestcaseParser *parser,const char **tag,
ali@0
    38
  const char **text)
ali@0
    39
{
ali@0
    40
    size_t n;
ali@0
    41
    char *eol,*endp;
ali@6
    42
    GString *string;
ali@6
    43
    g_free(parser->tag);
ali@0
    44
    parser->tag=NULL;
ali@6
    45
    g_free(parser->tag_text);
ali@0
    46
    parser->tag_text=NULL;
ali@0
    47
    (void)testcase_parser_get_flag(parser);
ali@0
    48
    if (strncmp(parser->contents+parser->pos,parser->flag->str,
ali@0
    49
      parser->flag->len))
ali@0
    50
	return FALSE;
ali@0
    51
    eol=strchr(parser->contents+parser->pos,'\n');
ali@0
    52
    if (!eol)
ali@0
    53
	return FALSE;
ali@0
    54
    endp=eol-parser->flag->len;
ali@0
    55
    if (strncmp(endp,parser->flag->str,parser->flag->len))
ali@0
    56
	return FALSE;
ali@6
    57
    while(endp>parser->contents && g_ascii_isspace(endp[-1]))
ali@0
    58
	endp--;
ali@0
    59
    parser->pos+=parser->flag->len;
ali@6
    60
    while(g_ascii_isspace(parser->contents[parser->pos]))
ali@0
    61
	parser->pos++;
ali@6
    62
    parser->tag=g_strndup(parser->contents+parser->pos,
ali@0
    63
      endp-(parser->contents+parser->pos));
ali@0
    64
    parser->pos=eol-parser->contents+1;
ali@6
    65
    string=g_string_new(NULL);
ali@0
    66
    while (!testcase_parser_at_eof(parser) &&
ali@0
    67
      strncmp(parser->contents+parser->pos,parser->flag->str,parser->flag->len))
ali@0
    68
    {
ali@0
    69
	eol=strchr(parser->contents+parser->pos,'\n');
ali@0
    70
	if (eol)
ali@0
    71
	    n=eol-(parser->contents+parser->pos)+1;
ali@0
    72
	else
ali@0
    73
	    n=strlen(parser->contents+parser->pos);
ali@6
    74
	g_string_append_len(string,parser->contents+parser->pos,n);
ali@0
    75
	parser->pos+=n;
ali@0
    76
    }
ali@6
    77
    parser->tag_text=g_string_free(string,FALSE);
ali@0
    78
    if (!parser->tag_text)
ali@6
    79
	parser->tag_text=g_strdup("");
ali@0
    80
    if (tag)
ali@0
    81
	*tag=parser->tag;
ali@0
    82
    if (text)
ali@0
    83
	*text=parser->tag_text;
ali@0
    84
    return TRUE;
ali@0
    85
}
ali@0
    86
ali@0
    87
/*
ali@0
    88
 * Create a testcase parser to read a regular file.
ali@0
    89
 */
ali@0
    90
TestcaseParser *testcase_parser_new_from_file(const char *filename)
ali@0
    91
{
ali@0
    92
    TestcaseParser *parser;
ali@7
    93
    gsize len;
ali@69
    94
    GError *err=NULL;
ali@6
    95
    parser=g_new0(TestcaseParser,1);
ali@69
    96
    if (!file_get_contents_text(filename,&parser->contents,&len,&err))
ali@0
    97
    {
ali@69
    98
	g_printerr("%s: %s\n",filename,err->message);
ali@69
    99
	g_error_free(err);
ali@6
   100
	g_free(parser);
ali@0
   101
	return NULL;
ali@0
   102
    }
ali@7
   103
    if (!g_utf8_validate(parser->contents,len,NULL))
ali@7
   104
    {
ali@11
   105
	g_printerr("%s: Does not contain valid UTF-8\n",filename);
ali@7
   106
	g_free(parser->contents);
ali@7
   107
	g_free(parser);
ali@7
   108
	return NULL;
ali@7
   109
    }
ali@6
   110
    parser->filename=g_strdup(filename);
ali@0
   111
    return parser;
ali@0
   112
}
ali@0
   113
ali@0
   114
/*
ali@0
   115
 * Free a testcase parser.
ali@0
   116
 */
ali@0
   117
void testcase_parser_free(TestcaseParser *parser)
ali@0
   118
{
ali@6
   119
    g_free(parser->filename);
ali@6
   120
    g_free(parser->contents);
ali@0
   121
    if (parser->flag)
ali@6
   122
	g_string_free(parser->flag,TRUE);
ali@6
   123
    g_free(parser->tag);
ali@6
   124
    g_free(parser->tag_text);
ali@6
   125
    g_free(parser);
ali@0
   126
}