-/* -*- mode: C; c-file-style: "gnu" -*- */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* desktop-file.c .desktop file parser
*
* Copyright (C) 2003 CodeFactory AB
* Copyright (C) 2003 Red Hat Inc.
*
- * Licensed under the Academic Free License version 1.2
+ * Licensed under the Academic Free License version 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
+
+#include <config.h>
#include <dbus/dbus-sysdeps.h>
#include <dbus/dbus-internals.h>
#include "desktop-file.h"
int n_allocated_sections;
};
+/**
+ * Parser for service files.
+ */
typedef struct
{
- DBusString data;
+ DBusString data; /**< The data from the file */
- BusDesktopFile *desktop_file;
- int current_section;
+ BusDesktopFile *desktop_file; /**< The resulting object */
+ int current_section; /**< The current section being parsed */
- int pos, len;
- int line_num;
+ int pos; /**< Current position */
+ int len; /**< Length */
+ int line_num; /**< Current line number */
} BusDesktopFileParser;
#define VALID_KEY_CHAR 1
#define VALID_LOCALE_CHAR 2
-unsigned char valid[256] = {
+static unsigned char valid[256] = {
0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 ,
line = §ion->lines[section->n_lines++];
- memset (line, 0, sizeof (BusDesktopFileLine));
+ _DBUS_ZERO(*line);
return line;
}
static void
parse_comment_or_blank (BusDesktopFileParser *parser)
{
- int line_end;
+ int line_end, eol_len;
- if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
+ if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len))
line_end = parser->len;
if (line_end == parser->len)
parser->pos = parser->len;
else
- parser->pos = line_end + 1;
+ parser->pos = line_end + eol_len;
parser->line_num += 1;
}
static dbus_bool_t
parse_section_start (BusDesktopFileParser *parser, DBusError *error)
{
- int line_end;
+ int line_end, eol_len;
char *section_name;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
+
+ if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len))
line_end = parser->len;
if (line_end - parser->pos <= 2 ||
if (open_section (parser, section_name) == NULL)
{
dbus_free (section_name);
+ parser_free (parser);
+ BUS_SET_OOM (error);
return FALSE;
}
if (line_end == parser->len)
parser->pos = parser->len;
else
- parser->pos = line_end + 1;
+ parser->pos = line_end + eol_len;
parser->line_num += 1;
static dbus_bool_t
parse_key_value (BusDesktopFileParser *parser, DBusError *error)
{
- int line_end;
+ int line_end, eol_len;
int key_start, key_end;
int value_start;
int p;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
+ if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len))
line_end = parser->len;
-
+
p = parser->pos;
key_start = p;
while (p < line_end &&
}
/* We ignore locales for now */
+ if (p < line_end && _dbus_string_get_byte (&parser->data, p) == '[')
+ {
+ if (line_end == parser->len)
+ parser->pos = parser->len;
+ else
+ parser->pos = line_end + eol_len;
+
+ parser->line_num += 1;
+
+ return TRUE;
+ }
/* Skip space before '=' */
while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ')
line = new_line (parser);
if (line == NULL)
{
+ dbus_free (value);
parser_free (parser);
+ BUS_SET_OOM (error);
return FALSE;
}
- if (!_dbus_string_init (&key, key_end - key_start))
+ if (!_dbus_string_init (&key))
{
+ dbus_free (value);
parser_free (parser);
+ BUS_SET_OOM (error);
return FALSE;
}
if (!_dbus_string_copy_len (&parser->data, key_start, key_end - key_start,
&key, 0))
{
+ _dbus_string_free (&key);
+ dbus_free (value);
parser_free (parser);
+ BUS_SET_OOM (error);
return FALSE;
}
if (!_dbus_string_steal_data (&key, &tmp))
{
+ _dbus_string_free (&key);
+ dbus_free (value);
parser_free (parser);
+ BUS_SET_OOM (error);
return FALSE;
}
if (line_end == parser->len)
parser->pos = parser->len;
else
- parser->pos = line_end + 1;
+ parser->pos = line_end + eol_len;
parser->line_num += 1;
return NULL;
}
- if (!_dbus_string_init (&str, _DBUS_INT_MAX))
- return NULL;
+ if (!_dbus_string_init (&str))
+ {
+ BUS_SET_OOM (error);
+ return NULL;
+ }
if (!_dbus_file_get_contents (&str, filename, error))
{
parser.pos = 0;
parser.len = _dbus_string_get_length (&parser.data);
parser.current_section = -1;
-
+
while (parser.pos < parser.len)
{
if (_dbus_string_get_byte (&parser.data, parser.pos) == '[')
{
if (!parse_section_start (&parser, error))
{
- _dbus_string_free (&parser.data);
return NULL;
}
}
{
if (!parse_key_value (&parser, error))
{
- _dbus_string_free (&parser.data);
return NULL;
}
}
bus_desktop_file_get_string (BusDesktopFile *desktop_file,
const char *section,
const char *keyname,
- char **val)
+ char **val,
+ DBusError *error)
{
const char *raw;
-
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
*val = NULL;
if (!bus_desktop_file_get_raw (desktop_file, section, keyname, &raw))
- return FALSE;
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "No \"%s\" key in .service file\n", keyname);
+ return FALSE;
+ }
*val = _dbus_strdup (raw);
- /* FIXME we don't distinguish "key not found" from "out of memory" here,
- * which is broken.
- */
if (*val == NULL)
- return FALSE;
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
return TRUE;
}