Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > media > main-release > by-pkgid > 926d2d1e3111287cee1b0a4fad4fb4f6 > files > 149

lib64dbus-1_3-devel-0.92-6mdv2007.0.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>desktop-file.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; <a class="qindex" href="annotated.html">Data Structures</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Data Fields</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>desktop-file.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* desktop-file.c  .desktop file parser</font>
00003 <font class="comment"> *</font>
00004 <font class="comment"> * Copyright (C) 2003  CodeFactory AB</font>
00005 <font class="comment"> * Copyright (C) 2003  Red Hat Inc.</font>
00006 <font class="comment"> *</font>
00007 <font class="comment"> * Licensed under the Academic Free License version 1.2</font>
00008 <font class="comment"> * </font>
00009 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font>
00010 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
00011 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font>
00012 <font class="comment"> * (at your option) any later version.</font>
00013 <font class="comment"> *</font>
00014 <font class="comment"> * This program is distributed in the hope that it will be useful,</font>
00015 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00016 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</font>
00017 <font class="comment"> * GNU General Public License for more details.</font>
00018 <font class="comment"> * </font>
00019 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
00020 <font class="comment"> * along with this program; if not, write to the Free Software</font>
00021 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</font>
00022 <font class="comment"> *</font>
00023 <font class="comment"> */</font>
00024 <font class="preprocessor">#include &lt;dbus/dbus-sysdeps.h&gt;</font>
00025 <font class="preprocessor">#include &lt;dbus/dbus-internals.h&gt;</font>
00026 <font class="preprocessor">#include "desktop-file.h"</font>
00027 <font class="preprocessor">#include "utils.h"</font>
00028 
00029 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00030 <font class="keyword"></font>{
00031   <font class="keywordtype">char</font> *key;
00032   <font class="keywordtype">char</font> *value;
00033 } BusDesktopFileLine;
00034 
00035 <font class="keyword">typedef</font> <font class="keyword">struct</font>
00036 <font class="keyword"></font>{
00037   <font class="keywordtype">char</font> *section_name;
00038   
00039   <font class="keywordtype">int</font> n_lines;
00040   BusDesktopFileLine *lines;
00041   <font class="keywordtype">int</font> n_allocated_lines;  
00042 } BusDesktopFileSection;
00043 
00044 <font class="keyword">struct </font>BusDesktopFile
00045 {
00046   <font class="keywordtype">int</font> n_sections;
00047   BusDesktopFileSection *sections;
00048   <font class="keywordtype">int</font> n_allocated_sections;
00049 };
00050 
<a name="l00054"></a><a class="code" href="structBusDesktopFileParser.html">00054</a> <font class="keyword">typedef</font> <font class="keyword">struct</font>
00055 <font class="keyword"></font>{
<a name="l00056"></a><a class="code" href="structBusDesktopFileParser.html#m0">00056</a>   <a class="code" href="structDBusString.html">DBusString</a> data; 
<a name="l00058"></a><a class="code" href="structBusDesktopFileParser.html#m1">00058</a>   BusDesktopFile *desktop_file; 
<a name="l00059"></a><a class="code" href="structBusDesktopFileParser.html#m2">00059</a>   <font class="keywordtype">int</font> current_section;    
<a name="l00061"></a><a class="code" href="structBusDesktopFileParser.html#m3">00061</a>   <font class="keywordtype">int</font> pos;          
<a name="l00062"></a><a class="code" href="structBusDesktopFileParser.html#m4">00062</a>   <font class="keywordtype">int</font> len;          
<a name="l00063"></a><a class="code" href="structBusDesktopFileParser.html#m5">00063</a>   <font class="keywordtype">int</font> line_num;     
00065 } <a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a>;
00066 
00067 <font class="preprocessor">#define VALID_KEY_CHAR 1</font>
00068 <font class="preprocessor"></font><font class="preprocessor">#define VALID_LOCALE_CHAR 2</font>
00069 <font class="preprocessor"></font><font class="keywordtype">unsigned</font> <font class="keywordtype">char</font> valid[256] = { 
00070    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00071    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00072    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 , 
00073    0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00074    0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 
00075    0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x2 , 
00076    0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 
00077    0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00078    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00079    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00080    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00081    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00082    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00083    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00084    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00085    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
00086 };
00087 
00088 <font class="keyword">static</font> <font class="keywordtype">void</font> report_error (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser,
00089                           <font class="keywordtype">char</font>                 *message,
00090                           <font class="keyword">const</font> <font class="keywordtype">char</font>           *error_name,
00091                           <a class="code" href="structDBusError.html">DBusError</a>            *error);
00092 
00093 <font class="keyword">static</font> <font class="keywordtype">void</font>
00094 parser_free (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser)
00095 {
00096   bus_desktop_file_free (parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a>);
00097   
00098   _dbus_string_free (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>);
00099 }
00100 
00101 <font class="keyword">static</font> <font class="keywordtype">void</font>
00102 bus_desktop_file_line_free (BusDesktopFileLine *line)
00103 {
00104   dbus_free (line-&gt;key);
00105   dbus_free (line-&gt;value);
00106 }
00107 
00108 <font class="keyword">static</font> <font class="keywordtype">void</font>
00109 bus_desktop_file_section_free (BusDesktopFileSection *section)
00110 {
00111   <font class="keywordtype">int</font> i;
00112 
00113   <font class="keywordflow">for</font> (i = 0; i &lt; section-&gt;n_lines; i++)
00114     bus_desktop_file_line_free (&amp;section-&gt;lines[i]);
00115 
00116   dbus_free (section-&gt;lines);
00117   dbus_free (section-&gt;section_name);
00118 }
00119 
00120 <font class="keywordtype">void</font>
00121 bus_desktop_file_free (BusDesktopFile *desktop_file)
00122 {
00123   <font class="keywordtype">int</font> i;
00124 
00125   <font class="keywordflow">for</font> (i = 0; i &lt; desktop_file-&gt;n_sections; i++)
00126     bus_desktop_file_section_free (&amp;desktop_file-&gt;sections[i]);
00127   dbus_free (desktop_file-&gt;sections);
00128 
00129   dbus_free (desktop_file);
00130 }
00131 
00132 <font class="keyword">static</font> dbus_bool_t
00133 grow_lines_in_section (BusDesktopFileSection *section)
00134 {
00135   BusDesktopFileLine *lines;
00136   
00137   <font class="keywordtype">int</font> new_n_lines;
00138 
00139   <font class="keywordflow">if</font> (section-&gt;n_allocated_lines == 0)
00140     new_n_lines = 1;
00141   <font class="keywordflow">else</font>
00142     new_n_lines = section-&gt;n_allocated_lines*2;
00143 
00144   lines = dbus_realloc (section-&gt;lines,
00145                         sizeof (BusDesktopFileLine) * new_n_lines);
00146 
00147   <font class="keywordflow">if</font> (lines == NULL)
00148     <font class="keywordflow">return</font> FALSE;
00149   
00150   section-&gt;lines = lines;
00151   section-&gt;n_allocated_lines = new_n_lines;
00152 
00153   <font class="keywordflow">return</font> TRUE;
00154 }
00155 
00156 <font class="keyword">static</font> dbus_bool_t
00157 grow_sections (BusDesktopFile *desktop_file)
00158 {
00159   <font class="keywordtype">int</font> new_n_sections;
00160   BusDesktopFileSection *sections;
00161   
00162   <font class="keywordflow">if</font> (desktop_file-&gt;n_allocated_sections == 0)
00163     new_n_sections = 1;
00164   <font class="keywordflow">else</font>
00165     new_n_sections = desktop_file-&gt;n_allocated_sections*2;
00166 
00167   sections = dbus_realloc (desktop_file-&gt;sections,
00168                            sizeof (BusDesktopFileSection) * new_n_sections);
00169   <font class="keywordflow">if</font> (sections == NULL)
00170     <font class="keywordflow">return</font> FALSE;
00171   
00172   desktop_file-&gt;sections = sections;
00173   
00174   desktop_file-&gt;n_allocated_sections = new_n_sections;
00175 
00176   <font class="keywordflow">return</font> TRUE;
00177 }
00178 
00179 <font class="keyword">static</font> <font class="keywordtype">char</font> *
00180 unescape_string (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser,
00181                  <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a>     *str,
00182                  <font class="keywordtype">int</font>                   pos,
00183                  <font class="keywordtype">int</font>                   end_pos,
00184                  <a class="code" href="structDBusError.html">DBusError</a>            *error)
00185 {
00186   <font class="keywordtype">char</font> *retval, *q;
00187 
00188   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00189   
00190   <font class="comment">/* len + 1 is enough, because unescaping never makes the</font>
00191 <font class="comment">   * string longer</font>
00192 <font class="comment">   */</font>
00193   retval = dbus_malloc (end_pos - pos + 1);
00194   <font class="keywordflow">if</font> (retval == NULL)
00195     {
00196       BUS_SET_OOM (error);
00197       <font class="keywordflow">return</font> NULL;
00198     }
00199 
00200   q = retval;
00201   
00202   <font class="keywordflow">while</font> (pos &lt; end_pos)
00203     {
00204       <font class="keywordflow">if</font> (_dbus_string_get_byte (str, pos) == 0)
00205         {
00206           <font class="comment">/* Found an embedded null */</font>
00207           dbus_free (retval);
00208           report_error (parser, <font class="stringliteral">"Text to be unescaped contains embedded nul"</font>,
00209                         BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
00210           <font class="keywordflow">return</font> NULL;
00211         }
00212 
00213       <font class="keywordflow">if</font> (_dbus_string_get_byte (str, pos) == <font class="charliteral">'\\'</font>)
00214         {
00215           pos ++;
00216 
00217           <font class="keywordflow">if</font> (pos &gt;= end_pos)
00218             {
00219               <font class="comment">/* Escape at end of string */</font>
00220               dbus_free (retval);
00221               report_error (parser, <font class="stringliteral">"Text to be unescaped ended in \\"</font>,
00222                             BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
00223               <font class="keywordflow">return</font> NULL;
00224             }
00225 
00226           <font class="keywordflow">switch</font> (_dbus_string_get_byte (str, pos))
00227             {
00228             <font class="keywordflow">case</font> <font class="charliteral">'s'</font>:
00229               *q++ = <font class="charliteral">' '</font>;
00230               <font class="keywordflow">break</font>;
00231            <font class="keywordflow">case</font> <font class="charliteral">'t'</font>:
00232               *q++ = <font class="charliteral">'\t'</font>;
00233               <font class="keywordflow">break</font>;
00234            <font class="keywordflow">case</font> <font class="charliteral">'n'</font>:
00235               *q++ = <font class="charliteral">'\n'</font>;
00236               <font class="keywordflow">break</font>;
00237            <font class="keywordflow">case</font> <font class="charliteral">'r'</font>:
00238               *q++ = <font class="charliteral">'\r'</font>;
00239               <font class="keywordflow">break</font>;
00240            <font class="keywordflow">case</font> <font class="charliteral">'\\'</font>:
00241               *q++ = <font class="charliteral">'\\'</font>;
00242               <font class="keywordflow">break</font>;
00243            <font class="keywordflow">default</font>:
00244              <font class="comment">/* Invalid escape code */</font>
00245              dbus_free (retval);
00246              report_error (parser, <font class="stringliteral">"Text to be unescaped had invalid escape sequence"</font>,
00247                            BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error);
00248              <font class="keywordflow">return</font> NULL;
00249             }
00250           pos++;
00251         }
00252       <font class="keywordflow">else</font>
00253         {
00254           *q++ =_dbus_string_get_byte (str, pos);
00255 
00256           pos++;
00257         }
00258     }
00259 
00260   *q = 0;
00261 
00262   <font class="keywordflow">return</font> retval;
00263 }
00264 
00265 <font class="keyword">static</font> BusDesktopFileSection* 
00266 new_section (BusDesktopFile *desktop_file,
00267              <font class="keyword">const</font> <font class="keywordtype">char</font>     *name)
00268 {
00269   <font class="keywordtype">int</font> n;
00270   <font class="keywordtype">char</font> *name_copy;
00271   
00272   <font class="keywordflow">if</font> (desktop_file-&gt;n_allocated_sections == desktop_file-&gt;n_sections)
00273     {
00274       <font class="keywordflow">if</font> (!grow_sections (desktop_file))
00275         <font class="keywordflow">return</font> NULL;
00276     }
00277 
00278   name_copy = _dbus_strdup (name);
00279   <font class="keywordflow">if</font> (name_copy == NULL)
00280     <font class="keywordflow">return</font> NULL;
00281 
00282   n = desktop_file-&gt;n_sections;
00283   desktop_file-&gt;sections[n].section_name = name_copy;
00284 
00285   desktop_file-&gt;sections[n].n_lines = 0;
00286   desktop_file-&gt;sections[n].lines = NULL;
00287   desktop_file-&gt;sections[n].n_allocated_lines = 0;
00288 
00289   <font class="keywordflow">if</font> (!grow_lines_in_section (&amp;desktop_file-&gt;sections[n]))
00290     {
00291       dbus_free (desktop_file-&gt;sections[n].section_name);
00292       desktop_file-&gt;sections[n].section_name = NULL;
00293       <font class="keywordflow">return</font> NULL;
00294     }
00295 
00296   desktop_file-&gt;n_sections += 1;
00297   
00298   <font class="keywordflow">return</font> &amp;desktop_file-&gt;sections[n];  
00299 }
00300 
00301 <font class="keyword">static</font> BusDesktopFileSection* 
00302 open_section (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser,
00303               <font class="keywordtype">char</font>                 *name)
00304 {  
00305   BusDesktopFileSection *section;
00306 
00307   section = new_section (parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a>, name);
00308   <font class="keywordflow">if</font> (section == NULL)
00309     <font class="keywordflow">return</font> NULL;
00310   
00311   parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m2">current_section</a> = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a>-&gt;n_sections - 1;
00312   _dbus_assert (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a>-&gt;sections[parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m2">current_section</a>] == section);
00313   
00314   <font class="keywordflow">return</font> section;
00315 }
00316 
00317 <font class="keyword">static</font> BusDesktopFileLine *
00318 new_line (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser)
00319 {
00320   BusDesktopFileSection *section;
00321   BusDesktopFileLine *line;
00322   
00323   section = &amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a>-&gt;sections[parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m2">current_section</a>];
00324 
00325   <font class="keywordflow">if</font> (section-&gt;n_allocated_lines == section-&gt;n_lines)
00326     {
00327       <font class="keywordflow">if</font> (!grow_lines_in_section (section))
00328         <font class="keywordflow">return</font> NULL;
00329     }
00330 
00331   line = &amp;section-&gt;lines[section-&gt;n_lines++];
00332 
00333   memset (line, 0, <font class="keyword">sizeof</font> (BusDesktopFileLine));
00334     
00335   <font class="keywordflow">return</font> line;
00336 }
00337 
00338 <font class="keyword">static</font> dbus_bool_t
00339 is_blank_line (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser)
00340 {
00341   <font class="keywordtype">int</font> p;
00342   <font class="keywordtype">char</font> c;
00343   
00344   p = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a>;
00345 
00346   c = _dbus_string_get_byte (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, p);
00347 
00348   <font class="keywordflow">while</font> (c &amp;&amp; c != <font class="charliteral">'\n'</font>)
00349     {
00350       <font class="keywordflow">if</font> (!(c == <font class="charliteral">' '</font> || c == <font class="charliteral">'\t'</font> || c == <font class="charliteral">'\n'</font> || c == <font class="charliteral">'\r'</font> || c == <font class="charliteral">'\f'</font>))
00351         <font class="keywordflow">return</font> FALSE;
00352       
00353       p++;
00354       c = _dbus_string_get_byte (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, p);
00355     }
00356 
00357   <font class="keywordflow">return</font> TRUE;
00358 }
00359 
00360 <font class="keyword">static</font> <font class="keywordtype">void</font>
00361 parse_comment_or_blank (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser)
00362 {
00363   <font class="keywordtype">int</font> line_end;
00364   
00365   <font class="keywordflow">if</font> (!_dbus_string_find (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a>, <font class="stringliteral">"\n"</font>, &amp;line_end))
00366     line_end = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>;
00367 
00368   <font class="keywordflow">if</font> (line_end == parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>)
00369     parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>;
00370   <font class="keywordflow">else</font>
00371     parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> = line_end + 1;
00372   
00373   parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m5">line_num</a> += 1;
00374 }
00375 
00376 <font class="keyword">static</font> dbus_bool_t
00377 is_valid_section_name (<font class="keyword">const</font> <font class="keywordtype">char</font> *name)
00378 {
00379   <font class="comment">/* 5. Group names may contain all ASCII characters except for control characters and '[' and ']'. */</font>
00380 
00381   <font class="keywordflow">while</font> (*name)
00382     {
00383       <font class="keywordflow">if</font> (!((*name &gt;= <font class="charliteral">'A'</font> &amp;&amp; *name &lt;= 'Z') || (*name &gt;= <font class="charliteral">'a'</font> || *name &lt;= <font class="charliteral">'z'</font>) ||
00384             *name == <font class="charliteral">'\n'</font> || *name == <font class="charliteral">'\t'</font>))
00385         <font class="keywordflow">return</font> FALSE;
00386       
00387       name++;
00388     }
00389 
00390   <font class="keywordflow">return</font> TRUE;
00391 }
00392 
00393 <font class="keyword">static</font> dbus_bool_t
00394 parse_section_start (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser, <a class="code" href="structDBusError.html">DBusError</a> *error)
00395 {
00396   <font class="keywordtype">int</font> line_end;
00397   <font class="keywordtype">char</font> *section_name;
00398 
00399   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00400   
00401   <font class="keywordflow">if</font> (!_dbus_string_find (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a>, <font class="stringliteral">"\n"</font>, &amp;line_end))
00402     line_end = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>;
00403   
00404   <font class="keywordflow">if</font> (line_end - parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> &lt;= 2 ||
00405       _dbus_string_get_byte (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, line_end - 1) != <font class="charliteral">']'</font>)
00406     {
00407       report_error (parser, <font class="stringliteral">"Invalid syntax for section header"</font>, BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
00408       parser_free (parser);
00409       <font class="keywordflow">return</font> FALSE;
00410     }
00411 
00412   section_name = unescape_string (parser,
00413                                   &amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> + 1, line_end - 1,
00414                                   error);
00415 
00416   <font class="keywordflow">if</font> (section_name == NULL)
00417     {
00418       parser_free (parser);
00419       <font class="keywordflow">return</font> FALSE;
00420     }
00421 
00422   <font class="keywordflow">if</font> (!is_valid_section_name (section_name))
00423     {
00424       report_error (parser, <font class="stringliteral">"Invalid characters in section name"</font>, BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error);
00425       parser_free (parser);
00426       dbus_free (section_name);
00427       <font class="keywordflow">return</font> FALSE;
00428     }
00429 
00430   <font class="keywordflow">if</font> (open_section (parser, section_name) == NULL)
00431     {
00432       dbus_free (section_name);
00433       <font class="keywordflow">return</font> FALSE;
00434     }
00435 
00436   <font class="keywordflow">if</font> (line_end == parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>)
00437     parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>;
00438   <font class="keywordflow">else</font>
00439     parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> = line_end + 1;
00440   
00441   parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m5">line_num</a> += 1;
00442 
00443   dbus_free (section_name);
00444   
00445   <font class="keywordflow">return</font> TRUE;
00446 }
00447 
00448 <font class="keyword">static</font> dbus_bool_t
00449 parse_key_value (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser, <a class="code" href="structDBusError.html">DBusError</a> *error)
00450 {
00451   <font class="keywordtype">int</font> line_end;
00452   <font class="keywordtype">int</font> key_start, key_end;
00453   <font class="keywordtype">int</font> value_start;
00454   <font class="keywordtype">int</font> p;
00455   <font class="keywordtype">char</font> *value, *tmp;
00456   <a class="code" href="structDBusString.html">DBusString</a> key;
00457   BusDesktopFileLine *line;
00458 
00459   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00460   
00461   <font class="keywordflow">if</font> (!_dbus_string_find (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a>, <font class="stringliteral">"\n"</font>, &amp;line_end))
00462     line_end = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>;
00463 
00464   p = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a>;
00465   key_start = p;
00466   <font class="keywordflow">while</font> (p &lt; line_end &amp;&amp;
00467          (valid[_dbus_string_get_byte (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, p)] &amp; VALID_KEY_CHAR))
00468     p++;
00469   key_end = p;
00470   
00471   <font class="keywordflow">if</font> (key_start == key_end)
00472     {
00473       report_error (parser, <font class="stringliteral">"Empty key name"</font>, BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
00474       parser_free (parser);
00475       <font class="keywordflow">return</font> FALSE;
00476     }
00477 
00478   <font class="comment">/* We ignore locales for now */</font>
00479   
00480   <font class="comment">/* Skip space before '=' */</font>
00481   <font class="keywordflow">while</font> (p &lt; line_end &amp;&amp; _dbus_string_get_byte (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, p) == <font class="charliteral">' '</font>)
00482     p++;
00483 
00484   <font class="keywordflow">if</font> (p &lt; line_end &amp;&amp; _dbus_string_get_byte (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, p) != <font class="charliteral">'='</font>)
00485     {
00486       report_error (parser, <font class="stringliteral">"Invalid characters in key name"</font>, BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error);
00487       parser_free (parser);
00488       <font class="keywordflow">return</font> FALSE;
00489     }
00490 
00491   <font class="keywordflow">if</font> (p == line_end)
00492     {
00493       report_error (parser, <font class="stringliteral">"No '=' in key/value pair"</font>, BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error);
00494       parser_free (parser);
00495       <font class="keywordflow">return</font> FALSE;
00496     }
00497 
00498   <font class="comment">/* Skip the '=' */</font>
00499   p++;
00500 
00501   <font class="comment">/* Skip space after '=' */</font>
00502   <font class="keywordflow">while</font> (p &lt; line_end &amp;&amp; _dbus_string_get_byte (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, p) == <font class="charliteral">' '</font>)
00503     p++;
00504 
00505   value_start = p;
00506   
00507   value = unescape_string (parser, &amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, value_start, line_end, error);
00508   <font class="keywordflow">if</font> (value == NULL)
00509     {
00510       parser_free (parser);
00511       <font class="keywordflow">return</font> FALSE;
00512     }
00513 
00514   line = new_line (parser);
00515   <font class="keywordflow">if</font> (line == NULL)
00516     {
00517       parser_free (parser);
00518       <font class="keywordflow">return</font> FALSE;
00519     }
00520   
00521   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;key))
00522     {
00523       parser_free (parser);
00524       <font class="keywordflow">return</font> FALSE;
00525     }
00526   
00527   <font class="keywordflow">if</font> (!_dbus_string_copy_len (&amp;parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, key_start, key_end - key_start,
00528                               &amp;key, 0))
00529     {
00530       parser_free (parser);
00531       <font class="keywordflow">return</font> FALSE;
00532     }
00533   
00534   <font class="keywordflow">if</font> (!_dbus_string_steal_data (&amp;key, &amp;tmp))
00535     {
00536       parser_free (parser);
00537       <font class="keywordflow">return</font> FALSE;
00538     }
00539   
00540   _dbus_string_free (&amp;key);
00541   
00542   line-&gt;key = tmp;
00543   line-&gt;value = value;
00544 
00545   <font class="keywordflow">if</font> (line_end == parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>)
00546     parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m4">len</a>;
00547   <font class="keywordflow">else</font>
00548     parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> = line_end + 1;
00549   
00550   parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m5">line_num</a> += 1;
00551 
00552   <font class="keywordflow">return</font> TRUE;
00553 }
00554 
00555 <font class="keyword">static</font> <font class="keywordtype">void</font>
00556 report_error (<a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> *parser,
00557               <font class="keywordtype">char</font>                 *message,
00558               <font class="keyword">const</font> <font class="keywordtype">char</font>           *error_name,
00559               <a class="code" href="structDBusError.html">DBusError</a>            *error)
00560 {
00561   <font class="keyword">const</font> <font class="keywordtype">char</font> *section_name = NULL;
00562 
00563   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00564   
00565   <font class="keywordflow">if</font> (parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m2">current_section</a> != -1)
00566     section_name = parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a>-&gt;sections[parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m2">current_section</a>].section_name;
00567 
00568   <font class="keywordflow">if</font> (section_name)
00569     dbus_set_error (error, error_name,
00570                     <font class="stringliteral">"Error in section %s at line %d: %s\n"</font>, section_name, parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m5">line_num</a>, message);
00571   <font class="keywordflow">else</font>
00572     dbus_set_error (error, error_name,
00573                     <font class="stringliteral">"Error at line %d: %s\n"</font>, parser-&gt;<a class="code" href="structBusDesktopFileParser.html#m5">line_num</a>, message);
00574 }
00575 
00576 <font class="preprocessor">#if 0</font>
00577 <font class="preprocessor"></font><font class="keyword">static</font> <font class="keywordtype">void</font>
00578 dump_desktop_file (BusDesktopFile *file)
00579 {
00580   <font class="keywordtype">int</font> i;
00581 
00582   <font class="keywordflow">for</font> (i = 0; i &lt; file-&gt;n_sections; i++)
00583     {
00584       <font class="keywordtype">int</font> j;
00585       
00586       printf (<font class="stringliteral">"[%s]\n"</font>, file-&gt;sections[i].section_name);
00587 
00588       <font class="keywordflow">for</font> (j = 0; j &lt; file-&gt;sections[i].n_lines; j++)
00589         {
00590           printf (<font class="stringliteral">"%s=%s\n"</font>, file-&gt;sections[i].lines[j].key,
00591                   file-&gt;sections[i].lines[j].value);
00592         }
00593     }
00594 }
00595 <font class="preprocessor">#endif</font>
00596 <font class="preprocessor"></font>
00597 BusDesktopFile*
00598 bus_desktop_file_load (<a class="code" href="structDBusString.html">DBusString</a> *filename,
00599                        <a class="code" href="structDBusError.html">DBusError</a>  *error)
00600 {
00601   <a class="code" href="structDBusString.html">DBusString</a> str;
00602   <a class="code" href="structBusDesktopFileParser.html">BusDesktopFileParser</a> parser;
00603   <a class="code" href="structDBusStat.html">DBusStat</a> sb;
00604 
00605   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00606   
00607   <font class="comment">/* Clearly there's a race here, but it's just to make it unlikely</font>
00608 <font class="comment">   * that we do something silly, we still handle doing it below.</font>
00609 <font class="comment">   */</font>
00610   <font class="keywordflow">if</font> (!_dbus_stat (filename, &amp;sb, error))
00611     <font class="keywordflow">return</font> NULL;
00612 
00613   <font class="keywordflow">if</font> (sb.<a class="code" href="structDBusStat.html#m4">size</a> &gt; _DBUS_ONE_KILOBYTE * 128)
00614     {
00615       dbus_set_error (error, DBUS_ERROR_FAILED,
00616                       <font class="stringliteral">"Desktop file size (%ld bytes) is too large"</font>, (<font class="keywordtype">long</font>) sb.<a class="code" href="structDBusStat.html#m4">size</a>);
00617       <font class="keywordflow">return</font> NULL;
00618     }
00619   
00620   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;str))
00621     <font class="keywordflow">return</font> NULL;
00622   
00623   <font class="keywordflow">if</font> (!_dbus_file_get_contents (&amp;str, filename, error))
00624     {
00625       _dbus_string_free (&amp;str);
00626       <font class="keywordflow">return</font> NULL;
00627     }
00628 
00629   <font class="keywordflow">if</font> (!_dbus_string_validate_utf8 (&amp;str, 0, _dbus_string_get_length (&amp;str)))
00630     {
00631       _dbus_string_free (&amp;str);
00632       dbus_set_error (error, DBUS_ERROR_FAILED,
00633                       <font class="stringliteral">"invalid UTF-8"</font>);   
00634       <font class="keywordflow">return</font> NULL;
00635     }
00636   
00637   parser.<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a> = dbus_new0 (BusDesktopFile, 1);
00638   <font class="keywordflow">if</font> (parser.<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a> == NULL)
00639     {
00640       _dbus_string_free (&amp;str);
00641       BUS_SET_OOM (error);
00642       <font class="keywordflow">return</font> NULL;
00643     }
00644   
00645   parser.<a class="code" href="structBusDesktopFileParser.html#m0">data</a> = str;
00646   parser.<a class="code" href="structBusDesktopFileParser.html#m5">line_num</a> = 1;
00647   parser.<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> = 0;
00648   parser.<a class="code" href="structBusDesktopFileParser.html#m4">len</a> = _dbus_string_get_length (&amp;parser.<a class="code" href="structBusDesktopFileParser.html#m0">data</a>);
00649   parser.<a class="code" href="structBusDesktopFileParser.html#m2">current_section</a> = -1;
00650   
00651   <font class="keywordflow">while</font> (parser.<a class="code" href="structBusDesktopFileParser.html#m3">pos</a> &lt; parser.<a class="code" href="structBusDesktopFileParser.html#m4">len</a>)
00652     {
00653       <font class="keywordflow">if</font> (_dbus_string_get_byte (&amp;parser.<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, parser.<a class="code" href="structBusDesktopFileParser.html#m3">pos</a>) == <font class="charliteral">'['</font>)
00654         {
00655           <font class="keywordflow">if</font> (!parse_section_start (&amp;parser, error))
00656             {
00657               _dbus_string_free (&amp;parser.<a class="code" href="structBusDesktopFileParser.html#m0">data</a>);
00658               <font class="keywordflow">return</font> NULL;
00659             }
00660         }
00661       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (is_blank_line (&amp;parser) ||
00662                _dbus_string_get_byte (&amp;parser.<a class="code" href="structBusDesktopFileParser.html#m0">data</a>, parser.<a class="code" href="structBusDesktopFileParser.html#m3">pos</a>) == <font class="charliteral">'#'</font>)
00663         parse_comment_or_blank (&amp;parser);
00664       <font class="keywordflow">else</font>
00665         {
00666           <font class="keywordflow">if</font> (!parse_key_value (&amp;parser, error))
00667             {
00668               _dbus_string_free (&amp;parser.<a class="code" href="structBusDesktopFileParser.html#m0">data</a>);
00669               <font class="keywordflow">return</font> NULL;
00670             }
00671         }
00672     }
00673 
00674   _dbus_string_free (&amp;parser.<a class="code" href="structBusDesktopFileParser.html#m0">data</a>);
00675 
00676   <font class="keywordflow">return</font> parser.<a class="code" href="structBusDesktopFileParser.html#m1">desktop_file</a>;
00677 }
00678 
00679 <font class="keyword">static</font> BusDesktopFileSection *
00680 lookup_section (BusDesktopFile *desktop_file,
00681                 <font class="keyword">const</font> <font class="keywordtype">char</font>     *section_name)
00682 {
00683   BusDesktopFileSection *section;
00684   <font class="keywordtype">int</font> i;
00685   
00686   <font class="keywordflow">if</font> (section_name == NULL)
00687     <font class="keywordflow">return</font> NULL;
00688   
00689   <font class="keywordflow">for</font> (i = 0; i &lt; desktop_file-&gt;n_sections; i ++)
00690     {
00691       section = &amp;desktop_file-&gt;sections[i];
00692 
00693       <font class="keywordflow">if</font> (strcmp (section-&gt;section_name, section_name) == 0)
00694         <font class="keywordflow">return</font> section;
00695     }
00696   
00697   <font class="keywordflow">return</font> NULL;
00698 }
00699 
00700 <font class="keyword">static</font> BusDesktopFileLine *
00701 lookup_line (BusDesktopFile        *desktop_file,
00702              BusDesktopFileSection *section,
00703              <font class="keyword">const</font> <font class="keywordtype">char</font>            *keyname)
00704 {
00705   BusDesktopFileLine *line;
00706   <font class="keywordtype">int</font> i;
00707 
00708   <font class="keywordflow">for</font> (i = 0; i &lt; section-&gt;n_lines; i++)
00709     {
00710       line = &amp;section-&gt;lines[i];
00711       
00712       <font class="keywordflow">if</font> (strcmp (line-&gt;key, keyname) == 0)
00713         <font class="keywordflow">return</font> line;
00714     }
00715   
00716   <font class="keywordflow">return</font> NULL;
00717 }
00718 
00719 dbus_bool_t
00720 bus_desktop_file_get_raw (BusDesktopFile  *desktop_file,
00721                           <font class="keyword">const</font> <font class="keywordtype">char</font>      *section_name,
00722                           <font class="keyword">const</font> <font class="keywordtype">char</font>      *keyname,
00723                           <font class="keyword">const</font> <font class="keywordtype">char</font>     **val)
00724 {
00725   BusDesktopFileSection *section;
00726   BusDesktopFileLine *line;
00727 
00728   *val = NULL;
00729 
00730   section = lookup_section (desktop_file, section_name);
00731   
00732   <font class="keywordflow">if</font> (!section)
00733     <font class="keywordflow">return</font> FALSE;
00734 
00735   line = lookup_line (desktop_file,
00736                       section,
00737                       keyname);
00738 
00739   <font class="keywordflow">if</font> (!line)
00740     <font class="keywordflow">return</font> FALSE;
00741   
00742   *val = line-&gt;value;
00743   
00744   <font class="keywordflow">return</font> TRUE;
00745 }
00746 
00747 dbus_bool_t
00748 bus_desktop_file_get_string (BusDesktopFile  *desktop_file,
00749                              <font class="keyword">const</font> <font class="keywordtype">char</font>      *section,
00750                              <font class="keyword">const</font> <font class="keywordtype">char</font>      *keyname,
00751                              <font class="keywordtype">char</font>           **val)
00752 {
00753   <font class="keyword">const</font> <font class="keywordtype">char</font> *raw;
00754   
00755   *val = NULL;
00756   
00757   <font class="keywordflow">if</font> (!bus_desktop_file_get_raw (desktop_file, section, keyname, &amp;raw))
00758     <font class="keywordflow">return</font> FALSE;
00759 
00760   *val = _dbus_strdup (raw);
00761 
00762   <font class="comment">/* FIXME we don't distinguish "key not found" from "out of memory" here,</font>
00763 <font class="comment">   * which is broken.</font>
00764 <font class="comment">   */</font>
00765   <font class="keywordflow">if</font> (*val == NULL)
00766     <font class="keywordflow">return</font> FALSE;
00767   
00768   <font class="keywordflow">return</font> TRUE;
00769 }
</pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:31:02 2003 for D-BUS by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>