Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > 2269bb274471fd2722517c2c0b740d7f > files > 158

rpm-devel-4.0.4-19mdk.i586.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>rpmio/macro.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.17 -->
<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="globals.html">Globals</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>rpmio/macro.c</h1><a href="macro_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 <span class="comment">/*@-branchstate@*/</span>
<a name="l00006"></a><a class="code" href="macro_8c.html#a11">00006</a> <span class="comment">/*@unused@*/</span> <span class="keyword">static</span> <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a11">_debug</a> = 0;
00007 
00008 <span class="preprocessor">#include "<a class="code" href="system_8h.html">system.h</a>"</span>
00009 <span class="preprocessor">#include &lt;stdarg.h&gt;</span>
00010 
00011 <span class="preprocessor">#if !defined(isblank)</span>
<a name="l00012"></a><a class="code" href="macro_8c.html#a0">00012</a> <span class="preprocessor"></span><span class="preprocessor">#define isblank(_c)     ((_c) == ' ' || (_c) == '\t')</span>
00013 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l00014"></a><a class="code" href="macro_8c.html#a1">00014</a> <span class="preprocessor"></span><span class="preprocessor">#define iseol(_c)       ((_c) == '\n' || (_c) == '\r')</span>
00015 <span class="preprocessor"></span>
<a name="l00016"></a><a class="code" href="macro_8c.html#a2">00016</a> <span class="preprocessor">#define STREQ(_t, _f, _fn)      ((_fn) == (sizeof(_t)-1) &amp;&amp; !strncmp((_t), (_f), (_fn)))</span>
00017 <span class="preprocessor"></span>
00018 <span class="preprocessor">#ifdef DEBUG_MACROS</span>
00019 <span class="preprocessor"></span><span class="preprocessor">#include &lt;sys/types.h&gt;</span>
00020 <span class="preprocessor">#include &lt;errno.h&gt;</span>
00021 <span class="preprocessor">#include &lt;fcntl.h&gt;</span>
00022 <span class="preprocessor">#include &lt;getopt.h&gt;</span>
00023 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
00024 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
00025 <span class="preprocessor">#include &lt;string.h&gt;</span>
00026 <span class="preprocessor">#define rpmError fprintf</span>
00027 <span class="preprocessor"></span><span class="preprocessor">#define RPMERR_BADSPEC stderr</span>
00028 <span class="preprocessor"></span><span class="preprocessor">#undef  _</span>
00029 <span class="preprocessor"></span><span class="preprocessor">#define _(x)    x</span>
00030 <span class="preprocessor"></span>
00031 <span class="preprocessor">#define vmefail()               (exit(1), NULL)</span>
00032 <span class="preprocessor"></span><span class="preprocessor">#define urlPath(_xr, _r)        *(_r) = (_xr)</span>
00033 <span class="preprocessor"></span>
00034 <span class="keyword">typedef</span> FILE * <a class="code" href="struct__FD__s.html">FD_t</a>;
00035 <span class="preprocessor">#define Fopen(_path, _fmode)    fopen(_path, "r");</span>
00036 <span class="preprocessor"></span><span class="preprocessor">#define Ferror                  ferror</span>
00037 <span class="preprocessor"></span><span class="preprocessor">#define Fstrerror(_fd)          strerror(errno)</span>
00038 <span class="preprocessor"></span><span class="preprocessor">#define Fread                   fread</span>
00039 <span class="preprocessor"></span><span class="preprocessor">#define Fclose                  fclose</span>
00040 <span class="preprocessor"></span>
00041 <span class="preprocessor">#define fdGetFILE(_fd)          (_fd)</span>
00042 <span class="preprocessor"></span>
00043 <span class="preprocessor">#else</span>
00044 <span class="preprocessor"></span>
00045 <span class="preprocessor">#include &lt;<a class="code" href="rpmio__internal_8h.html">rpmio_internal.h</a>&gt;</span>
00046 <span class="preprocessor">#include &lt;<a class="code" href="rpmmessages_8h.html">rpmmessages.h</a>&gt;</span>
00047 <span class="preprocessor">#include &lt;<a class="code" href="rpmerr_8h.html">rpmerr.h</a>&gt;</span>
00048 
00049 <span class="preprocessor">#endif</span>
00050 <span class="preprocessor"></span>
00051 <span class="preprocessor">#include &lt;<a class="code" href="rpmmacro_8h.html">rpmmacro.h</a>&gt;</span>
00052 
00053 <span class="preprocessor">#include "<a class="code" href="debug_8h.html">debug.h</a>"</span>
00054 
00055 <span class="comment">/*@access FD_t@*/</span>               <span class="comment">/* XXX compared with NULL */</span>
00056 <span class="comment">/*@access MacroContext@*/</span>
00057 <span class="comment">/*@access MacroEntry@*/</span>
00058 
<a name="l00059"></a><a class="code" href="macro_8c.html#a12">00059</a> <span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="structMacroContext__s.html">MacroContext_s</a> rpmGlobalMacroContext_s;
00060 <span class="comment">/*@-compmempass@*/</span>
<a name="l00061"></a><a class="code" href="macro_8c.html#a13">00061</a> <a class="code" href="structMacroContext__s.html">MacroContext</a> <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a> = &amp;rpmGlobalMacroContext_s;
00062 <span class="comment">/*@=compmempass@*/</span>
00063 
<a name="l00064"></a><a class="code" href="macro_8c.html#a14">00064</a> <span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="structMacroContext__s.html">MacroContext_s</a> rpmCLIMacroContext_s;
00065 <span class="comment">/*@-compmempass@*/</span>
<a name="l00066"></a><a class="code" href="macro_8c.html#a15">00066</a> <a class="code" href="structMacroContext__s.html">MacroContext</a> <a class="code" href="macro_8c.html#a15">rpmCLIMacroContext</a> = &amp;rpmCLIMacroContext_s;
00067 <span class="comment">/*@=compmempass@*/</span>
00068 
<a name="l00072"></a><a class="code" href="structMacroBuf__s.html">00072</a> <span class="keyword">typedef</span> <span class="comment">/*@abstract@*/</span> <span class="keyword">struct </span><a class="code" href="structMacroBuf__s.html">MacroBuf_s</a> {
<a name="l00073"></a><a class="code" href="structMacroBuf__s.html#m0">00073</a> <span class="comment">/*@shared@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * <a class="code" href="structMacroBuf__s.html#m0">s</a>;    
<a name="l00074"></a><a class="code" href="structMacroBuf__s.html#m1">00074</a> <span class="comment">/*@shared@*/</span> <span class="keywordtype">char</span> * <a class="code" href="structMacroBuf__s.html#m1">t</a>;          
<a name="l00075"></a><a class="code" href="structMacroBuf__s.html#m2">00075</a>     size_t <a class="code" href="structMacroBuf__s.html#m2">nb</a>;                  
<a name="l00076"></a><a class="code" href="structMacroBuf__s.html#m3">00076</a>     <span class="keywordtype">int</span> <a class="code" href="structMacroBuf__s.html#m3">depth</a>;                  
<a name="l00077"></a><a class="code" href="structMacroBuf__s.html#m4">00077</a>     <span class="keywordtype">int</span> <a class="code" href="structMacroBuf__s.html#m4">macro_trace</a>;            
<a name="l00078"></a><a class="code" href="structMacroBuf__s.html#m5">00078</a>     <span class="keywordtype">int</span> <a class="code" href="structMacroBuf__s.html#m5">expand_trace</a>;           
<a name="l00079"></a><a class="code" href="structMacroBuf__s.html#m6">00079</a> <span class="comment">/*@shared@*/</span> <span class="comment">/*@null@*/</span> <span class="keywordtype">void</span> * <a class="code" href="structMacroBuf__s.html#m6">spec</a>;    
<a name="l00080"></a><a class="code" href="structMacroBuf__s.html#m7">00080</a> <span class="comment">/*@dependent@*/</span> <a class="code" href="structMacroContext__s.html">MacroContext</a> <a class="code" href="structMacroBuf__s.html#m7">mc</a>;
00081 } * <a class="code" href="structMacroBuf__s.html">MacroBuf</a>;
00082 
<a name="l00083"></a><a class="code" href="macro_8c.html#a3">00083</a> <span class="preprocessor">#define SAVECHAR(_mb, _c) { *(_mb)-&gt;t = (_c), (_mb)-&gt;t++, (_mb)-&gt;nb--; }</span>
00084 <span class="preprocessor"></span>
00085 <span class="comment">/*@-exportlocal -exportheadervar@*/</span>
00086 
<a name="l00087"></a><a class="code" href="macro_8c.html#a4">00087</a> <span class="preprocessor">#define MAX_MACRO_DEPTH 16</span>
00088 <span class="preprocessor"></span><span class="comment">/*@unchecked@*/</span>
<a name="l00089"></a><a class="code" href="macro_8c.html#a17">00089</a> <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a17">max_macro_depth</a> = <a class="code" href="macro_8c.html#a4">MAX_MACRO_DEPTH</a>;
00090 
00091 <span class="preprocessor">#ifdef  DEBUG_MACROS</span>
00092 <span class="preprocessor"></span><span class="comment">/*@unchecked@*/</span>
00093 <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a18">print_macro_trace</a> = 0;
00094 <span class="comment">/*@unchecked@*/</span>
00095 <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a19">print_expand_trace</a> = 0;
00096 <span class="preprocessor">#else</span>
00097 <span class="preprocessor"></span><span class="comment">/*@unchecked@*/</span>
<a name="l00098"></a><a class="code" href="macro_8c.html#a18">00098</a> <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a18">print_macro_trace</a> = 0;
00099 <span class="comment">/*@unchecked@*/</span>
<a name="l00100"></a><a class="code" href="macro_8c.html#a19">00100</a> <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a19">print_expand_trace</a> = 0;
00101 <span class="preprocessor">#endif</span>
00102 <span class="preprocessor"></span><span class="comment">/*@=exportlocal =exportheadervar@*/</span>
00103 
<a name="l00104"></a><a class="code" href="macro_8c.html#a5">00104</a> <span class="preprocessor">#define MACRO_CHUNK_SIZE        16</span>
00105 <span class="preprocessor"></span>
00106 <span class="comment">/* forward ref */</span>
00107 <span class="keyword">static</span> <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a20">expandMacro</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb)
00108         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
00109 <span class="comment">                print_macro_trace, print_expand_trace,</span>
00110 <span class="comment">                fileSystem @*/</span>
00111         <span class="comment">/*@modifies mb, rpmGlobalMacroContext,</span>
00112 <span class="comment">                print_macro_trace, print_expand_trace,</span>
00113 <span class="comment">                fileSystem @*/</span>;
00114 
00120 <span class="comment">/*@unused@*/</span> <span class="keyword">static</span> <span class="keyword">inline</span> <span class="comment">/*@null@*/</span> <span class="keywordtype">void</span> *
<a name="l00121"></a><a class="code" href="macro_8c.html#a21">00121</a> <a class="code" href="poptint_8h.html#a14">_free</a>(<span class="comment">/*@only@*/</span> <span class="comment">/*@null@*/</span> <span class="keyword">const</span> <span class="keywordtype">void</span> * p)
00122         <span class="comment">/*@modifies p@*/</span>
00123 {
00124     <span class="keywordflow">if</span> (p != NULL)      free((<span class="keywordtype">void</span> *)p);
00125     <span class="keywordflow">return</span> NULL;
00126 }
00127 
00128 <span class="comment">/* =============================================================== */</span>
00129 
00136 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00137"></a><a class="code" href="macro_8c.html#a22">00137</a> <a class="code" href="macro_8c.html#a22">compareMacroName</a>(<span class="keyword">const</span> <span class="keywordtype">void</span> * ap, <span class="keyword">const</span> <span class="keywordtype">void</span> * bp)
00138         <span class="comment">/*@*/</span>
00139 {
00140     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> ame = *((<a class="code" href="structMacroEntry__s.html">MacroEntry</a> *)ap);
00141     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> bme = *((<a class="code" href="structMacroEntry__s.html">MacroEntry</a> *)bp);
00142 
00143     <span class="keywordflow">if</span> (ame == NULL &amp;&amp; bme == NULL)
00144         <span class="keywordflow">return</span> 0;
00145     <span class="keywordflow">if</span> (ame == NULL)
00146         <span class="keywordflow">return</span> 1;
00147     <span class="keywordflow">if</span> (bme == NULL)
00148         <span class="keywordflow">return</span> -1;
00149     <span class="keywordflow">return</span> strcmp(ame-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>, bme-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>);
00150 }
00151 
00156 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00157"></a><a class="code" href="macro_8c.html#a23">00157</a> <a class="code" href="macro_8c.html#a23">expandMacroTable</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc)
00158         <span class="comment">/*@modifies mc @*/</span>
00159 {
00160     <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> == NULL) {
00161         mc-&gt;<a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a> = <a class="code" href="macro_8c.html#a5">MACRO_CHUNK_SIZE</a>;
00162         mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> = (<a class="code" href="structMacroEntry__s.html">MacroEntry</a> *)
00163             <a class="code" href="rpmmalloc_8c.html#a1">xmalloc</a>(<span class="keyword">sizeof</span>(*(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>)) * mc-&gt;<a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a>);
00164         mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a> = 0;
00165     } <span class="keywordflow">else</span> {
00166         mc-&gt;<a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a> += <a class="code" href="macro_8c.html#a5">MACRO_CHUNK_SIZE</a>;
00167         mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> = (<a class="code" href="structMacroEntry__s.html">MacroEntry</a> *)
00168             <a class="code" href="rpmmalloc_8c.html#a3">xrealloc</a>(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>, <span class="keyword">sizeof</span>(*(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>)) *
00169                         mc-&gt;<a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a>);
00170     }
00171     memset(&amp;mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>[mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>], 0, <a class="code" href="macro_8c.html#a5">MACRO_CHUNK_SIZE</a> * <span class="keyword">sizeof</span>(*(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>)));
00172 }
00173 
00178 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00179"></a><a class="code" href="macro_8c.html#a24">00179</a> <a class="code" href="macro_8c.html#a24">sortMacroTable</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc)
00180         <span class="comment">/*@modifies mc @*/</span>
00181 {
00182     <span class="keywordtype">int</span> i;
00183 
00184     <span class="keywordflow">if</span> (mc == NULL || mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> == NULL)
00185         <span class="keywordflow">return</span>;
00186 
00187     qsort(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>, mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>, <span class="keyword">sizeof</span>(*(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>)),
00188                 <a class="code" href="macro_8c.html#a22">compareMacroName</a>);
00189 
00190     <span class="comment">/* Empty pointers are now at end of table. Reset first free index. */</span>
00191     <span class="keywordflow">for</span> (i = 0; i &lt; mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>; i++) {
00192         <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i] != NULL)
00193             <span class="keywordflow">continue</span>;
00194         mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a> = i;
00195         <span class="keywordflow">break</span>;
00196     }
00197 }
00198 
00199 <span class="keywordtype">void</span>
<a name="l00200"></a><a class="code" href="macro_8c.html#a25">00200</a> <a class="code" href="macro_8c.html#a25">rpmDumpMacroTable</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc, FILE * fp)
00201 {
00202     <span class="keywordtype">int</span> nempty = 0;
00203     <span class="keywordtype">int</span> nactive = 0;
00204 
00205     <span class="keywordflow">if</span> (mc == NULL) mc = <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>;
00206     <span class="keywordflow">if</span> (fp == NULL) fp = stderr;
00207     
00208     fprintf(fp, <span class="stringliteral">"========================\n"</span>);
00209     <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> != NULL) {
00210         <span class="keywordtype">int</span> i;
00211         <span class="keywordflow">for</span> (i = 0; i &lt; mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>; i++) {
00212             <a class="code" href="structMacroEntry__s.html">MacroEntry</a> me;
00213             <span class="keywordflow">if</span> ((me = mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i]) == NULL) {
00214                 <span class="comment">/* XXX this should never happen */</span>
00215                 nempty++;
00216                 <span class="keywordflow">continue</span>;
00217             }
00218             fprintf(fp, <span class="stringliteral">"%3d%c %s"</span>, me-&gt;<a class="code" href="structMacroEntry__s.html#m5">level</a>,
00219                         (me-&gt;<a class="code" href="structMacroEntry__s.html#m4">used</a> &gt; 0 ? <span class="charliteral">'='</span> : <span class="charliteral">':'</span>), me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>);
00220             <span class="keywordflow">if</span> (me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a> &amp;&amp; *me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a>)
00221                     fprintf(fp, <span class="stringliteral">"(%s)"</span>, me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a>);
00222             <span class="keywordflow">if</span> (me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a> &amp;&amp; *me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>)
00223                     fprintf(fp, <span class="stringliteral">"\t%s"</span>, me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>);
00224             fprintf(fp, <span class="stringliteral">"\n"</span>);
00225             nactive++;
00226         }
00227     }
00228     fprintf(fp, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"======================== active %d empty %d\n"</span>),
00229                 nactive, nempty);
00230 }
00231 
00239 <span class="comment">/*@-mustmod@*/</span> <span class="comment">/* LCL: segfault with modifies nothing annotation */</span>
00240 <span class="comment">/*@dependent@*/</span> <span class="comment">/*@null@*/</span> <span class="keyword">static</span> <a class="code" href="structMacroEntry__s.html">MacroEntry</a> *
<a name="l00241"></a><a class="code" href="macro_8c.html#a26">00241</a> <a class="code" href="macro_8c.html#a26">findEntry</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc, <span class="keyword">const</span> <span class="keywordtype">char</span> * name, size_t namelen)
00242         <span class="comment">/*@globals rpmGlobalMacroContext @*/</span>
00243         <span class="comment">/*@modifies rpmGlobalMacroContext @*/</span>
00244 {
00245     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> key, *ret;
00246     <span class="keyword">struct </span><a class="code" href="structMacroEntry__s.html">MacroEntry_s</a> keybuf;
00247     <span class="keywordtype">char</span> namebuf[1024];
00248 
00249     <span class="keywordflow">if</span> (mc == NULL) mc = <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>;
00250     <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> == NULL || mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a> == 0)
00251         <span class="keywordflow">return</span> NULL;
00252 
00253     <span class="keywordflow">if</span> (namelen &gt; 0) {
00254         strncpy(namebuf, name, namelen);
00255         namebuf[namelen] = <span class="charliteral">'\0'</span>;
00256         name = namebuf;
00257     }
00258     
00259     key = &amp;keybuf;
00260     memset(key, 0, <span class="keyword">sizeof</span>(*key));
00261     <span class="comment">/*@-temptrans -assignexpose@*/</span>
00262     key-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a> = (<span class="keywordtype">char</span> *)name;
00263     <span class="comment">/*@=temptrans =assignexpose@*/</span>
00264     ret = (<a class="code" href="structMacroEntry__s.html">MacroEntry</a> *) bsearch(&amp;key, mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>, mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>,
00265                         <span class="keyword">sizeof</span>(*(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>)), <a class="code" href="macro_8c.html#a22">compareMacroName</a>);
00266     <span class="comment">/* XXX TODO: find 1st empty slot and return that */</span>
00267     <span class="keywordflow">return</span> ret;
00268 }
00269 <span class="comment">/*@=mustmod@*/</span>
00270 
00271 <span class="comment">/* =============================================================== */</span>
00272 
00276 <span class="comment">/*@dependent@*/</span> <span class="keyword">static</span> <span class="keywordtype">char</span> *
<a name="l00277"></a><a class="code" href="macro_8c.html#a27">00277</a> <a class="code" href="macro_8c.html#a27">rdcl</a>(<span class="keywordtype">char</span> * buf, size_t size, <a class="code" href="struct__FD__s.html">FD_t</a> fd, <span class="keywordtype">int</span> escapes)
00278         <span class="comment">/*@globals fileSystem @*/</span>
00279         <span class="comment">/*@modifies buf, fileSystem @*/</span>
00280 {
00281     <span class="keywordtype">char</span> *q = buf;
00282     size_t nb = 0;
00283     size_t nread = 0;
00284     FILE * f = <a class="code" href="rpmio_8c.html#a9">fdGetFILE</a>(fd);
00285 
00286     *q = <span class="charliteral">'\0'</span>;
00287     <span class="keywordflow">if</span> (f != NULL)
00288     <span class="keywordflow">do</span> {
00289         <span class="comment">/* read next line */</span>
00290         <span class="keywordflow">if</span> (fgets(q, size, f) == NULL)
00291             <span class="keywordflow">break</span>;
00292         nb = strlen(q);
00293         nread += nb;
00294         <span class="keywordflow">for</span> (q += nb - 1; nb &gt; 0 &amp;&amp; <a class="code" href="macro_8c.html#a1">iseol</a>(*q); q--)
00295             nb--;
00296         <span class="keywordflow">if</span> (!(nb &gt; 0 &amp;&amp; *q == <span class="charliteral">'\\'</span>)) {  <span class="comment">/* continue? */</span>
00297             *(++q) = <span class="charliteral">'\0'</span>;              <span class="comment">/* trim trailing \r, \n */</span>
00298             <span class="keywordflow">break</span>;
00299         }
00300         <span class="keywordflow">if</span> (escapes) {                  <span class="comment">/* copy escape too */</span>
00301             q++;
00302             nb++;
00303         }
00304         size -= nb;
00305         <span class="keywordflow">if</span> (*q == <span class="charliteral">'\r'</span>)                 <span class="comment">/* XXX avoid \r madness */</span>
00306             *q = <span class="charliteral">'\n'</span>;
00307         *(++q) = <span class="charliteral">'\0'</span>;                  <span class="comment">/* next char in buf */</span>
00308     } <span class="keywordflow">while</span> (size &gt; 0);
00309     <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> (nread &gt; 0 ? buf : NULL); <span class="comment">/*@=retalias@*/</span>
00310 }
00311 
00319 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *
<a name="l00320"></a><a class="code" href="macro_8c.html#a28">00320</a> <a class="code" href="macro_8c.html#a28">matchchar</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * p, <span class="keywordtype">char</span> pl, <span class="keywordtype">char</span> pr)
00321         <span class="comment">/*@*/</span>
00322 {
00323     <span class="keywordtype">int</span> lvl = 0;
00324     <span class="keywordtype">char</span> c;
00325 
00326     <span class="keywordflow">while</span> ((c = *p++) != <span class="charliteral">'\0'</span>) {
00327         <span class="keywordflow">if</span> (c == <span class="charliteral">'\\'</span>) {                <span class="comment">/* Ignore escaped chars */</span>
00328             p++;
00329             <span class="keywordflow">continue</span>;
00330         }
00331         <span class="keywordflow">if</span> (c == pr) {
00332             <span class="keywordflow">if</span> (--lvl &lt;= 0)     <span class="keywordflow">return</span> --p;
00333         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (c == pl)
00334             lvl++;
00335     }
00336     <span class="keywordflow">return</span> (<span class="keyword">const</span> <span class="keywordtype">char</span> *)NULL;
00337 }
00338 
00345 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00346"></a><a class="code" href="macro_8c.html#a29">00346</a> <a class="code" href="macro_8c.html#a29">printMacro</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keyword">const</span> <span class="keywordtype">char</span> * s, <span class="keyword">const</span> <span class="keywordtype">char</span> * se)
00347         <span class="comment">/*@globals fileSystem @*/</span>
00348         <span class="comment">/*@modifies fileSystem @*/</span>
00349 {
00350     <span class="keyword">const</span> <span class="keywordtype">char</span> *senl;
00351     <span class="keyword">const</span> <span class="keywordtype">char</span> *ellipsis;
00352     <span class="keywordtype">int</span> choplen;
00353 
00354     <span class="keywordflow">if</span> (s &gt;= se) {      <span class="comment">/* XXX just in case */</span>
00355         fprintf(stderr, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"%3d&gt;%*s(empty)"</span>), mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>,
00356                 (2 * mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> + 1), <span class="stringliteral">""</span>);
00357         <span class="keywordflow">return</span>;
00358     }
00359 
00360     <span class="keywordflow">if</span> (s[-1] == <span class="charliteral">'{'</span>)
00361         s--;
00362 
00363     <span class="comment">/* Print only to first end-of-line (or end-of-string). */</span>
00364     <span class="keywordflow">for</span> (senl = se; *senl &amp;&amp; !<a class="code" href="macro_8c.html#a1">iseol</a>(*senl); senl++)
00365         {};
00366 
00367     <span class="comment">/* Limit trailing non-trace output */</span>
00368     choplen = 61 - (2 * mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00369     <span class="keywordflow">if</span> ((senl - s) &gt; choplen) {
00370         senl = s + choplen;
00371         ellipsis = <span class="stringliteral">"..."</span>;
00372     } <span class="keywordflow">else</span>
00373         ellipsis = <span class="stringliteral">""</span>;
00374 
00375     <span class="comment">/* Substitute caret at end-of-macro position */</span>
00376     fprintf(stderr, <span class="stringliteral">"%3d&gt;%*s%%%.*s^"</span>, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>,
00377         (2 * mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> + 1), <span class="stringliteral">""</span>, (<span class="keywordtype">int</span>)(se - s), s);
00378     <span class="keywordflow">if</span> (se[1] != <span class="charliteral">'\0'</span> &amp;&amp; (senl - (se+1)) &gt; 0)
00379         fprintf(stderr, <span class="stringliteral">"%-.*s%s"</span>, (<span class="keywordtype">int</span>)(senl - (se+1)), se+1, ellipsis);
00380     fprintf(stderr, <span class="stringliteral">"\n"</span>);
00381 }
00382 
00389 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00390"></a><a class="code" href="macro_8c.html#a30">00390</a> <a class="code" href="macro_8c.html#a30">printExpansion</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keyword">const</span> <span class="keywordtype">char</span> * t, <span class="keyword">const</span> <span class="keywordtype">char</span> * te)
00391         <span class="comment">/*@globals fileSystem @*/</span>
00392         <span class="comment">/*@modifies fileSystem @*/</span>
00393 {
00394     <span class="keyword">const</span> <span class="keywordtype">char</span> *ellipsis;
00395     <span class="keywordtype">int</span> choplen;
00396 
00397     <span class="keywordflow">if</span> (!(te &gt; t)) {
00398         fprintf(stderr, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"%3d&lt;%*s(empty)\n"</span>), mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>, (2 * mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> + 1), <span class="stringliteral">""</span>);
00399         <span class="keywordflow">return</span>;
00400     }
00401 
00402     <span class="comment">/* Shorten output which contains newlines */</span>
00403     <span class="keywordflow">while</span> (te &gt; t &amp;&amp; <a class="code" href="macro_8c.html#a1">iseol</a>(te[-1]))
00404         te--;
00405     ellipsis = <span class="stringliteral">""</span>;
00406     <span class="keywordflow">if</span> (mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> &gt; 0) {
00407         <span class="keyword">const</span> <span class="keywordtype">char</span> *tenl;
00408 
00409         <span class="comment">/* Skip to last line of expansion */</span>
00410         <span class="keywordflow">while</span> ((tenl = strchr(t, <span class="charliteral">'\n'</span>)) &amp;&amp; tenl &lt; te)
00411             t = ++tenl;
00412 
00413         <span class="comment">/* Limit expand output */</span>
00414         choplen = 61 - (2 * mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00415         <span class="keywordflow">if</span> ((te - t) &gt; choplen) {
00416             te = t + choplen;
00417             ellipsis = <span class="stringliteral">"..."</span>;
00418         }
00419     }
00420 
00421     fprintf(stderr, <span class="stringliteral">"%3d&lt;%*s"</span>, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>, (2 * mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> + 1), <span class="stringliteral">""</span>);
00422     <span class="keywordflow">if</span> (te &gt; t)
00423         fprintf(stderr, <span class="stringliteral">"%.*s%s"</span>, (<span class="keywordtype">int</span>)(te - t), t, ellipsis);
00424     fprintf(stderr, <span class="stringliteral">"\n"</span>);
00425 }
00426 
<a name="l00427"></a><a class="code" href="macro_8c.html#a6">00427</a> <span class="preprocessor">#define SKIPBLANK(_s, _c)       \</span>
00428 <span class="preprocessor">        while (((_c) = *(_s)) &amp;&amp; isblank(_c)) \</span>
00429 <span class="preprocessor">                (_s)++;</span>
00430 <span class="preprocessor"></span>
<a name="l00431"></a><a class="code" href="macro_8c.html#a7">00431</a> <span class="preprocessor">#define SKIPNONBLANK(_s, _c)    \</span>
00432 <span class="preprocessor">        while (((_c) = *(_s)) &amp;&amp; !(isblank(_c) || iseol(_c))) \</span>
00433 <span class="preprocessor">                (_s)++;</span>
00434 <span class="preprocessor"></span>
<a name="l00435"></a><a class="code" href="macro_8c.html#a8">00435</a> <span class="preprocessor">#define COPYNAME(_ne, _s, _c)   \</span>
00436 <span class="preprocessor">    {   SKIPBLANK(_s,_c);       \</span>
00437 <span class="preprocessor">        while(((_c) = *(_s)) &amp;&amp; (xisalnum(_c) || (_c) == '_')) \</span>
00438 <span class="preprocessor">                *(_ne)++ = *(_s)++; \</span>
00439 <span class="preprocessor">        *(_ne) = '\0';          \</span>
00440 <span class="preprocessor">    }</span>
00441 <span class="preprocessor"></span>
<a name="l00442"></a><a class="code" href="macro_8c.html#a9">00442</a> <span class="preprocessor">#define COPYOPTS(_oe, _s, _c)   \</span>
00443 <span class="preprocessor">    {   while(((_c) = *(_s)) &amp;&amp; (_c) != ')') \</span>
00444 <span class="preprocessor">                *(_oe)++ = *(_s)++; \</span>
00445 <span class="preprocessor">        *(_oe) = '\0';          \</span>
00446 <span class="preprocessor">    }</span>
00447 <span class="preprocessor"></span>
<a name="l00448"></a><a class="code" href="macro_8c.html#a10">00448</a> <span class="preprocessor">#define COPYBODY(_be, _s, _c)   \</span>
00449 <span class="preprocessor">    {   while(((_c) = *(_s)) &amp;&amp; !iseol(_c)) { \</span>
00450 <span class="preprocessor">                if ((_c) == '\\') \</span>
00451 <span class="preprocessor">                        (_s)++; \</span>
00452 <span class="preprocessor">                *(_be)++ = *(_s)++; \</span>
00453 <span class="preprocessor">        }                       \</span>
00454 <span class="preprocessor">        *(_be) = '\0';          \</span>
00455 <span class="preprocessor">    }</span>
00456 <span class="preprocessor"></span>
00464 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00465"></a><a class="code" href="macro_8c.html#a31">00465</a> <a class="code" href="macro_8c.html#a31">expandT</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keyword">const</span> <span class="keywordtype">char</span> * f, size_t flen)
00466         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
00467 <span class="comment">                fileSystem@*/</span>
00468         <span class="comment">/*@modifies mb, rpmGlobalMacroContext, fileSystem @*/</span>
00469 {
00470     <span class="keywordtype">char</span> *sbuf;
00471     <span class="keyword">const</span> <span class="keywordtype">char</span> *s = mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a>;
00472     <span class="keywordtype">int</span> rc;
00473 
00474     sbuf = <a class="code" href="system_8h.html#a36">alloca</a>(flen + 1);
00475     memset(sbuf, 0, (flen + 1));
00476 
00477     strncpy(sbuf, f, flen);
00478     sbuf[flen] = <span class="charliteral">'\0'</span>;
00479     mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a> = sbuf;
00480     rc = <a class="code" href="macro_8c.html#a20">expandMacro</a>(mb);
00481     mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a> = s;
00482     <span class="keywordflow">return</span> rc;
00483 }
00484 
00485 <span class="preprocessor">#if 0</span>
00486 <span class="preprocessor"></span>
00493 <span class="keyword">static</span> <span class="keywordtype">int</span>
00494 expandS(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keywordtype">char</span> * tbuf, size_t tbuflen)
00495         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
00496 <span class="comment">                fileSystem@*/</span>
00497         <span class="comment">/*@modifies mb, *tbuf, rpmGlobalMacroContext, fileSystem @*/</span>
00498 {
00499     <span class="keyword">const</span> <span class="keywordtype">char</span> *t = mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a>;
00500     size_t nb = mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a>;
00501     <span class="keywordtype">int</span> rc;
00502 
00503     mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a> = tbuf;
00504     mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> = tbuflen;
00505     rc = <a class="code" href="macro_8c.html#a20">expandMacro</a>(mb);
00506     mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a> = t;
00507     mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> = nb;
00508     <span class="keywordflow">return</span> rc;
00509 }
00510 <span class="preprocessor">#endif</span>
00511 <span class="preprocessor"></span>
00519 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00520"></a><a class="code" href="macro_8c.html#a32">00520</a> <a class="code" href="macro_8c.html#a32">expandU</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keywordtype">char</span> * u, size_t ulen)
00521         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
00522 <span class="comment">                fileSystem@*/</span>
00523         <span class="comment">/*@modifies mb, *u, rpmGlobalMacroContext, fileSystem @*/</span>
00524 {
00525     <span class="keyword">const</span> <span class="keywordtype">char</span> *s = mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a>;
00526     <span class="keywordtype">char</span> *t = mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a>;
00527     size_t nb = mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a>;
00528     <span class="keywordtype">char</span> *tbuf;
00529     <span class="keywordtype">int</span> rc;
00530 
00531     tbuf = <a class="code" href="system_8h.html#a36">alloca</a>(ulen + 1);
00532     memset(tbuf, 0, (ulen + 1));
00533 
00534     <span class="comment">/*@-temptrans -assignexpose@*/</span>
00535     mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a> = u;
00536     <span class="comment">/*@=temptrans =assignexpose@*/</span>
00537     mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a> = tbuf;
00538     mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> = ulen;
00539     rc = <a class="code" href="macro_8c.html#a20">expandMacro</a>(mb);
00540 
00541     tbuf[ulen] = <span class="charliteral">'\0'</span>;  <span class="comment">/* XXX just in case */</span>
00542     <span class="keywordflow">if</span> (ulen &gt; mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a>)
00543         strncpy(u, tbuf, (ulen - mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> + 1));
00544 
00545     mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a> = s;
00546     mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a> = t;
00547     mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> = nb;
00548 
00549     <span class="keywordflow">return</span> rc;
00550 }
00551 
00559 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00560"></a><a class="code" href="macro_8c.html#a33">00560</a> <a class="code" href="macro_8c.html#a33">doShellEscape</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keyword">const</span> <span class="keywordtype">char</span> * cmd, size_t clen)
00561         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
00562 <span class="comment">                fileSystem @*/</span>
00563         <span class="comment">/*@modifies mb, rpmGlobalMacroContext,</span>
00564 <span class="comment">                fileSystem @*/</span>
00565 {
00566     <span class="keywordtype">char</span> pcmd[BUFSIZ];
00567     FILE *shf;
00568     <span class="keywordtype">int</span> rc;
00569     <span class="keywordtype">int</span> c;
00570 
00571     strncpy(pcmd, cmd, clen);
00572     pcmd[clen] = <span class="charliteral">'\0'</span>;
00573     rc = <a class="code" href="macro_8c.html#a32">expandU</a>(mb, pcmd, <span class="keyword">sizeof</span>(pcmd));
00574     <span class="keywordflow">if</span> (rc)
00575         <span class="keywordflow">return</span> rc;
00576 
00577     <span class="keywordflow">if</span> ((shf = popen(pcmd, <span class="stringliteral">"r"</span>)) == NULL)
00578         <span class="keywordflow">return</span> 1;
00579     <span class="keywordflow">while</span>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> &gt; 0 &amp;&amp; (c = fgetc(shf)) != EOF)
00580         <a class="code" href="macro_8c.html#a3">SAVECHAR</a>(mb, c);
00581     (void) pclose(shf);
00582 
00583     <span class="comment">/* XXX delete trailing \r \n */</span>
00584     <span class="keywordflow">while</span> (<a class="code" href="macro_8c.html#a1">iseol</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a>[-1])) {
00585         *(mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a>--) = <span class="charliteral">'\0'</span>;
00586         mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a>++;
00587     }
00588     <span class="keywordflow">return</span> 0;
00589 }
00590 
00599 <span class="comment">/*@dependent@*/</span> <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *
<a name="l00600"></a><a class="code" href="macro_8c.html#a34">00600</a> <a class="code" href="macro_8c.html#a34">doDefine</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keyword">const</span> <span class="keywordtype">char</span> * se, <span class="keywordtype">int</span> level, <span class="keywordtype">int</span> expandbody)
00601         <span class="comment">/*@globals rpmGlobalMacroContext @*/</span>
00602         <span class="comment">/*@modifies mb, rpmGlobalMacroContext @*/</span>
00603 {
00604     <span class="keyword">const</span> <span class="keywordtype">char</span> *s = se;
00605     <span class="keywordtype">char</span> buf[BUFSIZ], *n = buf, *ne = n;
00606     <span class="keywordtype">char</span> *o = NULL, *oe;
00607     <span class="keywordtype">char</span> *b, *be;
00608     <span class="keywordtype">int</span> c;
00609     <span class="keywordtype">int</span> oc = <span class="charliteral">')'</span>;
00610 
00611     <span class="comment">/* Copy name */</span>
00612 <span class="comment">/*@-globs@*/</span>
00613     <a class="code" href="macro_8c.html#a8">COPYNAME</a>(ne, s, c);
00614 <span class="comment">/*@=globs@*/</span>
00615 
00616     <span class="comment">/* Copy opts (if present) */</span>
00617     oe = ne + 1;
00618     <span class="keywordflow">if</span> (*s == <span class="charliteral">'('</span>) {
00619         s++;    <span class="comment">/* skip ( */</span>
00620         o = oe;
00621         <a class="code" href="macro_8c.html#a9">COPYOPTS</a>(oe, s, oc);
00622         s++;    <span class="comment">/* skip ) */</span>
00623     }
00624 
00625     <span class="comment">/* Copy body, skipping over escaped newlines */</span>
00626     b = be = oe + 1;
00627 <span class="comment">/*@-globs@*/</span>
00628     <a class="code" href="macro_8c.html#a6">SKIPBLANK</a>(s, c);
00629 <span class="comment">/*@=globs@*/</span>
00630     <span class="keywordflow">if</span> (c == <span class="charliteral">'{'</span>) {     <span class="comment">/* XXX permit silent {...} grouping */</span>
00631         <span class="keywordflow">if</span> ((se = <a class="code" href="macro_8c.html#a28">matchchar</a>(s, c, <span class="charliteral">'}'</span>)) == NULL) {
00632             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
00633                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%s has unterminated body\n"</span>), n);
00634             se = s;     <span class="comment">/* XXX W2DO? */</span>
00635             <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00636         }
00637         s++;    <span class="comment">/* XXX skip { */</span>
00638         strncpy(b, s, (se - s));
00639         b[se - s] = <span class="charliteral">'\0'</span>;
00640         be += strlen(b);
00641         se++;   <span class="comment">/* XXX skip } */</span>
00642         s = se; <span class="comment">/* move scan forward */</span>
00643     } <span class="keywordflow">else</span> {    <span class="comment">/* otherwise free-field */</span>
00644         <a class="code" href="macro_8c.html#a10">COPYBODY</a>(be, s, c);
00645 
00646         <span class="comment">/* Trim trailing blanks/newlines */</span>
00647 <span class="comment">/*@-globs@*/</span>
00648         <span class="keywordflow">while</span> (--be &gt;= b &amp;&amp; (c = *be) &amp;&amp; (<a class="code" href="macro_8c.html#a0">isblank</a>(c) || <a class="code" href="macro_8c.html#a1">iseol</a>(c)))
00649             {};
00650 <span class="comment">/*@=globs@*/</span>
00651         *(++be) = <span class="charliteral">'\0'</span>; <span class="comment">/* one too far */</span>
00652     }
00653 
00654     <span class="comment">/* Move scan over body */</span>
00655     <span class="keywordflow">while</span> (<a class="code" href="macro_8c.html#a1">iseol</a>(*s))
00656         s++;
00657     se = s;
00658 
00659     <span class="comment">/* Names must start with alphabetic or _ and be at least 3 chars */</span>
00660     <span class="keywordflow">if</span> (!((c = *n) &amp;&amp; (<a class="code" href="rpmio_8h.html#a98">xisalpha</a>(c) || c == <span class="charliteral">'_'</span>) &amp;&amp; (ne - n) &gt; 2)) {
00661         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
00662                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%s has illegal name (%%define)\n"</span>), n);
00663         <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00664     }
00665 
00666     <span class="comment">/* Options must be terminated with ')' */</span>
00667     <span class="keywordflow">if</span> (o &amp;&amp; oc != <span class="charliteral">')'</span>) {
00668         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%s has unterminated opts\n"</span>), n);
00669         <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00670     }
00671 
00672     <span class="keywordflow">if</span> ((be - b) &lt; 1) {
00673         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%s has empty body\n"</span>), n);
00674         <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00675     }
00676 
00677 <span class="comment">/*@-modfilesys@*/</span>
00678     <span class="keywordflow">if</span> (expandbody &amp;&amp; <a class="code" href="macro_8c.html#a32">expandU</a>(mb, b, (&amp;buf[<span class="keyword">sizeof</span>(buf)] - b))) {
00679         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%s failed to expand\n"</span>), n);
00680         <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00681     }
00682 <span class="comment">/*@=modfilesys@*/</span>
00683 
00684     <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, n, o, b, (level - 1));
00685 
00686     <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00687 }
00688 
00695 <span class="comment">/*@dependent@*/</span> <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *
<a name="l00696"></a><a class="code" href="macro_8c.html#a35">00696</a> <a class="code" href="macro_8c.html#a35">doUndefine</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc, <span class="keyword">const</span> <span class="keywordtype">char</span> * se)
00697         <span class="comment">/*@globals rpmGlobalMacroContext @*/</span>
00698         <span class="comment">/*@modifies mc, rpmGlobalMacroContext @*/</span>
00699 {
00700     <span class="keyword">const</span> <span class="keywordtype">char</span> *s = se;
00701     <span class="keywordtype">char</span> buf[BUFSIZ], *n = buf, *ne = n;
00702     <span class="keywordtype">int</span> c;
00703 
00704 <span class="comment">/*@-globs@*/</span>
00705     <a class="code" href="macro_8c.html#a8">COPYNAME</a>(ne, s, c);
00706 <span class="comment">/*@=globs@*/</span>
00707 
00708     <span class="comment">/* Move scan over body */</span>
00709     <span class="keywordflow">while</span> (<a class="code" href="macro_8c.html#a1">iseol</a>(*s))
00710         s++;
00711     se = s;
00712 
00713     <span class="comment">/* Names must start with alphabetic or _ and be at least 3 chars */</span>
00714     <span class="keywordflow">if</span> (!((c = *n) &amp;&amp; (<a class="code" href="rpmio_8h.html#a98">xisalpha</a>(c) || c == <span class="charliteral">'_'</span>) &amp;&amp; (ne - n) &gt; 2)) {
00715         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
00716                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%s has illegal name (%%undefine)\n"</span>), n);
00717         <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00718     }
00719 
00720     <a class="code" href="macro_8c.html#a44">delMacro</a>(mc, n);
00721 
00722     <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00723 }
00724 
00725 <span class="preprocessor">#ifdef  DYING</span>
00726 <span class="preprocessor"></span><span class="keyword">static</span> <span class="keywordtype">void</span>
00727 dumpME(<span class="keyword">const</span> <span class="keywordtype">char</span> * msg, <a class="code" href="structMacroEntry__s.html">MacroEntry</a> me)
00728         <span class="comment">/*@globals fileSystem @*/</span>
00729         <span class="comment">/*@modifies fileSystem @*/</span>
00730 {
00731     <span class="keywordflow">if</span> (msg)
00732         fprintf(stderr, <span class="stringliteral">"%s"</span>, msg);
00733     fprintf(stderr, <span class="stringliteral">"\tme %p"</span>, me);
00734     <span class="keywordflow">if</span> (me)
00735         fprintf(stderr,<span class="stringliteral">"\tname %p(%s) prev %p"</span>,
00736                 me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>, me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>, me-&gt;<a class="code" href="structMacroEntry__s.html#m0">prev</a>);
00737     fprintf(stderr, <span class="stringliteral">"\n"</span>);
00738 }
00739 <span class="preprocessor">#endif</span>
00740 <span class="preprocessor"></span>
00749 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00750"></a><a class="code" href="macro_8c.html#a36">00750</a> <a class="code" href="macro_8c.html#a36">pushMacro</a>(<span class="comment">/*@out@*/</span> <a class="code" href="structMacroEntry__s.html">MacroEntry</a> * mep,
00751                 <span class="keyword">const</span> <span class="keywordtype">char</span> * n, <span class="comment">/*@null@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * o,
00752                 <span class="comment">/*@null@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * b, <span class="keywordtype">int</span> level)
00753         <span class="comment">/*@modifies *mep @*/</span>
00754 {
00755     <span class="comment">/*@-usedef@*/</span>
00756     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> prev = (mep &amp;&amp; *mep ? *mep : NULL);
00757     <span class="comment">/*@=usedef@*/</span>
00758     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> me = (MacroEntry) <a class="code" href="rpmmalloc_8c.html#a1">xmalloc</a>(<span class="keyword">sizeof</span>(*me));
00759 
00760     <span class="comment">/*@-assignexpose@*/</span>
00761     me-&gt;<a class="code" href="structMacroEntry__s.html#m0">prev</a> = prev;
00762     <span class="comment">/*@=assignexpose@*/</span>
00763     me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a> = (prev ? prev-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a> : <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(n));
00764     me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a> = (o ? <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(o) : NULL);
00765     me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a> = <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(b ? b : <span class="stringliteral">""</span>);
00766     me-&gt;<a class="code" href="structMacroEntry__s.html#m4">used</a> = 0;
00767     me-&gt;<a class="code" href="structMacroEntry__s.html#m5">level</a> = level;
00768     <span class="keywordflow">if</span> (mep)
00769         *mep = me;
00770     <span class="keywordflow">else</span>
00771         me = <a class="code" href="poptint_8h.html#a14">_free</a>(me);
00772 }
00773 
00778 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00779"></a><a class="code" href="macro_8c.html#a37">00779</a> <a class="code" href="macro_8c.html#a37">popMacro</a>(<a class="code" href="structMacroEntry__s.html">MacroEntry</a> * mep)
00780         <span class="comment">/*@modifies *mep @*/</span>
00781 {
00782         <a class="code" href="structMacroEntry__s.html">MacroEntry</a> me = (*mep ? *mep : NULL);
00783 
00784         <span class="keywordflow">if</span> (me) {
00785                 <span class="comment">/* XXX cast to workaround const */</span>
00786                 <span class="comment">/*@-onlytrans@*/</span>
00787                 <span class="keywordflow">if</span> ((*mep = me-&gt;<a class="code" href="structMacroEntry__s.html#m0">prev</a>) == NULL)
00788                         me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>);
00789                 me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a>);
00790                 me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>);
00791                 me = <a class="code" href="poptint_8h.html#a14">_free</a>(me);
00792                 <span class="comment">/*@=onlytrans@*/</span>
00793         }
00794 }
00795 
00800 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00801"></a><a class="code" href="macro_8c.html#a38">00801</a> <a class="code" href="macro_8c.html#a38">freeArgs</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb)
00802         <span class="comment">/*@modifies mb @*/</span>
00803 {
00804     <a class="code" href="structMacroContext__s.html">MacroContext</a> mc = mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>;
00805     <span class="keywordtype">int</span> ndeleted = 0;
00806     <span class="keywordtype">int</span> i;
00807 
00808     <span class="keywordflow">if</span> (mc == NULL || mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> == NULL)
00809         <span class="keywordflow">return</span>;
00810 
00811     <span class="comment">/* Delete dynamic macro definitions */</span>
00812     <span class="keywordflow">for</span> (i = 0; i &lt; mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>; i++) {
00813         <a class="code" href="structMacroEntry__s.html">MacroEntry</a> *mep, me;
00814         <span class="keywordtype">int</span> skiptest = 0;
00815         mep = &amp;mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i];
00816         me = *mep;
00817 
00818         <span class="keywordflow">if</span> (me == NULL)         <span class="comment">/* XXX this should never happen */</span>
00819             <span class="keywordflow">continue</span>;
00820         <span class="keywordflow">if</span> (me-&gt;<a class="code" href="structMacroEntry__s.html#m5">level</a> &lt; mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>)
00821             <span class="keywordflow">continue</span>;
00822         <span class="keywordflow">if</span> (strlen(me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>) == 1 &amp;&amp; strchr(<span class="stringliteral">"#*0"</span>, *me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>)) {
00823             <span class="keywordflow">if</span> (*me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a> == <span class="charliteral">'*'</span> &amp;&amp; me-&gt;<a class="code" href="structMacroEntry__s.html#m4">used</a> &gt; 0)
00824                 skiptest = 1; <span class="comment">/* XXX skip test for %# %* %0 */</span>
00825         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!skiptest &amp;&amp; me-&gt;<a class="code" href="structMacroEntry__s.html#m4">used</a> &lt;= 0) {
00826 <span class="preprocessor">#if NOTYET</span>
00827 <span class="preprocessor"></span>            <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
00828                         <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%s (%s) was not used below level %d\n"</span>),
00829                         me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>, me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>, me-&gt;<a class="code" href="structMacroEntry__s.html#m5">level</a>);
00830 <span class="preprocessor">#endif</span>
00831 <span class="preprocessor"></span>        }
00832         <a class="code" href="macro_8c.html#a37">popMacro</a>(mep);
00833         <span class="keywordflow">if</span> (!(mep &amp;&amp; *mep))
00834             ndeleted++;
00835     }
00836 
00837     <span class="comment">/* If any deleted macros, sort macro table */</span>
00838     <span class="keywordflow">if</span> (ndeleted)
00839         <a class="code" href="macro_8c.html#a24">sortMacroTable</a>(mc);
00840 }
00841 
00851 <span class="comment">/*@dependent@*/</span> <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *
<a name="l00852"></a><a class="code" href="macro_8c.html#a39">00852</a> <a class="code" href="macro_8c.html#a39">grabArgs</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keyword">const</span> <a class="code" href="structMacroEntry__s.html">MacroEntry</a> me, <span class="keyword">const</span> <span class="keywordtype">char</span> * se, <span class="keywordtype">char</span> lastc)
00853         <span class="comment">/*@globals rpmGlobalMacroContext @*/</span>
00854         <span class="comment">/*@modifies mb, rpmGlobalMacroContext @*/</span>
00855 {
00856     <span class="keywordtype">char</span> buf[BUFSIZ], *b, *be;
00857     <span class="keywordtype">char</span> aname[16];
00858     <span class="keyword">const</span> <span class="keywordtype">char</span> *opts, *o;
00859     <span class="keywordtype">int</span> argc = 0;
00860     <span class="keyword">const</span> <span class="keywordtype">char</span> **argv;
00861     <span class="keywordtype">int</span> c;
00862 
00863     <span class="comment">/* Copy macro name as argv[0], save beginning of args.  */</span>
00864     buf[0] = <span class="charliteral">'\0'</span>;
00865     b = be = <a class="code" href="system_8h.html#a32">stpcpy</a>(buf, me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>);
00866 
00867     <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"0"</span>, NULL, buf, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00868     
00869     argc = 1;   <span class="comment">/* XXX count argv[0] */</span>
00870 
00871     <span class="comment">/* Copy args into buf until lastc */</span>
00872     *be++ = <span class="charliteral">' '</span>;
00873     <span class="keywordflow">while</span> ((c = *se++) != <span class="charliteral">'\0'</span> &amp;&amp; c != lastc) {
00874 <span class="comment">/*@-globs@*/</span>
00875         <span class="keywordflow">if</span> (!<a class="code" href="macro_8c.html#a0">isblank</a>(c)) {
00876             *be++ = c;
00877             <span class="keywordflow">continue</span>;
00878         }
00879 <span class="comment">/*@=globs@*/</span>
00880         <span class="comment">/* c is blank */</span>
00881         <span class="keywordflow">if</span> (be[-1] == <span class="charliteral">' '</span>)
00882             <span class="keywordflow">continue</span>;
00883         <span class="comment">/* a word has ended */</span>
00884         *be++ = <span class="charliteral">' '</span>;
00885         argc++;
00886     }
00887     <span class="keywordflow">if</span> (c == <span class="charliteral">'\0'</span>) se--;        <span class="comment">/* one too far */</span>
00888     <span class="keywordflow">if</span> (be[-1] != <span class="charliteral">' '</span>)
00889         argc++, be++;           <span class="comment">/* last word has not trailing ' ' */</span>
00890     be[-1] = <span class="charliteral">'\0'</span>;
00891     <span class="keywordflow">if</span> (*b == <span class="charliteral">' '</span>) b++;         <span class="comment">/* skip the leading ' ' */</span>
00892 
00893 <span class="comment">/*</span>
00894 <span class="comment"> * The macro %* analoguous to the shell's $* means "Pass all non-macro</span>
00895 <span class="comment"> * parameters." Consequently, there needs to be a macro that means "Pass all</span>
00896 <span class="comment"> * (including macro parameters) options". This is useful for verifying</span>
00897 <span class="comment"> * parameters during expansion and yet transparently passing all parameters</span>
00898 <span class="comment"> * through for higher level processing (e.g. %description and/or %setup).</span>
00899 <span class="comment"> * This is the (potential) justification for %{**} ...</span>
00900 <span class="comment"> */</span>
00901     <span class="comment">/* Add unexpanded args as macro */</span>
00902     <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"**"</span>, NULL, b, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00903 
00904 <span class="preprocessor">#ifdef NOTYET</span>
00905 <span class="preprocessor"></span>    <span class="comment">/* XXX if macros can be passed as args ... */</span>
00906     <a class="code" href="macro_8c.html#a32">expandU</a>(mb, buf, <span class="keyword">sizeof</span>(buf));
00907 <span class="preprocessor">#endif</span>
00908 <span class="preprocessor"></span>
00909     <span class="comment">/* Build argv array */</span>
00910     argv = (<span class="keyword">const</span> <span class="keywordtype">char</span> **) <a class="code" href="system_8h.html#a36">alloca</a>((argc + 1) * <span class="keyword">sizeof</span>(*argv));
00911     be[-1] = <span class="charliteral">' '</span>; <span class="comment">/* assert((be - 1) == (b + strlen(b) == buf + strlen(buf))) */</span>
00912     be[0] = <span class="charliteral">'\0'</span>;
00913     b = buf;
00914     <span class="keywordflow">for</span> (c = 0; c &lt; argc; c++) {
00915         argv[c] = b;
00916         b = strchr(b, <span class="charliteral">' '</span>);
00917         *b++ = <span class="charliteral">'\0'</span>;
00918     }
00919     <span class="comment">/* assert(b == be);  */</span>
00920     argv[argc] = NULL;
00921 
00922     <span class="comment">/* Citation from glibc/posix/getopt.c:</span>
00923 <span class="comment">     *    Index in ARGV of the next element to be scanned.</span>
00924 <span class="comment">     *    This is used for communication to and from the caller</span>
00925 <span class="comment">     *    and for communication between successive calls to `getopt'.</span>
00926 <span class="comment">     *</span>
00927 <span class="comment">     *    On entry to `getopt', zero means this is the first call; initialize.</span>
00928 <span class="comment">     *</span>
00929 <span class="comment">     *    When `getopt' returns -1, this is the index of the first of the</span>
00930 <span class="comment">     *    non-option elements that the caller should itself scan.</span>
00931 <span class="comment">     *</span>
00932 <span class="comment">     *    Otherwise, `optind' communicates from one call to the next</span>
00933 <span class="comment">     *    how much of ARGV has been scanned so far.</span>
00934 <span class="comment">     */</span>
00935     <span class="comment">/* 1003.2 says this must be 1 before any call.  */</span>
00936 
00937 <span class="preprocessor">#ifdef __GLIBC__</span>
00938 <span class="preprocessor"></span>    <span class="comment">/*@-mods@*/</span>
00939     optind = 1;
00940     <span class="comment">/*@=mods@*/</span>
00941 <span class="preprocessor">#endif</span>
00942 <span class="preprocessor"></span>
00943     opts = me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a>;
00944 
00945     <span class="comment">/* Define option macros. */</span>
00946     <span class="keywordflow">while</span>((c = getopt(argc, (<span class="keywordtype">char</span> **)argv, opts)) != -1) {
00947         <span class="keywordflow">if</span> (c == <span class="charliteral">'?'</span> || (o = strchr(opts, c)) == NULL) {
00948             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Unknown option %c in %s(%s)\n"</span>),
00949                         (<span class="keywordtype">char</span>)c, me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>, opts);
00950             <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00951         }
00952         *be++ = <span class="charliteral">'-'</span>;
00953         *be++ = c;
00954         <span class="comment">/*@-usedef@*/</span>
00955         <span class="keywordflow">if</span> (o[1] == <span class="charliteral">':'</span>) {
00956         <span class="comment">/*@=usedef@*/</span>
00957             *be++ = <span class="charliteral">' '</span>;
00958             be = <a class="code" href="system_8h.html#a32">stpcpy</a>(be, optarg);
00959         }
00960         *be++ = <span class="charliteral">'\0'</span>;
00961         aname[0] = <span class="charliteral">'-'</span>; aname[1] = c; aname[2] = <span class="charliteral">'\0'</span>;
00962         <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, aname, NULL, b, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00963         <span class="keywordflow">if</span> (o[1] == <span class="charliteral">':'</span>) {
00964             aname[0] = <span class="charliteral">'-'</span>; aname[1] = c; aname[2] = <span class="charliteral">'*'</span>; aname[3] = <span class="charliteral">'\0'</span>;
00965             <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, aname, NULL, optarg, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00966         }
00967         be = b; <span class="comment">/* reuse the space */</span>
00968     }
00969 
00970     <span class="comment">/* Add arg count as macro. */</span>
00971     sprintf(aname, <span class="stringliteral">"%d"</span>, (argc - optind));
00972     <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"#"</span>, NULL, aname, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00973 
00974     <span class="comment">/* Add macro for each arg. Concatenate args for %*. */</span>
00975     <span class="keywordflow">if</span> (be) {
00976         *be = <span class="charliteral">'\0'</span>;
00977         <span class="keywordflow">for</span> (c = optind; c &lt; argc; c++) {
00978             sprintf(aname, <span class="stringliteral">"%d"</span>, (c - optind + 1));
00979             <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, aname, NULL, argv[c], mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00980             *be++ = <span class="charliteral">' '</span>;
00981             be = <a class="code" href="system_8h.html#a32">stpcpy</a>(be, argv[c]);
00982         }
00983     }
00984 
00985     <span class="comment">/* Add unexpanded args as macro. */</span>
00986     <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"*"</span>, NULL, b, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
00987 
00988     <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> se; <span class="comment">/*@=retalias@*/</span>
00989 }
00990 
00998 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00999"></a><a class="code" href="macro_8c.html#a40">00999</a> <a class="code" href="macro_8c.html#a40">doOutput</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keywordtype">int</span> waserror, <span class="keyword">const</span> <span class="keywordtype">char</span> * msg, size_t msglen)
01000         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
01001 <span class="comment">                fileSystem @*/</span>
01002         <span class="comment">/*@modifies mb, rpmGlobalMacroContext,</span>
01003 <span class="comment">                fileSystem @*/</span>
01004 {
01005     <span class="keywordtype">char</span> buf[BUFSIZ];
01006 
01007     strncpy(buf, msg, msglen);
01008     buf[msglen] = <span class="charliteral">'\0'</span>;
01009     (void) <a class="code" href="macro_8c.html#a32">expandU</a>(mb, buf, <span class="keyword">sizeof</span>(buf));
01010     <span class="keywordflow">if</span> (waserror)
01011         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <span class="stringliteral">"%s\n"</span>, buf);
01012     <span class="keywordflow">else</span>
01013         fprintf(stderr, <span class="stringliteral">"%s"</span>, buf);
01014 }
01015 
01025 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l01026"></a><a class="code" href="macro_8c.html#a41">01026</a> <a class="code" href="macro_8c.html#a41">doFoo</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb, <span class="keywordtype">int</span> negate, <span class="keyword">const</span> <span class="keywordtype">char</span> * f, size_t fn,
01027                 <span class="keyword">const</span> <span class="keywordtype">char</span> * g, size_t gn)
01028         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
01029 <span class="comment">                fileSystem, internalState @*/</span>
01030         <span class="comment">/*@modifies mb, rpmGlobalMacroContext,</span>
01031 <span class="comment">                fileSystem, internalState @*/</span>
01032 {
01033     <span class="keywordtype">char</span> buf[BUFSIZ], *b = NULL, *be;
01034     <span class="keywordtype">int</span> c;
01035 
01036     buf[0] = <span class="charliteral">'\0'</span>;
01037     <span class="keywordflow">if</span> (g) {
01038         strncpy(buf, g, gn);
01039         buf[gn] = <span class="charliteral">'\0'</span>;
01040         (void) <a class="code" href="macro_8c.html#a32">expandU</a>(mb, buf, <span class="keyword">sizeof</span>(buf));
01041     }
01042     <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"basename"</span>, f, fn)) {
01043         <span class="keywordflow">if</span> ((b = strrchr(buf, <span class="charliteral">'/'</span>)) == NULL)
01044             b = buf;
01045 <span class="preprocessor">#if NOTYET</span>
01046 <span class="preprocessor"></span>    <span class="comment">/* XXX watchout for conflict with %dir */</span>
01047     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"dirname"</span>, f, fn)) {
01048         <span class="keywordflow">if</span> ((b = strrchr(buf, <span class="charliteral">'/'</span>)) != NULL)
01049             *b = <span class="charliteral">'\0'</span>;
01050         b = buf;
01051 <span class="preprocessor">#endif</span>
01052 <span class="preprocessor"></span>    } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"suffix"</span>, f, fn)) {
01053         <span class="keywordflow">if</span> ((b = strrchr(buf, <span class="charliteral">'.'</span>)) != NULL)
01054             b++;
01055     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"expand"</span>, f, fn)) {
01056         b = buf;
01057     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"verbose"</span>, f, fn)) {
01058         <span class="keywordflow">if</span> (negate)
01059             b = (<a class="code" href="rpmmessages_8h.html#a12">rpmIsVerbose</a>() ? NULL : buf);
01060         <span class="keywordflow">else</span>
01061             b = (<a class="code" href="rpmmessages_8h.html#a12">rpmIsVerbose</a>() ? buf : NULL);
01062     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"url2path"</span>, f, fn) || <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"u2p"</span>, f, fn)) {
01063         (void)<a class="code" href="url_8c.html#a18">urlPath</a>(buf, (<span class="keyword">const</span> <span class="keywordtype">char</span> **)&amp;b);
01064         <span class="keywordflow">if</span> (*b == <span class="charliteral">'\0'</span>) b = <span class="stringliteral">"/"</span>;
01065     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"uncompress"</span>, f, fn)) {
01066         <a class="code" href="rpmmacro_8h.html#a13">rpmCompressedMagic</a> compressed = <a class="code" href="rpmmacro_8h.html#a32a15">COMPRESSED_OTHER</a>;
01067 <span class="comment">/*@-globs@*/</span>
01068         <span class="keywordflow">for</span> (b = buf; (c = *b) &amp;&amp; <a class="code" href="macro_8c.html#a0">isblank</a>(c);)
01069             b++;
01070         <span class="keywordflow">for</span> (be = b; (c = *be) &amp;&amp; !<a class="code" href="macro_8c.html#a0">isblank</a>(c);)
01071             be++;
01072 <span class="comment">/*@=globs@*/</span>
01073         *be++ = <span class="charliteral">'\0'</span>;
01074 <span class="preprocessor">#ifndef DEBUG_MACROS</span>
01075 <span class="preprocessor"></span>        (void) <a class="code" href="macro_8c.html#a49">isCompressed</a>(b, &amp;compressed);
01076 <span class="preprocessor">#endif</span>
01077 <span class="preprocessor"></span>        <span class="keywordflow">switch</span>(compressed) {
01078         <span class="keywordflow">default</span>:
01079         <span class="keywordflow">case</span> 0: <span class="comment">/* COMPRESSED_NOT */</span>
01080             sprintf(be, <span class="stringliteral">"%%_cat %s"</span>, b);
01081             <span class="keywordflow">break</span>;
01082         <span class="keywordflow">case</span> 1: <span class="comment">/* COMPRESSED_OTHER */</span>
01083             sprintf(be, <span class="stringliteral">"%%_gzip -dc %s"</span>, b);
01084             <span class="keywordflow">break</span>;
01085         <span class="keywordflow">case</span> 2: <span class="comment">/* COMPRESSED_BZIP2 */</span>
01086             sprintf(be, <span class="stringliteral">"%%_bzip2 %s"</span>, b);
01087             <span class="keywordflow">break</span>;
01088         <span class="keywordflow">case</span> 3: <span class="comment">/* COMPRESSED_ZIP */</span>
01089             sprintf(be, <span class="stringliteral">"%%_unzip %s"</span>, b);
01090             <span class="keywordflow">break</span>;
01091         }
01092         b = be;
01093     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"S"</span>, f, fn)) {
01094         <span class="keywordflow">for</span> (b = buf; (c = *b) &amp;&amp; <a class="code" href="rpmio_8h.html#a99">xisdigit</a>(c);)
01095             b++;
01096         <span class="keywordflow">if</span> (!c) {       <span class="comment">/* digit index */</span>
01097             b++;
01098             sprintf(b, <span class="stringliteral">"%%SOURCE%s"</span>, buf);
01099         } <span class="keywordflow">else</span>
01100             b = buf;
01101     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"P"</span>, f, fn)) {
01102         <span class="keywordflow">for</span> (b = buf; (c = *b) &amp;&amp; <a class="code" href="rpmio_8h.html#a99">xisdigit</a>(c);)
01103             b++;
01104         <span class="keywordflow">if</span> (!c) {       <span class="comment">/* digit index */</span>
01105             b++;
01106             sprintf(b, <span class="stringliteral">"%%PATCH%s"</span>, buf);
01107         } <span class="keywordflow">else</span>
01108                         b = buf;
01109     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"F"</span>, f, fn)) {
01110         b = buf + strlen(buf) + 1;
01111         sprintf(b, <span class="stringliteral">"file%s.file"</span>, buf);
01112     }
01113 
01114     <span class="keywordflow">if</span> (b) {
01115         (void) <a class="code" href="macro_8c.html#a31">expandT</a>(mb, b, strlen(b));
01116     }
01117 }
01118 
01125 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l01126"></a><a class="code" href="macro_8c.html#a20">01126</a> <a class="code" href="macro_8c.html#a20">expandMacro</a>(<a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb)
01127         <span class="comment">/*@globals rpmGlobalMacroContext,</span>
01128 <span class="comment">                print_macro_trace, print_expand_trace,</span>
01129 <span class="comment">                fileSystem @*/</span>
01130         <span class="comment">/*@modifies mb, rpmGlobalMacroContext,</span>
01131 <span class="comment">                print_macro_trace, print_expand_trace,</span>
01132 <span class="comment">                fileSystem @*/</span>
01133 {
01134     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> *mep;
01135     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> me;
01136     <span class="keyword">const</span> <span class="keywordtype">char</span> *s = mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a>, *se;
01137     <span class="keyword">const</span> <span class="keywordtype">char</span> *f, *fe;
01138     <span class="keyword">const</span> <span class="keywordtype">char</span> *g, *ge;
01139     size_t fn, gn;
01140     <span class="keywordtype">char</span> *t = mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a>;    <span class="comment">/* save expansion pointer for printExpand */</span>
01141     <span class="keywordtype">int</span> c;
01142     <span class="keywordtype">int</span> rc = 0;
01143     <span class="keywordtype">int</span> negate;
01144     <span class="keywordtype">char</span> grab;
01145     <span class="keywordtype">int</span> chkexist;
01146 
01147     <span class="keywordflow">if</span> (++mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> &gt; <a class="code" href="macro_8c.html#a17">max_macro_depth</a>) {
01148         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
01149                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Recursion depth(%d) greater than max(%d)\n"</span>),
01150                 mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>, <a class="code" href="macro_8c.html#a17">max_macro_depth</a>);
01151         mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>--;
01152         mb-&gt;<a class="code" href="structMacroBuf__s.html#m5">expand_trace</a> = 1;
01153         <span class="keywordflow">return</span> 1;
01154     }
01155 
01156     <span class="keywordflow">while</span> (rc == 0 &amp;&amp; mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> &gt; 0 &amp;&amp; (c = *s) != <span class="charliteral">'\0'</span>) {
01157         s++;
01158         <span class="comment">/* Copy text until next macro */</span>
01159         <span class="keywordflow">switch</span>(c) {
01160         <span class="keywordflow">case</span> <span class="charliteral">'%'</span>:
01161                 <span class="keywordflow">if</span> (*s != <span class="charliteral">'%'</span>)
01162                         <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01163                 s++;    <span class="comment">/* skip first % in %% */</span>
01164                 <span class="comment">/*@fallthrough@*/</span>
01165         <span class="keywordflow">default</span>:
01166                 <a class="code" href="macro_8c.html#a3">SAVECHAR</a>(mb, c);
01167                 <span class="keywordflow">continue</span>;
01168                 <span class="comment">/*@notreached@*/</span> <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01169         }
01170 
01171         <span class="comment">/* Expand next macro */</span>
01172         f = fe = NULL;
01173         g = ge = NULL;
01174         <span class="keywordflow">if</span> (mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> &gt; 1)      <span class="comment">/* XXX full expansion for outermost level */</span>
01175                 t = mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a>;      <span class="comment">/* save expansion pointer for printExpand */</span>
01176         negate = 0;
01177         grab = <span class="charliteral">'\0'</span>;
01178         chkexist = 0;
01179         <span class="keywordflow">switch</span> ((c = *s)) {
01180         <span class="keywordflow">default</span>:                <span class="comment">/* %name substitution */</span>
01181                 <span class="keywordflow">while</span> (strchr(<span class="stringliteral">"!?"</span>, *s) != NULL) {
01182                         <span class="keywordflow">switch</span>(*s++) {
01183                         <span class="keywordflow">case</span> <span class="charliteral">'!'</span>:
01184                                 negate = ((negate + 1) % 2);
01185                                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01186                         <span class="keywordflow">case</span> <span class="charliteral">'?'</span>:
01187                                 chkexist++;
01188                                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01189                         }
01190                 }
01191                 f = se = s;
01192                 <span class="keywordflow">if</span> (*se == <span class="charliteral">'-'</span>)
01193                         se++;
01194                 <span class="keywordflow">while</span>((c = *se) &amp;&amp; (<a class="code" href="rpmio_8h.html#a100">xisalnum</a>(c) || c == <span class="charliteral">'_'</span>))
01195                         se++;
01196                 <span class="comment">/* Recognize non-alnum macros too */</span>
01197                 <span class="keywordflow">switch</span> (*se) {
01198                 <span class="keywordflow">case</span> <span class="charliteral">'*'</span>:
01199                         se++;
01200                         <span class="keywordflow">if</span> (*se == <span class="charliteral">'*'</span>) se++;
01201                         <span class="comment">/*@innerbreak@*/</span> <span class="keywordflow">break</span>;
01202                 <span class="keywordflow">case</span> <span class="charliteral">'#'</span>:
01203                         se++;
01204                         <span class="comment">/*@innerbreak@*/</span> <span class="keywordflow">break</span>;
01205                 <span class="keywordflow">default</span>:
01206                         <span class="comment">/*@innerbreak@*/</span> <span class="keywordflow">break</span>;
01207                 }
01208                 fe = se;
01209                 <span class="comment">/* For "%name " macros ... */</span>
01210 <span class="comment">/*@-globs@*/</span>
01211                 <span class="keywordflow">if</span> ((c = *fe) &amp;&amp; <a class="code" href="macro_8c.html#a0">isblank</a>(c))
01212                         grab = <span class="charliteral">'\n'</span>;
01213 <span class="comment">/*@=globs@*/</span>
01214                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01215         <span class="keywordflow">case</span> <span class="charliteral">'('</span>:               <span class="comment">/* %(...) shell escape */</span>
01216                 <span class="keywordflow">if</span> ((se = <a class="code" href="macro_8c.html#a28">matchchar</a>(s, c, <span class="charliteral">')'</span>)) == NULL) {
01217                         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
01218                                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Unterminated %c: %s\n"</span>), (<span class="keywordtype">char</span>)c, s);
01219                         rc = 1;
01220                         <span class="keywordflow">continue</span>;
01221                 }
01222                 <span class="keywordflow">if</span> (mb-&gt;<a class="code" href="structMacroBuf__s.html#m4">macro_trace</a>)
01223                         <a class="code" href="macro_8c.html#a29">printMacro</a>(mb, s, se+1);
01224 
01225                 s++;    <span class="comment">/* skip ( */</span>
01226                 rc = <a class="code" href="macro_8c.html#a33">doShellEscape</a>(mb, s, (se - s));
01227                 se++;   <span class="comment">/* skip ) */</span>
01228 
01229                 s = se;
01230                 <span class="keywordflow">continue</span>;
01231                 <span class="comment">/*@notreached@*/</span> <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01232         <span class="keywordflow">case</span> <span class="charliteral">'{'</span>:               <span class="comment">/* %{...}/%{...:...} substitution */</span>
01233                 <span class="keywordflow">if</span> ((se = <a class="code" href="macro_8c.html#a28">matchchar</a>(s, c, <span class="charliteral">'}'</span>)) == NULL) {
01234                         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
01235                                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Unterminated %c: %s\n"</span>), (<span class="keywordtype">char</span>)c, s);
01236                         rc = 1;
01237                         <span class="keywordflow">continue</span>;
01238                 }
01239                 f = s+1;<span class="comment">/* skip { */</span>
01240                 se++;   <span class="comment">/* skip } */</span>
01241                 <span class="keywordflow">while</span> (strchr(<span class="stringliteral">"!?"</span>, *f) != NULL) {
01242                         <span class="keywordflow">switch</span>(*f++) {
01243                         <span class="keywordflow">case</span> <span class="charliteral">'!'</span>:
01244                                 negate = ((negate + 1) % 2);
01245                                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01246                         <span class="keywordflow">case</span> <span class="charliteral">'?'</span>:
01247                                 chkexist++;
01248                                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01249                         }
01250                 }
01251                 <span class="keywordflow">for</span> (fe = f; (c = *fe) &amp;&amp; !strchr(<span class="stringliteral">" :}"</span>, c);)
01252                         fe++;
01253                 <span class="keywordflow">switch</span> (c) {
01254                 <span class="keywordflow">case</span> <span class="charliteral">':'</span>:
01255                         g = fe + 1;
01256                         ge = se - 1;
01257                         <span class="comment">/*@innerbreak@*/</span> <span class="keywordflow">break</span>;
01258                 <span class="keywordflow">case</span> <span class="charliteral">' '</span>:
01259                         grab = se[-1];
01260                         <span class="comment">/*@innerbreak@*/</span> <span class="keywordflow">break</span>;
01261                 <span class="keywordflow">default</span>:
01262                         <span class="comment">/*@innerbreak@*/</span> <span class="keywordflow">break</span>;
01263                 }
01264                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01265         }
01266 
01267         <span class="comment">/* XXX Everything below expects fe &gt; f */</span>
01268         fn = (fe - f);
01269         gn = (ge - g);
01270         <span class="keywordflow">if</span> ((fe - f) &lt;= 0) {
01271 <span class="comment">/* XXX Process % in unknown context */</span>
01272                 c = <span class="charliteral">'%'</span>;        <span class="comment">/* XXX only need to save % */</span>
01273                 <a class="code" href="macro_8c.html#a3">SAVECHAR</a>(mb, c);
01274 <span class="preprocessor">#if 0</span>
01275 <span class="preprocessor"></span>                <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
01276                         <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"A %% is followed by an unparseable macro\n"</span>));
01277 <span class="preprocessor">#endif</span>
01278 <span class="preprocessor"></span>                s = se;
01279                 <span class="keywordflow">continue</span>;
01280         }
01281 
01282         <span class="keywordflow">if</span> (mb-&gt;<a class="code" href="structMacroBuf__s.html#m4">macro_trace</a>)
01283                 <a class="code" href="macro_8c.html#a29">printMacro</a>(mb, s, se);
01284 
01285         <span class="comment">/* Expand builtin macros */</span>
01286         <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"global"</span>, f, fn)) {
01287                 s = <a class="code" href="macro_8c.html#a34">doDefine</a>(mb, se, <a class="code" href="rpmmacro_8h.html#a7">RMIL_GLOBAL</a>, 1);
01288                 <span class="keywordflow">continue</span>;
01289         }
01290         <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"define"</span>, f, fn)) {
01291                 s = <a class="code" href="macro_8c.html#a34">doDefine</a>(mb, se, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>, 0);
01292                 <span class="keywordflow">continue</span>;
01293         }
01294         <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"undefine"</span>, f, fn)) {
01295                 s = <a class="code" href="macro_8c.html#a35">doUndefine</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, se);
01296                 <span class="keywordflow">continue</span>;
01297         }
01298 
01299         <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"echo"</span>, f, fn) ||
01300             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"warn"</span>, f, fn) ||
01301             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"error"</span>, f, fn)) {
01302                 <span class="keywordtype">int</span> waserror = 0;
01303                 <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"error"</span>, f, fn))
01304                         waserror = 1;
01305                 <span class="keywordflow">if</span> (g &lt; ge)
01306                         <a class="code" href="macro_8c.html#a40">doOutput</a>(mb, waserror, g, gn);
01307                 <span class="keywordflow">else</span>
01308                         <a class="code" href="macro_8c.html#a40">doOutput</a>(mb, waserror, f, fn);
01309                 s = se;
01310                 <span class="keywordflow">continue</span>;
01311         }
01312 
01313         <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"trace"</span>, f, fn)) {
01314                 <span class="comment">/* XXX TODO restore expand_trace/macro_trace to 0 on return */</span>
01315                 mb-&gt;<a class="code" href="structMacroBuf__s.html#m5">expand_trace</a> = mb-&gt;<a class="code" href="structMacroBuf__s.html#m4">macro_trace</a> = (negate ? 0 : mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
01316                 <span class="keywordflow">if</span> (mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> == 1) {
01317                         <a class="code" href="macro_8c.html#a18">print_macro_trace</a> = mb-&gt;<a class="code" href="structMacroBuf__s.html#m4">macro_trace</a>;
01318                         <a class="code" href="macro_8c.html#a19">print_expand_trace</a> = mb-&gt;<a class="code" href="structMacroBuf__s.html#m5">expand_trace</a>;
01319                 }
01320                 s = se;
01321                 <span class="keywordflow">continue</span>;
01322         }
01323 
01324         <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"dump"</span>, f, fn)) {
01325                 <a class="code" href="macro_8c.html#a25">rpmDumpMacroTable</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, NULL);
01326                 <span class="keywordflow">while</span> (<a class="code" href="macro_8c.html#a1">iseol</a>(*se))
01327                         se++;
01328                 s = se;
01329                 <span class="keywordflow">continue</span>;
01330         }
01331 
01332         <span class="comment">/* XXX necessary but clunky */</span>
01333         <span class="keywordflow">if</span> (<a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"basename"</span>, f, fn) ||
01334             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"suffix"</span>, f, fn) ||
01335             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"expand"</span>, f, fn) ||
01336             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"verbose"</span>, f, fn) ||
01337             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"uncompress"</span>, f, fn) ||
01338             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"url2path"</span>, f, fn) ||
01339             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"u2p"</span>, f, fn) ||
01340             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"S"</span>, f, fn) ||
01341             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"P"</span>, f, fn) ||
01342             <a class="code" href="macro_8c.html#a2">STREQ</a>(<span class="stringliteral">"F"</span>, f, fn)) {
01343                 <span class="comment">/*@-internalglobs@*/</span> <span class="comment">/* FIX: verbose may be set */</span>
01344                 <a class="code" href="macro_8c.html#a41">doFoo</a>(mb, negate, f, fn, g, gn);
01345                 <span class="comment">/*@=internalglobs@*/</span>
01346                 s = se;
01347                 <span class="keywordflow">continue</span>;
01348         }
01349 
01350         <span class="comment">/* Expand defined macros */</span>
01351         mep = <a class="code" href="macro_8c.html#a26">findEntry</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, f, fn);
01352         me = (mep ? *mep : NULL);
01353 
01354         <span class="comment">/* XXX Special processing for flags */</span>
01355         <span class="keywordflow">if</span> (*f == <span class="charliteral">'-'</span>) {
01356                 <span class="keywordflow">if</span> (me)
01357                         me-&gt;<a class="code" href="structMacroEntry__s.html#m4">used</a>++;     <span class="comment">/* Mark macro as used */</span>
01358                 <span class="keywordflow">if</span> ((me == NULL &amp;&amp; !negate) ||  <span class="comment">/* Without -f, skip %{-f...} */</span>
01359                     (me != NULL &amp;&amp; negate)) {   <span class="comment">/* With -f, skip %{!-f...} */</span>
01360                         s = se;
01361                         <span class="keywordflow">continue</span>;
01362                 }
01363 
01364                 <span class="keywordflow">if</span> (g &amp;&amp; g &lt; ge) {              <span class="comment">/* Expand X in %{-f:X} */</span>
01365                         rc = <a class="code" href="macro_8c.html#a31">expandT</a>(mb, g, gn);
01366                 } <span class="keywordflow">else</span>
01367                 <span class="keywordflow">if</span> (me &amp;&amp; me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a> &amp;&amp; *me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>) {<span class="comment">/* Expand %{-f}/%{-f*} */</span>
01368                         rc = <a class="code" href="macro_8c.html#a31">expandT</a>(mb, me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>, strlen(me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>));
01369                 }
01370                 s = se;
01371                 <span class="keywordflow">continue</span>;
01372         }
01373 
01374         <span class="comment">/* XXX Special processing for macro existence */</span>
01375         <span class="keywordflow">if</span> (chkexist) {
01376                 <span class="keywordflow">if</span> ((me == NULL &amp;&amp; !negate) ||  <span class="comment">/* Without -f, skip %{?f...} */</span>
01377                     (me != NULL &amp;&amp; negate)) {   <span class="comment">/* With -f, skip %{!?f...} */</span>
01378                         s = se;
01379                         <span class="keywordflow">continue</span>;
01380                 }
01381                 <span class="keywordflow">if</span> (g &amp;&amp; g &lt; ge) {              <span class="comment">/* Expand X in %{?f:X} */</span>
01382                         rc = <a class="code" href="macro_8c.html#a31">expandT</a>(mb, g, gn);
01383                 } <span class="keywordflow">else</span>
01384                 <span class="keywordflow">if</span> (me &amp;&amp; me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a> &amp;&amp; *me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>) { <span class="comment">/* Expand %{?f}/%{?f*} */</span>
01385                         rc = <a class="code" href="macro_8c.html#a31">expandT</a>(mb, me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>, strlen(me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>));
01386                 }
01387                 s = se;
01388                 <span class="keywordflow">continue</span>;
01389         }
01390         
01391         <span class="keywordflow">if</span> (me == NULL) {       <span class="comment">/* leave unknown %... as is */</span>
01392 <span class="preprocessor">#ifndef HACK</span>
01393 <span class="preprocessor"></span><span class="preprocessor">#if DEAD</span>
01394 <span class="preprocessor"></span>                <span class="comment">/* XXX hack to skip over empty arg list */</span>
01395                 <span class="keywordflow">if</span> (fn == 1 &amp;&amp; *f == <span class="charliteral">'*'</span>) {
01396                         s = se;
01397                         <span class="keywordflow">continue</span>;
01398                 }
01399 <span class="preprocessor">#endif</span>
01400 <span class="preprocessor"></span>                <span class="comment">/* XXX hack to permit non-overloaded %foo to be passed */</span>
01401                 c = <span class="charliteral">'%'</span>;        <span class="comment">/* XXX only need to save % */</span>
01402                 <a class="code" href="macro_8c.html#a3">SAVECHAR</a>(mb, c);
01403 <span class="preprocessor">#else</span>
01404 <span class="preprocessor"></span>                <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>,
01405                         <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Macro %%%.*s not found, skipping\n"</span>), fn, f);
01406                 s = se;
01407 <span class="preprocessor">#endif</span>
01408 <span class="preprocessor"></span>                <span class="keywordflow">continue</span>;
01409         }
01410 
01411         <span class="comment">/* Setup args for "%name " macros with opts */</span>
01412         <span class="keywordflow">if</span> (me &amp;&amp; me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a> != NULL) {
01413                 <span class="keywordflow">if</span> (grab != <span class="charliteral">'\0'</span>) {
01414                         se = <a class="code" href="macro_8c.html#a39">grabArgs</a>(mb, me, fe, grab);
01415                 } <span class="keywordflow">else</span> {
01416                         <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"**"</span>, NULL, <span class="stringliteral">""</span>, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
01417                         <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"*"</span>, NULL, <span class="stringliteral">""</span>, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
01418                         <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"#"</span>, NULL, <span class="stringliteral">"0"</span>, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
01419                         <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"0"</span>, NULL, me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>, mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>);
01420                 }
01421         }
01422 
01423         <span class="comment">/* Recursively expand body of macro */</span>
01424         <span class="keywordflow">if</span> (me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a> &amp;&amp; *me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>) {
01425                 <span class="comment">/*@-onlytrans@*/</span>
01426                 mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a> = me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>;
01427                 <span class="comment">/*@=onlytrans@*/</span>
01428                 rc = <a class="code" href="macro_8c.html#a20">expandMacro</a>(mb);
01429                 <span class="keywordflow">if</span> (rc == 0)
01430                         me-&gt;<a class="code" href="structMacroEntry__s.html#m4">used</a>++;     <span class="comment">/* Mark macro as used */</span>
01431         }
01432 
01433         <span class="comment">/* Free args for "%name " macros with opts */</span>
01434         <span class="keywordflow">if</span> (me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a> != NULL)
01435                 <a class="code" href="macro_8c.html#a38">freeArgs</a>(mb);
01436 
01437         s = se;
01438     }
01439 
01440     *mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a> = <span class="charliteral">'\0'</span>;
01441     mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a> = s;
01442     mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a>--;
01443     <span class="keywordflow">if</span> (rc != 0 || mb-&gt;<a class="code" href="structMacroBuf__s.html#m5">expand_trace</a>)
01444         <a class="code" href="macro_8c.html#a30">printExpansion</a>(mb, t, mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a>);
01445     <span class="keywordflow">return</span> rc;
01446 }
01447 
01448 <span class="comment">/* =============================================================== */</span>
01449 
01450 <span class="keywordtype">int</span>
<a name="l01451"></a><a class="code" href="macro_8c.html#a42">01451</a> <a class="code" href="macro_8c.html#a42">expandMacros</a>(<span class="keywordtype">void</span> * spec, <a class="code" href="structMacroContext__s.html">MacroContext</a> mc, <span class="keywordtype">char</span> * sbuf, size_t slen)
01452 {
01453     <a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb = <a class="code" href="system_8h.html#a36">alloca</a>(<span class="keyword">sizeof</span>(*mb));
01454     <span class="keywordtype">char</span> *tbuf;
01455     <span class="keywordtype">int</span> rc;
01456 
01457     <span class="keywordflow">if</span> (sbuf == NULL || slen == 0)
01458         <span class="keywordflow">return</span> 0;
01459     <span class="keywordflow">if</span> (mc == NULL) mc = <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>;
01460 
01461     tbuf = <a class="code" href="system_8h.html#a36">alloca</a>(slen + 1);
01462     memset(tbuf, 0, (slen + 1));
01463 
01464     <span class="comment">/*@-temptrans -assignexpose@*/</span>
01465     mb-&gt;<a class="code" href="structMacroBuf__s.html#m0">s</a> = sbuf;
01466     <span class="comment">/*@=temptrans =assignexpose@*/</span>
01467     mb-&gt;<a class="code" href="structMacroBuf__s.html#m1">t</a> = tbuf;
01468     mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> = slen;
01469     mb-&gt;<a class="code" href="structMacroBuf__s.html#m3">depth</a> = 0;
01470     mb-&gt;<a class="code" href="structMacroBuf__s.html#m4">macro_trace</a> = <a class="code" href="macro_8c.html#a18">print_macro_trace</a>;
01471     mb-&gt;<a class="code" href="structMacroBuf__s.html#m5">expand_trace</a> = <a class="code" href="macro_8c.html#a19">print_expand_trace</a>;
01472 
01473     <span class="comment">/*@-temptrans -assignexpose@*/</span>
01474     mb-&gt;<a class="code" href="structMacroBuf__s.html#m6">spec</a> = spec;    <span class="comment">/* (future) %file expansion info */</span>
01475     mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a> = mc;
01476     <span class="comment">/*@=temptrans =assignexpose@*/</span>
01477 
01478     rc = <a class="code" href="macro_8c.html#a20">expandMacro</a>(mb);
01479 
01480     <span class="keywordflow">if</span> (mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> == 0)
01481         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Target buffer overflow\n"</span>));
01482 
01483     tbuf[slen] = <span class="charliteral">'\0'</span>;  <span class="comment">/* XXX just in case */</span>
01484     strncpy(sbuf, tbuf, (slen - mb-&gt;<a class="code" href="structMacroBuf__s.html#m2">nb</a> + 1));
01485 
01486     <span class="keywordflow">return</span> rc;
01487 }
01488 
01489 <span class="keywordtype">void</span>
<a name="l01490"></a><a class="code" href="macro_8c.html#a43">01490</a> <a class="code" href="macro_8c.html#a43">addMacro</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc,
01491         <span class="keyword">const</span> <span class="keywordtype">char</span> * n, <span class="keyword">const</span> <span class="keywordtype">char</span> * o, <span class="keyword">const</span> <span class="keywordtype">char</span> * b, <span class="keywordtype">int</span> level)
01492 {
01493     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> * mep;
01494 
01495     <span class="keywordflow">if</span> (mc == NULL) mc = <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>;
01496 
01497     <span class="comment">/* If new name, expand macro table */</span>
01498     <span class="keywordflow">if</span> ((mep = <a class="code" href="macro_8c.html#a26">findEntry</a>(mc, n, 0)) == NULL) {
01499         <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a> == mc-&gt;<a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a>)
01500             <a class="code" href="macro_8c.html#a23">expandMacroTable</a>(mc);
01501         <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> != NULL)
01502             mep = mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> + mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>++;
01503     }
01504 
01505     <span class="keywordflow">if</span> (mep != NULL) {
01506         <span class="comment">/* Push macro over previous definition */</span>
01507         <a class="code" href="macro_8c.html#a36">pushMacro</a>(mep, n, o, b, level);
01508 
01509         <span class="comment">/* If new name, sort macro table */</span>
01510         <span class="keywordflow">if</span> ((*mep)-&gt;prev == NULL)
01511             <a class="code" href="macro_8c.html#a24">sortMacroTable</a>(mc);
01512     }
01513 }
01514 
01515 <span class="keywordtype">void</span>
<a name="l01516"></a><a class="code" href="macro_8c.html#a44">01516</a> <a class="code" href="macro_8c.html#a44">delMacro</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc, <span class="keyword">const</span> <span class="keywordtype">char</span> * n)
01517 {
01518     <a class="code" href="structMacroEntry__s.html">MacroEntry</a> * mep;
01519 
01520     <span class="keywordflow">if</span> (mc == NULL) mc = <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>;
01521     <span class="comment">/* If name exists, pop entry */</span>
01522     <span class="keywordflow">if</span> ((mep = <a class="code" href="macro_8c.html#a26">findEntry</a>(mc, n, 0)) != NULL) {
01523         <a class="code" href="macro_8c.html#a37">popMacro</a>(mep);
01524         <span class="comment">/* If deleted name, sort macro table */</span>
01525         <span class="keywordflow">if</span> (!(mep &amp;&amp; *mep))
01526             <a class="code" href="macro_8c.html#a24">sortMacroTable</a>(mc);
01527     }
01528 }
01529 
01530 <span class="comment">/*@-mustmod@*/</span> <span class="comment">/* LCL: mc is modified through mb-&gt;mc, mb is abstract */</span>
01531 <span class="keywordtype">int</span>
<a name="l01532"></a><a class="code" href="macro_8c.html#a45">01532</a> <a class="code" href="macro_8c.html#a45">rpmDefineMacro</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc, <span class="keyword">const</span> <span class="keywordtype">char</span> * macro, <span class="keywordtype">int</span> level)
01533 {
01534     <a class="code" href="structMacroBuf__s.html">MacroBuf</a> mb = <a class="code" href="system_8h.html#a36">alloca</a>(<span class="keyword">sizeof</span>(*mb));
01535 
01536     memset(mb, 0, <span class="keyword">sizeof</span>(*mb));
01537     <span class="comment">/* XXX just enough to get by */</span>
01538     <span class="comment">/*@-temptrans -assignexpose@*/</span>
01539     mb-&gt;<a class="code" href="structMacroBuf__s.html#m7">mc</a> = (mc ? mc : <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>);
01540     <span class="comment">/*@=temptrans =assignexpose@*/</span>
01541     (void) <a class="code" href="macro_8c.html#a34">doDefine</a>(mb, macro, level, 0);
01542     <span class="keywordflow">return</span> 0;
01543 }
01544 <span class="comment">/*@=mustmod@*/</span>
01545 
01546 <span class="keywordtype">void</span>
<a name="l01547"></a><a class="code" href="macro_8c.html#a46">01547</a> <a class="code" href="macro_8c.html#a46">rpmLoadMacros</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc, <span class="keywordtype">int</span> level)
01548 {
01549 
01550     <span class="keywordflow">if</span> (mc == NULL || mc == <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>)
01551         <span class="keywordflow">return</span>;
01552 
01553     <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> != NULL) {
01554         <span class="keywordtype">int</span> i;
01555         <span class="keywordflow">for</span> (i = 0; i &lt; mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>; i++) {
01556             <a class="code" href="structMacroEntry__s.html">MacroEntry</a> *mep, me;
01557             mep = &amp;mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i];
01558             me = *mep;
01559 
01560             <span class="keywordflow">if</span> (me == NULL)             <span class="comment">/* XXX this should never happen */</span>
01561                 <span class="keywordflow">continue</span>;
01562             <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>, me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a>, me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>, (level - 1));
01563         }
01564     }
01565 }
01566 
01567 <span class="keywordtype">void</span>
<a name="l01568"></a><a class="code" href="macro_8c.html#a47">01568</a> <a class="code" href="macro_8c.html#a47">rpmInitMacros</a>(<span class="comment">/*@unused@*/</span> <a class="code" href="structMacroContext__s.html">MacroContext</a> mc, <span class="keyword">const</span> <span class="keywordtype">char</span> *macrofiles)
01569 {
01570     <span class="keywordtype">char</span> *m, *mfile, *me;
01571 
01572     <span class="keywordflow">if</span> (macrofiles == NULL)
01573         <span class="keywordflow">return</span>;
01574 <span class="preprocessor">#ifdef  DYING</span>
01575 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (mc == NULL) mc = <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>;
01576 <span class="preprocessor">#endif</span>
01577 <span class="preprocessor"></span>
01578     <span class="keywordflow">for</span> (mfile = m = <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(macrofiles); mfile &amp;&amp; *mfile != <span class="charliteral">'\0'</span>; mfile = me) {
01579         <a class="code" href="struct__FD__s.html">FD_t</a> fd;
01580         <span class="keywordtype">char</span> buf[BUFSIZ];
01581 
01582         <span class="keywordflow">for</span> (me = mfile; (me = strchr(me, <span class="charliteral">':'</span>)) != NULL; me++) {
01583             <span class="keywordflow">if</span> (!(me[1] == <span class="charliteral">'/'</span> &amp;&amp; me[2] == <span class="charliteral">'/'</span>))
01584                 <span class="comment">/*@innerbreak@*/</span> <span class="keywordflow">break</span>;
01585         }
01586 
01587         <span class="keywordflow">if</span> (me &amp;&amp; *me == <span class="charliteral">':'</span>)
01588             *me++ = <span class="charliteral">'\0'</span>;
01589         <span class="keywordflow">else</span>
01590             me = mfile + strlen(mfile);
01591 
01592         <span class="comment">/* Expand ~/ to $HOME */</span>
01593         buf[0] = <span class="charliteral">'\0'</span>;
01594         <span class="keywordflow">if</span> (mfile[0] == <span class="charliteral">'~'</span> &amp;&amp; mfile[1] == <span class="charliteral">'/'</span>) {
01595             <span class="keywordtype">char</span> *home;
01596             <span class="keywordflow">if</span> ((home = <a class="code" href="system_8h.html#a34">getenv</a>(<span class="stringliteral">"HOME"</span>)) != NULL) {
01597                 mfile += 2;
01598                 strncpy(buf, home, <span class="keyword">sizeof</span>(buf));
01599                 strncat(buf, <span class="stringliteral">"/"</span>, <span class="keyword">sizeof</span>(buf) - strlen(buf));
01600             }
01601         }
01602         strncat(buf, mfile, <span class="keyword">sizeof</span>(buf) - strlen(buf));
01603         buf[<span class="keyword">sizeof</span>(buf)-1] = <span class="charliteral">'\0'</span>;
01604 
01605         fd = <a class="code" href="group__rpmio.html#a83">Fopen</a>(buf, <span class="stringliteral">"r.fpio"</span>);
01606         <span class="keywordflow">if</span> (fd == NULL || <a class="code" href="group__rpmio.html#a85">Ferror</a>(fd)) {
01607             <span class="keywordflow">if</span> (fd) (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(fd);
01608             <span class="keywordflow">continue</span>;
01609         }
01610 
01611         <span class="comment">/* XXX Assume new fangled macro expansion */</span>
01612         <span class="comment">/*@-mods@*/</span>
01613         <a class="code" href="macro_8c.html#a17">max_macro_depth</a> = 16;
01614         <span class="comment">/*@=mods@*/</span>
01615 
01616         <span class="keywordflow">while</span>(<a class="code" href="macro_8c.html#a27">rdcl</a>(buf, <span class="keyword">sizeof</span>(buf), fd, 1) != NULL) {
01617             <span class="keywordtype">char</span> c, *n;
01618 
01619             n = buf;
01620 <span class="comment">/*@-globs@*/</span>
01621             <a class="code" href="macro_8c.html#a6">SKIPBLANK</a>(n, c);
01622 <span class="comment">/*@=globs@*/</span>
01623 
01624             <span class="keywordflow">if</span> (c != <span class="charliteral">'%'</span>)
01625                 <span class="comment">/*@innercontinue@*/</span> <span class="keywordflow">continue</span>;
01626             n++;        <span class="comment">/* skip % */</span>
01627             (void) <a class="code" href="macro_8c.html#a45">rpmDefineMacro</a>(NULL, n, <a class="code" href="rpmmacro_8h.html#a1">RMIL_MACROFILES</a>);
01628         }
01629         (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(fd);
01630     }
01631     m = <a class="code" href="poptint_8h.html#a14">_free</a>(m);
01632 
01633     <span class="comment">/* Reload cmdline macros */</span>
01634     <span class="comment">/*@-mods@*/</span>
01635     <a class="code" href="macro_8c.html#a46">rpmLoadMacros</a>(<a class="code" href="macro_8c.html#a15">rpmCLIMacroContext</a>, <a class="code" href="rpmmacro_8h.html#a3">RMIL_CMDLINE</a>);
01636     <span class="comment">/*@=mods@*/</span>
01637 }
01638 
01639 <span class="comment">/*@-globstate@*/</span>
01640 <span class="keywordtype">void</span>
<a name="l01641"></a><a class="code" href="macro_8c.html#a48">01641</a> <a class="code" href="macro_8c.html#a48">rpmFreeMacros</a>(<a class="code" href="structMacroContext__s.html">MacroContext</a> mc)
01642 {
01643     
01644     <span class="keywordflow">if</span> (mc == NULL) mc = <a class="code" href="macro_8c.html#a13">rpmGlobalMacroContext</a>;
01645 
01646     <span class="keywordflow">if</span> (mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> != NULL) {
01647         <span class="keywordtype">int</span> i;
01648         <span class="keywordflow">for</span> (i = 0; i &lt; mc-&gt;<a class="code" href="structMacroContext__s.html#m2">firstFree</a>; i++) {
01649             <a class="code" href="structMacroEntry__s.html">MacroEntry</a> me;
01650             <span class="keywordflow">while</span> ((me = mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i]) != NULL) {
01651                 <span class="comment">/* XXX cast to workaround const */</span>
01652                 <span class="comment">/*@-onlytrans@*/</span>
01653                 <span class="keywordflow">if</span> ((mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i] = me-&gt;<a class="code" href="structMacroEntry__s.html#m0">prev</a>) == NULL)
01654                     me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-&gt;<a class="code" href="structMacroEntry__s.html#m1">name</a>);
01655                 <span class="comment">/*@=onlytrans@*/</span>
01656                 me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-&gt;<a class="code" href="structMacroEntry__s.html#m2">opts</a>);
01657                 me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-&gt;<a class="code" href="structMacroEntry__s.html#m3">body</a>);
01658                 me = <a class="code" href="poptint_8h.html#a14">_free</a>(me);
01659             }
01660         }
01661         mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(mc-&gt;<a class="code" href="structMacroContext__s.html#m0">macroTable</a>);
01662     }
01663     memset(mc, 0, <span class="keyword">sizeof</span>(*mc));
01664 }
01665 <span class="comment">/*@=globstate@*/</span>
01666 
01667 <span class="comment">/* =============================================================== */</span>
<a name="l01668"></a><a class="code" href="macro_8c.html#a49">01668</a> <span class="keywordtype">int</span> <a class="code" href="macro_8c.html#a49">isCompressed</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * file, <a class="code" href="rpmmacro_8h.html#a13">rpmCompressedMagic</a> * compressed)
01669 {
01670     <a class="code" href="struct__FD__s.html">FD_t</a> fd;
01671     ssize_t nb;
01672     <span class="keywordtype">int</span> rc = -1;
01673     <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> magic[4];
01674 
01675     *compressed = <a class="code" href="rpmmacro_8h.html#a32a14">COMPRESSED_NOT</a>;
01676 
01677     fd = <a class="code" href="group__rpmio.html#a83">Fopen</a>(file, <span class="stringliteral">"r.ufdio"</span>);
01678     <span class="keywordflow">if</span> (fd == NULL || <a class="code" href="group__rpmio.html#a85">Ferror</a>(fd)) {
01679         <span class="comment">/* XXX Fstrerror */</span>
01680         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"File %s: %s\n"</span>), file, <a class="code" href="group__rpmio.html#a11">Fstrerror</a>(fd));
01681         <span class="keywordflow">if</span> (fd) (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(fd);
01682         <span class="keywordflow">return</span> 1;
01683     }
01684     nb = <a class="code" href="group__rpmio.html#a77">Fread</a>(magic, <span class="keyword">sizeof</span>(magic[0]), <span class="keyword">sizeof</span>(magic), fd);
01685     <span class="keywordflow">if</span> (nb &lt; 0) {
01686         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"File %s: %s\n"</span>), file, <a class="code" href="group__rpmio.html#a11">Fstrerror</a>(fd));
01687         rc = 1;
01688     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nb &lt; <span class="keyword">sizeof</span>(magic)) {
01689         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a60">RPMERR_BADSPEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"File %s is smaller than %u bytes\n"</span>),
01690                 file, (<span class="keywordtype">unsigned</span>)<span class="keyword">sizeof</span>(magic));
01691         rc = 0;
01692     }
01693     (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(fd);
01694     <span class="keywordflow">if</span> (rc &gt;= 0)
01695         <span class="keywordflow">return</span> rc;
01696 
01697     rc = 0;
01698 
01699     <span class="keywordflow">if</span> ((magic[0] == <span class="charliteral">'B'</span>) &amp;&amp; (magic[1] == <span class="charliteral">'Z'</span>)) {
01700         *compressed = <a class="code" href="rpmmacro_8h.html#a32a16">COMPRESSED_BZIP2</a>;
01701     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> ((magic[0] == 0120) &amp;&amp; (magic[1] == 0113) &amp;&amp;
01702          (magic[2] == 0003) &amp;&amp; (magic[3] == 0004)) {    <span class="comment">/* pkzip */</span>
01703         *compressed = <a class="code" href="rpmmacro_8h.html#a32a17">COMPRESSED_ZIP</a>;
01704     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (((magic[0] == 0037) &amp;&amp; (magic[1] == 0213)) || <span class="comment">/* gzip */</span>
01705         ((magic[0] == 0037) &amp;&amp; (magic[1] == 0236)) ||   <span class="comment">/* old gzip */</span>
01706         ((magic[0] == 0037) &amp;&amp; (magic[1] == 0036)) ||   <span class="comment">/* pack */</span>
01707         ((magic[0] == 0037) &amp;&amp; (magic[1] == 0240)) ||   <span class="comment">/* SCO lzh */</span>
01708         ((magic[0] == 0037) &amp;&amp; (magic[1] == 0235))      <span class="comment">/* compress */</span>
01709         ) {
01710         *compressed = <a class="code" href="rpmmacro_8h.html#a32a15">COMPRESSED_OTHER</a>;
01711     }
01712 
01713     <span class="keywordflow">return</span> rc;
01714 }
01715 
01716 <span class="comment">/* =============================================================== */</span>
01717 
01718 <span class="comment">/*@-modfilesys@*/</span>
01719 <span class="keywordtype">char</span> * 
<a name="l01720"></a><a class="code" href="macro_8c.html#a50">01720</a> <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *arg, ...)
01721 {
01722     <span class="keywordtype">char</span> buf[BUFSIZ], *p, *pe;
01723     <span class="keyword">const</span> <span class="keywordtype">char</span> *s;
01724     va_list ap;
01725 
01726     <span class="keywordflow">if</span> (arg == NULL)
01727         <span class="keywordflow">return</span> <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(<span class="stringliteral">""</span>);
01728 
01729     buf[0] = <span class="charliteral">'\0'</span>;
01730     p = buf;
01731     pe = <a class="code" href="system_8h.html#a32">stpcpy</a>(p, arg);
01732 
01733     va_start(ap, arg);
01734     <span class="keywordflow">while</span> ((s = va_arg(ap, <span class="keyword">const</span> <span class="keywordtype">char</span> *)) != NULL)
01735         pe = <a class="code" href="system_8h.html#a32">stpcpy</a>(pe, s);
01736     va_end(ap);
01737     (void) <a class="code" href="macro_8c.html#a42">expandMacros</a>(NULL, NULL, buf, <span class="keyword">sizeof</span>(buf));
01738     <span class="keywordflow">return</span> <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(buf);
01739 }
01740 <span class="comment">/*@=modfilesys@*/</span>
01741 
01742 <span class="keywordtype">int</span>
<a name="l01743"></a><a class="code" href="macro_8c.html#a51">01743</a> <a class="code" href="macro_8c.html#a51">rpmExpandNumeric</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *arg)
01744 {
01745     <span class="keyword">const</span> <span class="keywordtype">char</span> *val;
01746     <span class="keywordtype">int</span> rc;
01747 
01748     <span class="keywordflow">if</span> (arg == NULL)
01749         <span class="keywordflow">return</span> 0;
01750 
01751     val = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(arg, NULL);
01752     <span class="keywordflow">if</span> (!(val &amp;&amp; *val != <span class="charliteral">'%'</span>))
01753         rc = 0;
01754     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (*val == <span class="charliteral">'Y'</span> || *val == <span class="charliteral">'y'</span>)
01755         rc = 1;
01756     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (*val == <span class="charliteral">'N'</span> || *val == <span class="charliteral">'n'</span>)
01757         rc = 0;
01758     <span class="keywordflow">else</span> {
01759         <span class="keywordtype">char</span> *end;
01760         rc = strtol(val, &amp;end, 0);
01761         <span class="keywordflow">if</span> (!(end &amp;&amp; *end == <span class="charliteral">'\0'</span>))
01762             rc = 0;
01763     }
01764     val = <a class="code" href="poptint_8h.html#a14">_free</a>(val);
01765 
01766     <span class="keywordflow">return</span> rc;
01767 }
01768 
01769 <span class="comment">/* @todo "../sbin/./../bin/" not correct. */</span>
<a name="l01770"></a><a class="code" href="macro_8c.html#a52">01770</a> <span class="keywordtype">char</span> *<a class="code" href="macro_8c.html#a52">rpmCleanPath</a>(<span class="keywordtype">char</span> * path)
01771 {
01772     <span class="keyword">const</span> <span class="keywordtype">char</span> *s;
01773     <span class="keywordtype">char</span> *se, *t, *te;
01774     <span class="keywordtype">int</span> <a class="code" href="rpmio__internal_8h.html#a10">begin</a> = 1;
01775 
01776     <span class="keywordflow">if</span> (path == NULL)
01777         <span class="keywordflow">return</span> NULL;
01778 
01779 <span class="comment">/*fprintf(stderr, "*** RCP %s -&gt;\n", path); */</span>
01780     s = t = te = path;
01781     <span class="keywordflow">while</span> (*s != <span class="charliteral">'\0'</span>) {
01782 <span class="comment">/*fprintf(stderr, "*** got \"%.*s\"\trest \"%s\"\n", (t-path), path, s); */</span>
01783         <span class="keywordflow">switch</span>(*s) {
01784         <span class="keywordflow">case</span> <span class="charliteral">':'</span>:                       <span class="comment">/* handle url's */</span>
01785             <span class="keywordflow">if</span> (s[1] == <span class="charliteral">'/'</span> &amp;&amp; s[2] == <span class="charliteral">'/'</span>) {
01786                 *t++ = *s++;
01787                 *t++ = *s++;
01788                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01789             }
01790             <a class="code" href="rpmio__internal_8h.html#a10">begin</a>=1;
01791             <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01792         <span class="keywordflow">case</span> <span class="charliteral">'/'</span>:
01793             <span class="comment">/* Move parent dir forward */</span>
01794             <span class="keywordflow">for</span> (se = te + 1; se &lt; t &amp;&amp; *se != <span class="charliteral">'/'</span>; se++)
01795                 {};
01796             <span class="keywordflow">if</span> (se &lt; t &amp;&amp; *se == <span class="charliteral">'/'</span>) {
01797                 te = se;
01798 <span class="comment">/*fprintf(stderr, "*** next pdir \"%.*s\"\n", (te-path), path); */</span>
01799             }
01800             <span class="keywordflow">while</span> (s[1] == <span class="charliteral">'/'</span>)
01801                 s++;
01802             <span class="keywordflow">while</span> (t &gt; path &amp;&amp; t[-1] == <span class="charliteral">'/'</span>)
01803                 t--;
01804             <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01805         <span class="keywordflow">case</span> <span class="charliteral">'.'</span>:
01806             <span class="comment">/* Leading .. is special */</span>
01807             <span class="comment">/* Check that it is ../, so that we don't interpret */</span>
01808             <span class="comment">/* ..?(i.e. "...") or ..* (i.e. "..bogus") as "..". */</span>
01809             <span class="comment">/* in the case of "...", this ends up being processed*/</span>
01810             <span class="comment">/* as "../.", and the last '.' is stripped.  This   */</span>
01811             <span class="comment">/* would not be correct processing.                 */</span>
01812             <span class="keywordflow">if</span> (<a class="code" href="rpmio__internal_8h.html#a10">begin</a> &amp;&amp; s[1] == <span class="charliteral">'.'</span> &amp;&amp; (s[2] == <span class="charliteral">'/'</span> || s[2] == <span class="charliteral">'\0'</span>)) {
01813 <span class="comment">/*fprintf(stderr, "    leading \"..\"\n"); */</span>
01814                 *t++ = *s++;
01815                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01816             }
01817             <span class="comment">/* Single . is special */</span>
01818             <span class="keywordflow">if</span> (<a class="code" href="rpmio__internal_8h.html#a10">begin</a> &amp;&amp; s[1] == <span class="charliteral">'\0'</span>) {
01819                 <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01820             }
01821             <span class="comment">/* Trim embedded ./ , trailing /. */</span>
01822             <span class="keywordflow">if</span> ((t[-1] == <span class="charliteral">'/'</span> &amp;&amp; s[1] == <span class="charliteral">'\0'</span>) || (t != path &amp;&amp; s[1] == <span class="charliteral">'/'</span>)) {
01823                 s++;
01824                 <span class="keywordflow">continue</span>;
01825             }
01826             <span class="comment">/* Trim embedded /../ and trailing /.. */</span>
01827             <span class="keywordflow">if</span> (!<a class="code" href="rpmio__internal_8h.html#a10">begin</a> &amp;&amp; t &gt; path &amp;&amp; t[-1] == <span class="charliteral">'/'</span> &amp;&amp; s[1] == <span class="charliteral">'.'</span> &amp;&amp; (s[2] == <span class="charliteral">'/'</span> || s[2] == <span class="charliteral">'\0'</span>)) {
01828                 t = te;
01829                 <span class="comment">/* Move parent dir forward */</span>
01830                 <span class="keywordflow">if</span> (te &gt; path)
01831                     <span class="keywordflow">for</span> (--te; te &gt; path &amp;&amp; *te != <span class="charliteral">'/'</span>; te--)
01832                         {};
01833 <span class="comment">/*fprintf(stderr, "*** prev pdir \"%.*s\"\n", (te-path), path); */</span>
01834                 s++;
01835                 s++;
01836                 <span class="keywordflow">continue</span>;
01837             }
01838             <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01839         <span class="keywordflow">default</span>:
01840             <a class="code" href="rpmio__internal_8h.html#a10">begin</a> = 0;
01841             <span class="comment">/*@switchbreak@*/</span> <span class="keywordflow">break</span>;
01842         }
01843         *t++ = *s++;
01844     }
01845 
01846     <span class="comment">/* Trim trailing / (but leave single / alone) */</span>
01847     <span class="keywordflow">if</span> (t &gt; &amp;path[1] &amp;&amp; t[-1] == <span class="charliteral">'/'</span>)
01848         t--;
01849     *t = <span class="charliteral">'\0'</span>;
01850 
01851 <span class="comment">/*fprintf(stderr, "\t%s\n", path); */</span>
01852     <span class="comment">/*@-temptrans -retalias@*/</span> <span class="keywordflow">return</span> path; <span class="comment">/*@=temptrans =retalias@*/</span>
01853 }
01854 
01855 <span class="comment">/* Return concatenated and expanded canonical path. */</span>
01856 
01857 <span class="keyword">const</span> <span class="keywordtype">char</span> *
<a name="l01858"></a><a class="code" href="macro_8c.html#a53">01858</a> <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *path, ...)
01859 {
01860     <span class="keywordtype">char</span> buf[BUFSIZ];
01861     <span class="keyword">const</span> <span class="keywordtype">char</span> * s;
01862     <span class="keywordtype">char</span> * t, * te;
01863     va_list ap;
01864 
01865     <span class="keywordflow">if</span> (path == NULL)
01866         <span class="keywordflow">return</span> <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(<span class="stringliteral">""</span>);
01867 
01868     buf[0] = <span class="charliteral">'\0'</span>;
01869     t = buf;
01870     te = <a class="code" href="system_8h.html#a32">stpcpy</a>(t, path);
01871     *te = <span class="charliteral">'\0'</span>;
01872 
01873     va_start(ap, path);
01874     <span class="keywordflow">while</span> ((s = va_arg(ap, <span class="keyword">const</span> <span class="keywordtype">char</span> *)) != NULL) {
01875         te = <a class="code" href="system_8h.html#a32">stpcpy</a>(te, s);
01876         *te = <span class="charliteral">'\0'</span>;
01877     }
01878     va_end(ap);
01879 <span class="comment">/*@-modfilesys@*/</span>
01880     (void) <a class="code" href="macro_8c.html#a42">expandMacros</a>(NULL, NULL, buf, <span class="keyword">sizeof</span>(buf));
01881 <span class="comment">/*@=modfilesys@*/</span>
01882 
01883     (void) <a class="code" href="macro_8c.html#a52">rpmCleanPath</a>(buf);
01884     <span class="keywordflow">return</span> <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(buf);        <span class="comment">/* XXX xstrdup has side effects. */</span>
01885 }
01886 
01887 <span class="comment">/* Merge 3 args into path, any or all of which may be a url. */</span>
01888 
<a name="l01889"></a><a class="code" href="macro_8c.html#a54">01889</a> <span class="keyword">const</span> <span class="keywordtype">char</span> * <a class="code" href="macro_8c.html#a54">rpmGenPath</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * urlroot, <span class="keyword">const</span> <span class="keywordtype">char</span> * urlmdir,
01890                 <span class="keyword">const</span> <span class="keywordtype">char</span> *urlfile)
01891 {
01892 <span class="comment">/*@owned@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * xroot = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(urlroot, NULL);
01893 <span class="comment">/*@dependent@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * root = xroot;
01894 <span class="comment">/*@owned@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * xmdir = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(urlmdir, NULL);
01895 <span class="comment">/*@dependent@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * mdir = xmdir;
01896 <span class="comment">/*@owned@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * xfile = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(urlfile, NULL);
01897 <span class="comment">/*@dependent@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * file = xfile;
01898     <span class="keyword">const</span> <span class="keywordtype">char</span> * result;
01899     <span class="keyword">const</span> <span class="keywordtype">char</span> * url = NULL;
01900     <span class="keywordtype">int</span> nurl = 0;
01901     <span class="keywordtype">int</span> ut;
01902 
01903 <span class="preprocessor">#if 0</span>
01904 <span class="preprocessor"></span><span class="keywordflow">if</span> (_debug) fprintf(stderr, <span class="stringliteral">"*** RGP xroot %s xmdir %s xfile %s\n"</span>, xroot, xmdir, xfile);
01905 <span class="preprocessor">#endif</span>
01906 <span class="preprocessor"></span>    ut = <a class="code" href="url_8c.html#a18">urlPath</a>(xroot, &amp;root);
01907     <span class="keywordflow">if</span> (url == NULL &amp;&amp; ut &gt; <a class="code" href="rpmurl_8h.html#a30a15">URL_IS_DASH</a>) {
01908         url = xroot;
01909         nurl = root - xroot;
01910 <span class="preprocessor">#if 0</span>
01911 <span class="preprocessor"></span><span class="keywordflow">if</span> (_debug) fprintf(stderr, <span class="stringliteral">"*** RGP ut %d root %s nurl %d\n"</span>, ut, root, nurl);
01912 <span class="preprocessor">#endif</span>
01913 <span class="preprocessor"></span>    }
01914     <span class="keywordflow">if</span> (root == NULL || *root == <span class="charliteral">'\0'</span>) root = <span class="stringliteral">"/"</span>;
01915 
01916     ut = <a class="code" href="url_8c.html#a18">urlPath</a>(xmdir, &amp;mdir);
01917     <span class="keywordflow">if</span> (url == NULL &amp;&amp; ut &gt; <a class="code" href="rpmurl_8h.html#a30a15">URL_IS_DASH</a>) {
01918         url = xmdir;
01919         nurl = mdir - xmdir;
01920 <span class="preprocessor">#if 0</span>
01921 <span class="preprocessor"></span><span class="keywordflow">if</span> (_debug) fprintf(stderr, <span class="stringliteral">"*** RGP ut %d mdir %s nurl %d\n"</span>, ut, mdir, nurl);
01922 <span class="preprocessor">#endif</span>
01923 <span class="preprocessor"></span>    }
01924     <span class="keywordflow">if</span> (mdir == NULL || *mdir == <span class="charliteral">'\0'</span>) mdir = <span class="stringliteral">"/"</span>;
01925 
01926     ut = <a class="code" href="url_8c.html#a18">urlPath</a>(xfile, &amp;file);
01927     <span class="keywordflow">if</span> (url == NULL &amp;&amp; ut &gt; <a class="code" href="rpmurl_8h.html#a30a15">URL_IS_DASH</a>) {
01928         url = xfile;
01929         nurl = file - xfile;
01930 <span class="preprocessor">#if 0</span>
01931 <span class="preprocessor"></span><span class="keywordflow">if</span> (_debug) fprintf(stderr, <span class="stringliteral">"*** RGP ut %d file %s nurl %d\n"</span>, ut, file, nurl);
01932 <span class="preprocessor">#endif</span>
01933 <span class="preprocessor"></span>    }
01934 
01935     <span class="keywordflow">if</span> (url &amp;&amp; nurl &gt; 0) {
01936         <span class="keywordtype">char</span> *t = strncpy(<a class="code" href="system_8h.html#a36">alloca</a>(nurl+1), url, nurl);
01937         t[nurl] = <span class="charliteral">'\0'</span>;
01938         url = t;
01939     } <span class="keywordflow">else</span>
01940         url = <span class="stringliteral">""</span>;
01941 
01942     result = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(url, root, <span class="stringliteral">"/"</span>, mdir, <span class="stringliteral">"/"</span>, file, NULL);
01943 
01944     xroot = <a class="code" href="poptint_8h.html#a14">_free</a>(xroot);
01945     xmdir = <a class="code" href="poptint_8h.html#a14">_free</a>(xmdir);
01946     xfile = <a class="code" href="poptint_8h.html#a14">_free</a>(xfile);
01947 <span class="preprocessor">#if 0</span>
01948 <span class="preprocessor"></span><span class="keywordflow">if</span> (_debug) fprintf(stderr, <span class="stringliteral">"*** RGP result %s\n"</span>, result);
01949 <span class="preprocessor">#endif</span>
01950 <span class="preprocessor"></span>    <span class="keywordflow">return</span> result;
01951 }
01952 
01953 <span class="comment">/* =============================================================== */</span>
01954 
01955 <span class="preprocessor">#if defined(DEBUG_MACROS)</span>
01956 <span class="preprocessor"></span>
01957 <span class="preprocessor">#if defined(EVAL_MACROS)</span>
01958 <span class="preprocessor"></span>
01959 <span class="keywordtype">char</span> *macrofiles = <span class="stringliteral">"/usr/lib/rpm/macros:/etc/rpm/macros:~/.rpmmacros"</span>;
01960 
01961 <span class="keywordtype">int</span>
01962 <a class="code" href="rpmsignature_8c.html#a0">main</a>(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])
01963 {
01964     <span class="keywordtype">int</span> c;
01965     <span class="keywordtype">int</span> errflg = 0;
01966     <span class="keyword">extern</span> <span class="keywordtype">char</span> *optarg;
01967     <span class="keyword">extern</span> <span class="keywordtype">int</span> optind;
01968 
01969     <span class="keywordflow">while</span> ((c = getopt(argc, argv, <span class="stringliteral">"f:"</span>)) != EOF ) {
01970         <span class="keywordflow">switch</span> (c) {
01971         <span class="keywordflow">case</span> <span class="charliteral">'f'</span>:
01972             macrofiles = optarg;
01973             <span class="keywordflow">break</span>;
01974         <span class="keywordflow">case</span> <span class="charliteral">'?'</span>:
01975         <span class="keywordflow">default</span>:
01976             errflg++;
01977             <span class="keywordflow">break</span>;
01978         }
01979     }
01980     <span class="keywordflow">if</span> (errflg || optind &gt;= argc) {
01981         fprintf(stderr, <span class="stringliteral">"Usage: %s [-f macropath ] macro ...\n"</span>, argv[0]);
01982         exit(1);
01983     }
01984 
01985     <a class="code" href="macro_8c.html#a47">rpmInitMacros</a>(NULL, macrofiles);
01986     <span class="keywordflow">for</span> ( ; optind &lt; argc; optind++) {
01987         <span class="keyword">const</span> <span class="keywordtype">char</span> *val;
01988 
01989         val = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(argv[optind], NULL);
01990         <span class="keywordflow">if</span> (val) {
01991             fprintf(stdout, <span class="stringliteral">"%s:\t%s\n"</span>, argv[optind], val);
01992             val = <a class="code" href="poptint_8h.html#a14">_free</a>(val);
01993         }
01994     }
01995     <a class="code" href="macro_8c.html#a48">rpmFreeMacros</a>(NULL);
01996     <span class="keywordflow">return</span> 0;
01997 }
01998 
01999 <span class="preprocessor">#else   </span><span class="comment">/* !EVAL_MACROS */</span>
02000 
02001 <span class="keywordtype">char</span> *macrofiles = <span class="stringliteral">"../macros:./testmacros"</span>;
02002 <span class="keywordtype">char</span> *testfile = <span class="stringliteral">"./test"</span>;
02003 
02004 <span class="keywordtype">int</span>
02005 <a class="code" href="rpmsignature_8c.html#a0">main</a>(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])
02006 {
02007     <span class="keywordtype">char</span> buf[BUFSIZ];
02008     FILE *fp;
02009     <span class="keywordtype">int</span> x;
02010 
02011     <a class="code" href="macro_8c.html#a47">rpmInitMacros</a>(NULL, macrofiles);
02012     <a class="code" href="macro_8c.html#a25">rpmDumpMacroTable</a>(NULL, NULL);
02013 
02014     <span class="keywordflow">if</span> ((fp = fopen(testfile, <span class="stringliteral">"r"</span>)) != NULL) {
02015         <span class="keywordflow">while</span>(<a class="code" href="macro_8c.html#a27">rdcl</a>(buf, <span class="keyword">sizeof</span>(buf), fp, 1)) {
02016             x = <a class="code" href="macro_8c.html#a42">expandMacros</a>(NULL, NULL, buf, <span class="keyword">sizeof</span>(buf));
02017             fprintf(stderr, <span class="stringliteral">"%d-&gt;%s\n"</span>, x, buf);
02018             memset(buf, 0, <span class="keyword">sizeof</span>(buf));
02019         }
02020         fclose(fp);
02021     }
02022 
02023     <span class="keywordflow">while</span>(<a class="code" href="macro_8c.html#a27">rdcl</a>(buf, <span class="keyword">sizeof</span>(buf), stdin, 1)) {
02024         x = <a class="code" href="macro_8c.html#a42">expandMacros</a>(NULL, NULL, buf, <span class="keyword">sizeof</span>(buf));
02025         fprintf(stderr, <span class="stringliteral">"%d-&gt;%s\n &lt;-\n"</span>, x, buf);
02026         memset(buf, 0, <span class="keyword">sizeof</span>(buf));
02027     }
02028     <a class="code" href="macro_8c.html#a48">rpmFreeMacros</a>(NULL);
02029 
02030     <span class="keywordflow">return</span> 0;
02031 }
02032 <span class="preprocessor">#endif  </span><span class="comment">/* EVAL_MACROS */</span>
02033 <span class="preprocessor">#endif  </span><span class="comment">/* DEBUG_MACROS */</span>
02034 <span class="comment">/*@=branchstate@*/</span>
</pre></div><hr><address style="align: right;"><small>Generated on Thu Sep 12 22:15:01 2002 for rpm 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.17 </small></address>
</body>
</html>