Coverage report for bus/desktop-file.c.gcov
-: 0:Source:desktop-file.c
-: 0:Graph:desktop-file.gcno
-: 0:Data:desktop-file.gcda
-: 0:Runs:10118
-: 0:Programs:2
-: 1:/* -*- mode: C; c-file-style: "gnu" -*- */
-: 2:/* desktop-file.c .desktop file parser
-: 3: *
-: 4: * Copyright (C) 2003 CodeFactory AB
-: 5: * Copyright (C) 2003 Red Hat Inc.
-: 6: *
-: 7: * Licensed under the Academic Free License version 2.1
-: 8: *
-: 9: * This program is free software; you can redistribute it and/or modify
-: 10: * it under the terms of the GNU General Public License as published by
-: 11: * the Free Software Foundation; either version 2 of the License, or
-: 12: * (at your option) any later version.
-: 13: *
-: 14: * This program is distributed in the hope that it will be useful,
-: 15: * but WITHOUT ANY WARRANTY; without even the implied warranty of
-: 16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-: 17: * GNU General Public License for more details.
-: 18: *
-: 19: * You should have received a copy of the GNU General Public License
-: 20: * along with this program; if not, write to the Free Software
-: 21: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-: 22: *
-: 23: */
-: 24:#include <dbus/dbus-sysdeps.h>
-: 25:#include <dbus/dbus-internals.h>
-: 26:#include "desktop-file.h"
-: 27:#include "utils.h"
-: 28:
-: 29:typedef struct
-: 30:{
-: 31: char *key;
-: 32: char *value;
-: 33:} BusDesktopFileLine;
-: 34:
-: 35:typedef struct
-: 36:{
-: 37: char *section_name;
-: 38:
-: 39: int n_lines;
-: 40: BusDesktopFileLine *lines;
-: 41: int n_allocated_lines;
-: 42:} BusDesktopFileSection;
-: 43:
-: 44:struct BusDesktopFile
-: 45:{
-: 46: int n_sections;
-: 47: BusDesktopFileSection *sections;
-: 48: int n_allocated_sections;
-: 49:};
-: 50:
-: 51:/**
-: 52: * Parser for service files.
-: 53: */
-: 54:typedef struct
-: 55:{
-: 56: DBusString data; /**< The data from the file */
-: 57:
-: 58: BusDesktopFile *desktop_file; /**< The resulting object */
-: 59: int current_section; /**< The current section being parsed */
-: 60:
-: 61: int pos; /**< Current position */
-: 62: int len; /**< Length */
-: 63: int line_num; /**< Current line number */
-: 64:
-: 65:} BusDesktopFileParser;
-: 66:
-: 67:#define VALID_KEY_CHAR 1
-: 68:#define VALID_LOCALE_CHAR 2
-: 69:unsigned char valid[256] = {
-: 70: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 71: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 72: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 ,
-: 73: 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 74: 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 ,
-: 75: 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x2 ,
-: 76: 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 ,
-: 77: 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 78: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 79: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 80: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 81: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 82: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 83: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 84: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 85: 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
-: 86:};
-: 87:
-: 88:static void report_error (BusDesktopFileParser *parser,
-: 89: char *message,
-: 90: const char *error_name,
-: 91: DBusError *error);
-: 92:
-: 93:static void
-: 94:parser_free (BusDesktopFileParser *parser)
function parser_free called 0 returned 0% blocks executed 0%
#####: 95:{
#####: 96: bus_desktop_file_free (parser->desktop_file);
call 0 never executed
-: 97:
#####: 98: _dbus_string_free (&parser->data);
call 0 never executed
#####: 99:}
-: 100:
-: 101:static void
-: 102:bus_desktop_file_line_free (BusDesktopFileLine *line)
function bus_desktop_file_line_free called 48 returned 100% blocks executed 100%
48: 103:{
48: 104: dbus_free (line->key);
call 0 returned 100%
48: 105: dbus_free (line->value);
call 0 returned 100%
48: 106:}
-: 107:
-: 108:static void
-: 109:bus_desktop_file_section_free (BusDesktopFileSection *section)
function bus_desktop_file_section_free called 24 returned 100% blocks executed 100%
24: 110:{
-: 111: int i;
-: 112:
72: 113: for (i = 0; i < section->n_lines; i++)
branch 0 taken 67%
branch 1 taken 33% (fallthrough)
48: 114: bus_desktop_file_line_free (§ion->lines[i]);
call 0 returned 100%
-: 115:
24: 116: dbus_free (section->lines);
call 0 returned 100%
24: 117: dbus_free (section->section_name);
call 0 returned 100%
24: 118:}
-: 119:
-: 120:void
-: 121:bus_desktop_file_free (BusDesktopFile *desktop_file)
function bus_desktop_file_free called 24 returned 100% blocks executed 100%
24: 122:{
-: 123: int i;
-: 124:
48: 125: for (i = 0; i < desktop_file->n_sections; i++)
branch 0 taken 50%
branch 1 taken 50% (fallthrough)
24: 126: bus_desktop_file_section_free (&desktop_file->sections[i]);
call 0 returned 100%
24: 127: dbus_free (desktop_file->sections);
call 0 returned 100%
-: 128:
24: 129: dbus_free (desktop_file);
call 0 returned 100%
24: 130:}
-: 131:
-: 132:static dbus_bool_t
-: 133:grow_lines_in_section (BusDesktopFileSection *section)
function grow_lines_in_section called 48 returned 100% blocks executed 88%
48: 134:{
-: 135: BusDesktopFileLine *lines;
-: 136:
-: 137: int new_n_lines;
-: 138:
48: 139: if (section->n_allocated_lines == 0)
branch 0 taken 50% (fallthrough)
branch 1 taken 50%
24: 140: new_n_lines = 1;
-: 141: else
24: 142: new_n_lines = section->n_allocated_lines*2;
-: 143:
48: 144: lines = dbus_realloc (section->lines,
call 0 returned 100%
-: 145: sizeof (BusDesktopFileLine) * new_n_lines);
-: 146:
48: 147: if (lines == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 148: return FALSE;
-: 149:
48: 150: section->lines = lines;
48: 151: section->n_allocated_lines = new_n_lines;
-: 152:
48: 153: return TRUE;
-: 154:}
-: 155:
-: 156:static dbus_bool_t
-: 157:grow_sections (BusDesktopFile *desktop_file)
function grow_sections called 24 returned 100% blocks executed 75%
24: 158:{
-: 159: int new_n_sections;
-: 160: BusDesktopFileSection *sections;
-: 161:
24: 162: if (desktop_file->n_allocated_sections == 0)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
24: 163: new_n_sections = 1;
-: 164: else
#####: 165: new_n_sections = desktop_file->n_allocated_sections*2;
-: 166:
24: 167: sections = dbus_realloc (desktop_file->sections,
call 0 returned 100%
-: 168: sizeof (BusDesktopFileSection) * new_n_sections);
24: 169: if (sections == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 170: return FALSE;
-: 171:
24: 172: desktop_file->sections = sections;
-: 173:
24: 174: desktop_file->n_allocated_sections = new_n_sections;
-: 175:
24: 176: return TRUE;
-: 177:}
-: 178:
-: 179:static char *
-: 180:unescape_string (BusDesktopFileParser *parser,
-: 181: const DBusString *str,
-: 182: int pos,
-: 183: int end_pos,
-: 184: DBusError *error)
function unescape_string called 72 returned 100% blocks executed 45%
72: 185:{
-: 186: char *retval, *q;
-: 187:
72: 188: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 189:
-: 190: /* len + 1 is enough, because unescaping never makes the
-: 191: * string longer
-: 192: */
72: 193: retval = dbus_malloc (end_pos - pos + 1);
call 0 returned 100%
72: 194: if (retval == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 195: {
#####: 196: BUS_SET_OOM (error);
call 0 never executed
#####: 197: return NULL;
-: 198: }
-: 199:
72: 200: q = retval;
-: 201:
2670: 202: while (pos < end_pos)
branch 0 taken 97%
branch 1 taken 3% (fallthrough)
-: 203: {
2526: 204: if (_dbus_string_get_byte (str, pos) == 0)
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 205: {
-: 206: /* Found an embedded null */
#####: 207: dbus_free (retval);
call 0 never executed
#####: 208: report_error (parser, "Text to be unescaped contains embedded nul",
call 0 never executed
-: 209: BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
#####: 210: return NULL;
-: 211: }
-: 212:
2526: 213: if (_dbus_string_get_byte (str, pos) == '\\')
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 214: {
#####: 215: pos ++;
-: 216:
#####: 217: if (pos >= end_pos)
branch 0 never executed
branch 1 never executed
-: 218: {
-: 219: /* Escape at end of string */
#####: 220: dbus_free (retval);
call 0 never executed
#####: 221: report_error (parser, "Text to be unescaped ended in \\",
call 0 never executed
-: 222: BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
#####: 223: return NULL;
-: 224: }
-: 225:
#####: 226: switch (_dbus_string_get_byte (str, pos))
call 0 never executed
branch 1 never executed
branch 2 never executed
branch 3 never executed
branch 4 never executed
branch 5 never executed
branch 6 never executed
-: 227: {
-: 228: case 's':
#####: 229: *q++ = ' ';
#####: 230: break;
-: 231: case 't':
#####: 232: *q++ = '\t';
#####: 233: break;
-: 234: case 'n':
#####: 235: *q++ = '\n';
#####: 236: break;
-: 237: case 'r':
#####: 238: *q++ = '\r';
#####: 239: break;
-: 240: case '\\':
#####: 241: *q++ = '\\';
#####: 242: break;
-: 243: default:
-: 244: /* Invalid escape code */
#####: 245: dbus_free (retval);
call 0 never executed
#####: 246: report_error (parser, "Text to be unescaped had invalid escape sequence",
call 0 never executed
-: 247: BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
#####: 248: return NULL;
-: 249: }
#####: 250: pos++;
-: 251: }
-: 252: else
-: 253: {
2526: 254: *q++ =_dbus_string_get_byte (str, pos);
call 0 returned 100%
-: 255:
2526: 256: pos++;
-: 257: }
-: 258: }
-: 259:
72: 260: *q = 0;
-: 261:
72: 262: return retval;
-: 263:}
-: 264:
-: 265:static BusDesktopFileSection*
-: 266:new_section (BusDesktopFile *desktop_file,
-: 267: const char *name)
function new_section called 24 returned 100% blocks executed 69%
24: 268:{
-: 269: int n;
-: 270: char *name_copy;
-: 271:
24: 272: if (desktop_file->n_allocated_sections == desktop_file->n_sections)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
-: 273: {
24: 274: if (!grow_sections (desktop_file))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 275: return NULL;
-: 276: }
-: 277:
24: 278: name_copy = _dbus_strdup (name);
call 0 returned 100%
24: 279: if (name_copy == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 280: return NULL;
-: 281:
24: 282: n = desktop_file->n_sections;
24: 283: desktop_file->sections[n].section_name = name_copy;
-: 284:
24: 285: desktop_file->sections[n].n_lines = 0;
24: 286: desktop_file->sections[n].lines = NULL;
24: 287: desktop_file->sections[n].n_allocated_lines = 0;
-: 288:
24: 289: if (!grow_lines_in_section (&desktop_file->sections[n]))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 290: {
#####: 291: dbus_free (desktop_file->sections[n].section_name);
call 0 never executed
#####: 292: desktop_file->sections[n].section_name = NULL;
#####: 293: return NULL;
-: 294: }
-: 295:
24: 296: desktop_file->n_sections += 1;
-: 297:
24: 298: return &desktop_file->sections[n];
-: 299:}
-: 300:
-: 301:static BusDesktopFileSection*
-: 302:open_section (BusDesktopFileParser *parser,
-: 303: char *name)
function open_section called 24 returned 100% blocks executed 83%
24: 304:{
-: 305: BusDesktopFileSection *section;
-: 306:
24: 307: section = new_section (parser->desktop_file, name);
call 0 returned 100%
24: 308: if (section == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 309: return NULL;
-: 310:
24: 311: parser->current_section = parser->desktop_file->n_sections - 1;
24: 312: _dbus_assert (&parser->desktop_file->sections[parser->current_section] == section);
call 0 returned 100%
-: 313:
24: 314: return section;
-: 315:}
-: 316:
-: 317:static BusDesktopFileLine *
-: 318:new_line (BusDesktopFileParser *parser)
function new_line called 48 returned 100% blocks executed 86%
48: 319:{
-: 320: BusDesktopFileSection *section;
-: 321: BusDesktopFileLine *line;
-: 322:
48: 323: section = &parser->desktop_file->sections[parser->current_section];
-: 324:
48: 325: if (section->n_allocated_lines == section->n_lines)
branch 0 taken 50% (fallthrough)
branch 1 taken 50%
-: 326: {
24: 327: if (!grow_lines_in_section (section))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 328: return NULL;
-: 329: }
-: 330:
48: 331: line = §ion->lines[section->n_lines++];
-: 332:
48: 333: memset (line, 0, sizeof (BusDesktopFileLine));
call 0 returned 100%
-: 334:
48: 335: return line;
-: 336:}
-: 337:
-: 338:static dbus_bool_t
-: 339:is_blank_line (BusDesktopFileParser *parser)
function is_blank_line called 51 returned 100% blocks executed 86%
51: 340:{
-: 341: int p;
-: 342: char c;
-: 343:
51: 344: p = parser->pos;
-: 345:
51: 346: c = _dbus_string_get_byte (&parser->data, p);
call 0 returned 100%
-: 347:
102: 348: while (c && c != '\n')
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 94%
branch 3 taken 6% (fallthrough)
-: 349: {
48: 350: if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f'))
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
branch 4 taken 100% (fallthrough)
branch 5 taken 0%
branch 6 taken 100% (fallthrough)
branch 7 taken 0%
branch 8 taken 100% (fallthrough)
branch 9 taken 0%
48: 351: return FALSE;
-: 352:
#####: 353: p++;
#####: 354: c = _dbus_string_get_byte (&parser->data, p);
call 0 never executed
-: 355: }
-: 356:
3: 357: return TRUE;
-: 358:}
-: 359:
-: 360:static void
-: 361:parse_comment_or_blank (BusDesktopFileParser *parser)
3: 362:{
-: 363: int line_end;
-: 364:
3: 365: if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 366: line_end = parser->len;
-: 367:
3: 368: if (line_end == parser->len)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 369: parser->pos = parser->len;
-: 370: else
3: 371: parser->pos = line_end + 1;
-: 372:
3: 373: parser->line_num += 1;
3: 374:}
-: 375:
-: 376:static dbus_bool_t
-: 377:is_valid_section_name (const char *name)
function is_valid_section_name called 24 returned 100% blocks executed 75%
24: 378:{
-: 379: /* 5. Group names may contain all ASCII characters except for control characters and '[' and ']'. */
-: 380:
360: 381: while (*name)
branch 0 taken 93%
branch 1 taken 7% (fallthrough)
-: 382: {
312: 383: if (!((*name >= 'A' && *name <= 'Z') || (*name >= 'a' || *name <= 'z') ||
branch 0 taken 85% (fallthrough)
branch 1 taken 15%
branch 2 taken 55% (fallthrough)
branch 3 taken 45%
branch 4 taken 25% (fallthrough)
branch 5 taken 75%
branch 6 taken 0% (fallthrough)
branch 7 taken 100%
branch 8 never executed
branch 9 never executed
branch 10 never executed
branch 11 never executed
-: 384: *name == '\n' || *name == '\t'))
#####: 385: return FALSE;
-: 386:
312: 387: name++;
-: 388: }
-: 389:
24: 390: return TRUE;
-: 391:}
-: 392:
-: 393:static dbus_bool_t
-: 394:parse_section_start (BusDesktopFileParser *parser, DBusError *error)
function parse_section_start called 24 returned 100% blocks executed 60%
24: 395:{
-: 396: int line_end;
-: 397: char *section_name;
-: 398:
24: 399: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 400:
24: 401: if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 402: line_end = parser->len;
-: 403:
24: 404: if (line_end - parser->pos <= 2 ||
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 0% (fallthrough)
branch 4 taken 100%
-: 405: _dbus_string_get_byte (&parser->data, line_end - 1) != ']')
-: 406: {
#####: 407: report_error (parser, "Invalid syntax for section header", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
call 0 never executed
#####: 408: parser_free (parser);
call 0 never executed
#####: 409: return FALSE;
-: 410: }
-: 411:
24: 412: section_name = unescape_string (parser,
call 0 returned 100%
-: 413: &parser->data, parser->pos + 1, line_end - 1,
-: 414: error);
-: 415:
24: 416: if (section_name == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 417: {
#####: 418: parser_free (parser);
call 0 never executed
#####: 419: return FALSE;
-: 420: }
-: 421:
24: 422: if (!is_valid_section_name (section_name))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 423: {
#####: 424: report_error (parser, "Invalid characters in section name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error);
call 0 never executed
#####: 425: parser_free (parser);
call 0 never executed
#####: 426: dbus_free (section_name);
call 0 never executed
#####: 427: return FALSE;
-: 428: }
-: 429:
24: 430: if (open_section (parser, section_name) == NULL)
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 431: {
#####: 432: dbus_free (section_name);
call 0 never executed
#####: 433: return FALSE;
-: 434: }
-: 435:
24: 436: if (line_end == parser->len)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 437: parser->pos = parser->len;
-: 438: else
24: 439: parser->pos = line_end + 1;
-: 440:
24: 441: parser->line_num += 1;
-: 442:
24: 443: dbus_free (section_name);
call 0 returned 100%
-: 444:
24: 445: return TRUE;
-: 446:}
-: 447:
-: 448:static dbus_bool_t
-: 449:parse_key_value (BusDesktopFileParser *parser, DBusError *error)
function parse_key_value called 48 returned 100% blocks executed 61%
48: 450:{
-: 451: int line_end;
-: 452: int key_start, key_end;
-: 453: int value_start;
-: 454: int p;
-: 455: char *value, *tmp;
-: 456: DBusString key;
-: 457: BusDesktopFileLine *line;
-: 458:
48: 459: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 460:
48: 461: if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 462: line_end = parser->len;
-: 463:
48: 464: p = parser->pos;
48: 465: key_start = p;
288: 466: while (p < line_end &&
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 80%
branch 4 taken 20% (fallthrough)
-: 467: (valid[_dbus_string_get_byte (&parser->data, p)] & VALID_KEY_CHAR))
192: 468: p++;
48: 469: key_end = p;
-: 470:
48: 471: if (key_start == key_end)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 472: {
#####: 473: report_error (parser, "Empty key name", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
call 0 never executed
#####: 474: parser_free (parser);
call 0 never executed
#####: 475: return FALSE;
-: 476: }
-: 477:
-: 478: /* We ignore locales for now */
48: 479: if (p < line_end && _dbus_string_get_byte (&parser->data, p) == '[')
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 0% (fallthrough)
branch 4 taken 100%
-: 480: {
#####: 481: if (line_end == parser->len)
branch 0 never executed
branch 1 never executed
#####: 482: parser->pos = parser->len;
-: 483: else
#####: 484: parser->pos = line_end + 1;
-: 485:
#####: 486: parser->line_num += 1;
-: 487:
#####: 488: return TRUE;
-: 489: }
-: 490:
-: 491: /* Skip space before '=' */
96: 492: while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ')
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 0%
branch 4 taken 100% (fallthrough)
#####: 493: p++;
-: 494:
48: 495: if (p < line_end && _dbus_string_get_byte (&parser->data, p) != '=')
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 0% (fallthrough)
branch 4 taken 100%
-: 496: {
#####: 497: report_error (parser, "Invalid characters in key name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error);
call 0 never executed
#####: 498: parser_free (parser);
call 0 never executed
#####: 499: return FALSE;
-: 500: }
-: 501:
48: 502: if (p == line_end)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 503: {
#####: 504: report_error (parser, "No '=' in key/value pair", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
call 0 never executed
#####: 505: parser_free (parser);
call 0 never executed
#####: 506: return FALSE;
-: 507: }
-: 508:
-: 509: /* Skip the '=' */
48: 510: p++;
-: 511:
-: 512: /* Skip space after '=' */
96: 513: while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ')
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 0%
branch 4 taken 100% (fallthrough)
#####: 514: p++;
-: 515:
48: 516: value_start = p;
-: 517:
48: 518: value = unescape_string (parser, &parser->data, value_start, line_end, error);
call 0 returned 100%
48: 519: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 520: {
#####: 521: parser_free (parser);
call 0 never executed
#####: 522: return FALSE;
-: 523: }
-: 524:
48: 525: line = new_line (parser);
call 0 returned 100%
48: 526: if (line == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 527: {
#####: 528: parser_free (parser);
call 0 never executed
#####: 529: return FALSE;
-: 530: }
-: 531:
48: 532: if (!_dbus_string_init (&key))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 533: {
#####: 534: parser_free (parser);
call 0 never executed
#####: 535: return FALSE;
-: 536: }
-: 537:
48: 538: if (!_dbus_string_copy_len (&parser->data, key_start, key_end - key_start,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 539: &key, 0))
-: 540: {
#####: 541: parser_free (parser);
call 0 never executed
#####: 542: return FALSE;
-: 543: }
-: 544:
48: 545: if (!_dbus_string_steal_data (&key, &tmp))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 546: {
#####: 547: parser_free (parser);
call 0 never executed
#####: 548: return FALSE;
-: 549: }
-: 550:
48: 551: _dbus_string_free (&key);
call 0 returned 100%
-: 552:
48: 553: line->key = tmp;
48: 554: line->value = value;
-: 555:
48: 556: if (line_end == parser->len)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 557: parser->pos = parser->len;
-: 558: else
48: 559: parser->pos = line_end + 1;
-: 560:
48: 561: parser->line_num += 1;
-: 562:
48: 563: return TRUE;
-: 564:}
-: 565:
-: 566:static void
-: 567:report_error (BusDesktopFileParser *parser,
-: 568: char *message,
-: 569: const char *error_name,
-: 570: DBusError *error)
function report_error called 0 returned 0% blocks executed 0%
#####: 571:{
#####: 572: const char *section_name = NULL;
-: 573:
#####: 574: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 never executed
branch 1 never executed
call 2 never executed
branch 3 never executed
branch 4 never executed
call 5 never executed
-: 575:
#####: 576: if (parser->current_section != -1)
branch 0 never executed
branch 1 never executed
#####: 577: section_name = parser->desktop_file->sections[parser->current_section].section_name;
-: 578:
#####: 579: if (section_name)
branch 0 never executed
branch 1 never executed
#####: 580: dbus_set_error (error, error_name,
call 0 never executed
-: 581: "Error in section %s at line %d: %s\n", section_name, parser->line_num, message);
-: 582: else
#####: 583: dbus_set_error (error, error_name,
call 0 never executed
-: 584: "Error at line %d: %s\n", parser->line_num, message);
#####: 585:}
-: 586:
-: 587:#if 0
-: 588:static void
-: 589:dump_desktop_file (BusDesktopFile *file)
-: 590:{
-: 591: int i;
-: 592:
-: 593: for (i = 0; i < file->n_sections; i++)
-: 594: {
-: 595: int j;
-: 596:
-: 597: printf ("[%s]\n", file->sections[i].section_name);
-: 598:
-: 599: for (j = 0; j < file->sections[i].n_lines; j++)
-: 600: {
-: 601: printf ("%s=%s\n", file->sections[i].lines[j].key,
-: 602: file->sections[i].lines[j].value);
-: 603: }
-: 604: }
-: 605:}
-: 606:#endif
-: 607:
-: 608:BusDesktopFile*
-: 609:bus_desktop_file_load (DBusString *filename,
-: 610: DBusError *error)
function bus_desktop_file_load called 24 returned 100% blocks executed 71%
24: 611:{
-: 612: DBusString str;
-: 613: BusDesktopFileParser parser;
-: 614: DBusStat sb;
-: 615:
24: 616: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 617:
-: 618: /* Clearly there's a race here, but it's just to make it unlikely
-: 619: * that we do something silly, we still handle doing it below.
-: 620: */
24: 621: if (!_dbus_stat (filename, &sb, error))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 622: return NULL;
-: 623:
24: 624: if (sb.size > _DBUS_ONE_KILOBYTE * 128)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 625: {
#####: 626: dbus_set_error (error, DBUS_ERROR_FAILED,
call 0 never executed
-: 627: "Desktop file size (%ld bytes) is too large", (long) sb.size);
#####: 628: return NULL;
-: 629: }
-: 630:
24: 631: if (!_dbus_string_init (&str))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 632: return NULL;
-: 633:
24: 634: if (!_dbus_file_get_contents (&str, filename, error))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 635: {
#####: 636: _dbus_string_free (&str);
call 0 never executed
#####: 637: return NULL;
-: 638: }
-: 639:
24: 640: if (!_dbus_string_validate_utf8 (&str, 0, _dbus_string_get_length (&str)))
call 0 returned 100%
call 1 returned 100%
branch 2 taken 0% (fallthrough)
branch 3 taken 100%
-: 641: {
#####: 642: _dbus_string_free (&str);
call 0 never executed
#####: 643: dbus_set_error (error, DBUS_ERROR_FAILED,
call 0 never executed
-: 644: "invalid UTF-8");
#####: 645: return NULL;
-: 646: }
-: 647:
24: 648: parser.desktop_file = dbus_new0 (BusDesktopFile, 1);
call 0 returned 100%
24: 649: if (parser.desktop_file == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 650: {
#####: 651: _dbus_string_free (&str);
call 0 never executed
#####: 652: BUS_SET_OOM (error);
call 0 never executed
#####: 653: return NULL;
-: 654: }
-: 655:
24: 656: parser.data = str;
24: 657: parser.line_num = 1;
24: 658: parser.pos = 0;
24: 659: parser.len = _dbus_string_get_length (&parser.data);
call 0 returned 100%
24: 660: parser.current_section = -1;
-: 661:
123: 662: while (parser.pos < parser.len)
branch 0 taken 76%
branch 1 taken 24% (fallthrough)
-: 663: {
75: 664: if (_dbus_string_get_byte (&parser.data, parser.pos) == '[')
call 0 returned 100%
branch 1 taken 32% (fallthrough)
branch 2 taken 68%
-: 665: {
24: 666: if (!parse_section_start (&parser, error))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 667: {
#####: 668: return NULL;
-: 669: }
-: 670: }
54: 671: else if (is_blank_line (&parser) ||
call 0 returned 100%
branch 1 taken 94% (fallthrough)
branch 2 taken 6%
call 3 returned 100%
branch 4 taken 0% (fallthrough)
branch 5 taken 100%
-: 672: _dbus_string_get_byte (&parser.data, parser.pos) == '#')
3: 673: parse_comment_or_blank (&parser);
call 0 returned 100%
-: 674: else
-: 675: {
48: 676: if (!parse_key_value (&parser, error))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 677: {
#####: 678: return NULL;
-: 679: }
-: 680: }
-: 681: }
-: 682:
24: 683: _dbus_string_free (&parser.data);
call 0 returned 100%
-: 684:
24: 685: return parser.desktop_file;
-: 686:}
-: 687:
-: 688:static BusDesktopFileSection *
-: 689:lookup_section (BusDesktopFile *desktop_file,
-: 690: const char *section_name)
function lookup_section called 48 returned 100% blocks executed 70%
48: 691:{
-: 692: BusDesktopFileSection *section;
-: 693: int i;
-: 694:
48: 695: if (section_name == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 696: return NULL;
-: 697:
48: 698: for (i = 0; i < desktop_file->n_sections; i ++)
branch 0 taken 100%
branch 1 taken 0% (fallthrough)
-: 699: {
48: 700: section = &desktop_file->sections[i];
-: 701:
48: 702: if (strcmp (section->section_name, section_name) == 0)
call 0 returned 100%
branch 1 taken 100% (fallthrough)
branch 2 taken 0%
48: 703: return section;
-: 704: }
-: 705:
#####: 706: return NULL;
-: 707:}
-: 708:
-: 709:static BusDesktopFileLine *
-: 710:lookup_line (BusDesktopFile *desktop_file,
-: 711: BusDesktopFileSection *section,
-: 712: const char *keyname)
function lookup_line called 48 returned 100% blocks executed 88%
48: 713:{
-: 714: BusDesktopFileLine *line;
-: 715: int i;
-: 716:
72: 717: for (i = 0; i < section->n_lines; i++)
branch 0 taken 100%
branch 1 taken 0% (fallthrough)
-: 718: {
72: 719: line = §ion->lines[i];
-: 720:
72: 721: if (strcmp (line->key, keyname) == 0)
call 0 returned 100%
branch 1 taken 67% (fallthrough)
branch 2 taken 33%
48: 722: return line;
-: 723: }
-: 724:
#####: 725: return NULL;
-: 726:}
-: 727:
-: 728:dbus_bool_t
-: 729:bus_desktop_file_get_raw (BusDesktopFile *desktop_file,
-: 730: const char *section_name,
-: 731: const char *keyname,
-: 732: const char **val)
function bus_desktop_file_get_raw called 48 returned 100% blocks executed 75%
48: 733:{
-: 734: BusDesktopFileSection *section;
-: 735: BusDesktopFileLine *line;
-: 736:
48: 737: *val = NULL;
-: 738:
48: 739: section = lookup_section (desktop_file, section_name);
call 0 returned 100%
-: 740:
48: 741: if (!section)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 742: return FALSE;
-: 743:
48: 744: line = lookup_line (desktop_file,
call 0 returned 100%
-: 745: section,
-: 746: keyname);
-: 747:
48: 748: if (!line)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 749: return FALSE;
-: 750:
48: 751: *val = line->value;
-: 752:
48: 753: return TRUE;
-: 754:}
-: 755:
-: 756:dbus_bool_t
-: 757:bus_desktop_file_get_string (BusDesktopFile *desktop_file,
-: 758: const char *section,
-: 759: const char *keyname,
-: 760: char **val)
function bus_desktop_file_get_string called 48 returned 100% blocks executed 75%
48: 761:{
-: 762: const char *raw;
-: 763:
48: 764: *val = NULL;
-: 765:
48: 766: if (!bus_desktop_file_get_raw (desktop_file, section, keyname, &raw))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 767: return FALSE;
-: 768:
48: 769: *val = _dbus_strdup (raw);
call 0 returned 100%
-: 770:
-: 771: /* FIXME we don't distinguish "key not found" from "out of memory" here,
-: 772: * which is broken.
-: 773: */
48: 774: if (*val == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 775: return FALSE;
-: 776:
48: 777: return TRUE;
-: 778:}