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